【実務・中級編】 EAPOL(Extensible Authentication Protocol over LAN)のフレーム構造とパケットタイプ – インフラ・物理&L2/L3ネットワーク基礎実践ガイド

認証の「門番」を解剖する:EAPOLフレームの深淵と実務的トラブルシューティング

ネットワークエンジニアとして現場に立っていると、上位レイヤーのHTTP/3やgRPCの話に花が咲く一方で、足元のL2レイヤーで起きている「沈黙」に頭を抱えることがよくあります。特にIEEE 802.1X認証が絡む環境では、認証が通らないという事象に対し、ただ「設定ミスでしょう」と決めつけるのは禁物です。

今日は、スイッチのポートにLANケーブルを差し込んだ瞬間に繰り広げられる、認証の「握手」――EAPOL(Extensible Authentication Protocol over LAN)の正体を徹底的に解剖します。

—

1. EAPOLとは何か:イーサネットを「認証のトンネル」に変える魔法

EAPOLは、IEEE 802.1Xの核心です。通常、EAPはPPP(Point-to-Point Protocol)上で動作するように設計されていましたが、これをイーサネット環境で無理なく動かすために生まれたのがEAPOLです。

物理層でのリンクアップ直後、サプリカント(PC等の端末)は、オーセンティケータ(スイッチ)に対してEAPOLパケットを投げ込みます。この時、IPアドレスすら割り当てられていない「無防備な状態」で通信を行うため、通常のIPヘッダーではなく、イーサネットフレームの直上にEAPOLを載せるという荒技を使います。

EAPOLフレームの構造

EAPOLは、イーサネットフレームの「タイプフィールド」に 0x888E を指定することで、スイッチ側のプロトコルスタックが「これは認証用パケットだ」と即座に判断できるように設計されています。

  • Destination MAC: 01:80:C2:00:00:03 (IEEE 802.1X ポートアクセスエンティティのマルチキャストアドレス)
  • EtherType: 0x888E
  • EAPOL Header: バージョン、タイプ、データ長
  • EAP Packet: 実際の認証データ(ID要求やレスポンスなど)

この 01:80:C2:00:00:03 というマルチキャストアドレスが重要です。多くのスイッチでは、このフレームをCPUにダイレクトに引き渡すため、トポロジ内の途中にこのアドレスをフィルタリングしてしまうL2スイッチやハブがあると、認証は一瞬で詰みます。

—

2. パケットタイプが語る「交渉」のシーケンス

現場でWiresharkを叩いたとき、まず注目すべきは EAPOL Type です。主なものは以下の4つです。

| Type | 名称 | 役割 |
| :— | :— | :— |
| 0x00 | EAP-Packet | 本丸。EAPメッセージの搬送用。 |
| 0x01 | EAPOL-Start | サプリカントからの「認証させてくれ!」という合図。 |
| 0x02 | EAPOL-Logoff | 通信終了。ポートを未認証状態に戻す。 |
| 0x03 | EAPOL-Key | EAPOL-Key。WPA/WPA2/WPA3等の暗号化鍵の配布に使用。 |

認証フローの典型はこうです。
1. サプリカント: EAPOL-Start を送信。
2. スイッチ: EAP-Request/Identity を送信。
3. サプリカント: EAP-Response/Identity(IDを回答)を送信。
4. スイッチ: Radiusサーバーと連携し、検証開始。

トラブルシューティングの際、EAPOL-Start は飛んでいるのに EAP-Request が返ってこない場合、スイッチ側の設定(dot1x system-auth-control 等)が漏れているか、ポートが「強制認証(force-authorized)」モードになっていないかを真っ先に疑います。

—

3. 実務でのデバッグ:Pythonで「認証の影」を追う

実務では、生のパケットをキャプチャするだけでなく、認証プロセスのシミュレーションが必要な場面もあります。scapy を使えば、EAPOLパケットを構築してスイッチの挙動をテスト可能です。

from scapy.all import *

# ターゲットスイッチの認証用マルチキャストアドレス
EAPOL_DST = "01:80:c2:00:00:03"

# EAPOL Startパケットの構築
# Ethernetヘッダー + EAPOLヘッダー(Type 1: Start)
pkt = Ether(dst=EAPOL_DST, src=get_if_hwaddr("eth0"), type=0x888E) / \
      EAPOL(version=2, type=1) # type 1 = EAPOL-Start

# 送信してスイッチの反応を待機
sendp(pkt, iface="eth0")
print("EAPOL-Startを送信しました。認証パケットの到着を待ちます...")

# スイッチからのRequest/Identityをキャプチャする準備
sniff(filter="ether proto 0x888e", count=1, timeout=5)

このコードを実行し、スイッチが即座に EAP-Request/Identity を返してくるかを確認してください。もし返ってこなければ、L2レベルでの疎通遮断、またはスイッチの認証ポートが「シャットダウン状態」あるいは「未設定」である可能性が高いです。

—

4. 現場の教訓:設定の罠とTips

最後に、運用現場でよく踏む地雷を共有します。

  • ポートFast設定の罠: Ciscoスイッチなどで spanning-tree portfast を入れていない場合、リンクアップ直後のスパニングツリーのリスニング/ラーニング期間が原因で、端末が投げる EAPOL-Start がスイッチに届かず、タイムアウトします。
  • VLAN変更のタイミング: 認証成功後に Voice VLAN や Dynamic VLAN を割り当てる際、スイッチ側でVLANが未作成だとポートがエラーになります。show vlan brief を常に正としてください。
  • MTU問題: EAPOLは小さいパケットですが、RADIUSサーバーとのやり取りで証明書(EAP-TLS)が巨大化すると、MTU値の調整が必要になることがあります。

最後に

EAPOLは、目に見えない「信頼」をコード化する儀式です。パケットをキャプチャし、その中身を覗き込むことで、ネットワークは単なる「箱」から「対話相手」へと変わります。もし現場で認証が通らず途方に暮れたら、まずは 0x888E が正しく流れているか、そこから全てを紐解いてみてください。

プロトコルの深淵を覗くことは、インフラエンジニアにとって最高の知的なエンターテインメントです。それでは、良きパケットライフを。

コメント

タイトルとURLをコピーしました