「認証してない端末は即刻アウト」:802.1Xで構築するゼロトラストの最前線
ネットワークエンジニアとして現場に立っていると、「境界さえ守れば安心」という時代がとうに終わったことを痛感させられます。社内LANに接続されたPCが、いつの間にかランサムウェアの踏み台になっていた――そんな悪夢を未然に防ぐ最後の砦が、802.1X認証を用いたネットワークアクセスコントロール(NAC)です。
今回は、教科書を読み解くだけでは決して見えてこない、RADIUSとEAPの「泥臭い挙動」と、現場で生き残るための実装テクニックを解説します。
—
1. なぜ今、802.1Xなのか?
ゼロトラストの原則は「Verify Explicitly(明示的に検証せよ)」。802.1Xは、物理ポートにLANケーブルを挿した瞬間にこの原則を強制します。
認証プロセスにおいて、主役は3者です。
- サプリカント (Supplicant): 接続を試みるクライアント端末
- オーセンティケーター (Authenticator): スイッチや無線AP(門番)
- 認証サーバー (Authentication Server): RADIUSサーバー(裁判官)
この三者が、EAPoL (EAP over LAN) や RADIUS プロトコルを介して「こいつは信頼できるデバイスか?」を問答するわけです。
2. 認証のシーケンス:パケットの裏側を覗く
認証が成功してVLANが切り替わるまでの裏側は、非常に繊細なやり取りで構成されています。
1. EAP-Start: サプリカントがスイッチに「繋いでもいい?」と合図を送る。
2. EAP-Request Identity: スイッチが「お前は誰だ?」と問う。
3. RADIUS Access-Request: スイッチがRADIUSサーバーへ情報を転送。
4. RADIUS Access-Challenge: サーバーが暗号化トークンなどを要求。
5. RADIUS Access-Accept: 認証成功。「こいつは許可されたユーザーだ」とスイッチに通知。
ここで重要なのが、RADIUS Access-Accept に含まれる VLAN割り当て属性 です。これを受け取ったスイッチは、動的にそのポートを「隔離VLAN」から「業務VLAN」へと切り替えます。
—
3. 実装のキモ:RADIUS属性の指定
RADIUSサーバー(FreeRADIUSなど)を設定する際、認証成功時に返す属性には注意が必要です。以下は、users ファイルでの設定例です。
# 認証成功時のポリシー設定
"engineer-01" Cleartext-Password := "SecretPassword123"
# 認証成功時に VLAN 10 を割り当てるための標準属性
Tunnel-Type = VLAN,
Tunnel-Medium-Type = IEEE-802,
Tunnel-Private-Group-ID = "10"
もし、認証に失敗した端末を隔離したい場合は、別途「隔離VLAN」用のIDを割り当てる設定を記述します。現場では、この Tunnel-Private-Group-ID の値がスイッチ側の VLAN ID と一致していないという初歩的なミスが、トラブルシューティングの8割を占めます。
—
4. 運用エンジニアのためのデバッグ術
「なぜか認証が通らない」そんな時、パケットキャプチャなしで解決しようとするのは自殺行為です。まずはスイッチ側のデバッグコマンドを叩きましょう。
Cisco IOSでのデバッグ例
# 認証のプロセスをリアルタイムで確認する
debug dot1x all
debug radius
これに加え、RADIUSサーバー側でのログ確認も必須です。Python等でRADIUSリクエストをシミュレーションしたい場合は、pyrad ライブラリを使うと非常に便利です。
# pyradを使った認証テストコードの断片
from pyrad.client import Client
from pyrad.dictionary import Dictionary
# RADIUSサーバーとの通信設定
srv = Client(server="192.168.1.10", secret=b"shared_secret", dict=Dictionary("dictionary"))
srv.auth_packet_code = 1 # Access-Request
# ユーザー認証のリクエスト作成
srv.CreateAuthPacket(code=1, User_Name="engineer-01")
srv["User-Password"] = srv.PwCrypt("SecretPassword123")
# 送信して応答を待つ
try:
reply = srv.SendPacket()
print(f"サーバーからの応答: {reply.code}")
except Exception as e:
print(f"RADIUS通信エラー: {e}")
—
5. 現場の教訓:成功率を上げるために
802.1Xの導入で最も苦労するのは、認証失敗時の「端末の隔離」と「ユーザー体験」の両立です。
- フォールバックの準備: 認証サーバーがダウンした際、スイッチがどのVLANに落ちるか(
authentication event fail action authorize vlan 99など)を必ず設計してください。これを怠ると、サーバー障害時に全社員がネットワークから締め出されるという「自爆テロ」が起きます。 - タイマー値の調整: 認証に時間がかかると、DHCPの取得がタイムアウトすることがあります。
dot1x timeout tx-period等のパラメーターは、インフラの応答速度に合わせてシビアに調整しましょう。
最後に
ネットワークのセキュリティは、完璧なマニュアルを読むことではなく、パケットが期待通りに流れない瞬間に「なぜ?」と問い続ける姿勢から生まれます。802.1Xは確かに導入の難易度は高いですが、一度構築してしまえば、マルウェアの横展開を物理層で食い止める強力な防壁になります。
皆さんのネットワークが、今日も安全であることを願っています。何かトラブルがあれば、まずは debug コマンドでパケットの断末魔を聞いてみてください。答えは必ずそこにあります。
コメント