STUDY · NETWORK GUIDE

4-7 IPsec VPN 基礎 — IKE がトンネルの鍵を配り SA が通信を守る

通信の中身を暗号で守る IPsec を扱う。IKEv1 の main mode 6 + quick mode 3 = 9 メッセージと、IKEv2 の IKE_SA_INIT + IKE_AUTH = 4 メッセージへの統合を対比し、鍵を安全に配る IKE と方向別の暗号契約 SA の関係を csr1000v の show で検証する。経路に NAT を挟むと UDP500 から UDP4500 へ移る NAT-T まで実機で確かめ、4-6 の伏線を回収する。S2S 実構成は 4-8 に送る。

1. 前節の振り返りと本節の内容

前節 4-6 NAT/PAT では、内部のプライベートアドレスと外部のグローバルアドレスを inside と outside の向き で変換する NAT を扱いました。変換の対応を変換テーブルに記憶し、経路の途中でパケットの送信元・宛先を書き換えて往復を成立させる仕組みでした。その末尾で、NAT が経路上でヘッダを書き換えると IPsec の検証が壊れる、という矛盾を伏線として残しました。

第 4 章はここまで、4-1 ACL の in/out、4-5 ZBF の zone-pair、4-6 NAT の inside/outside と、通信を制御する 向き状態 の考え方で貫いてきました。ACL・ZBF・NAT はいずれも、パケットを 通す・遮断する・書き換える 制御でした。本節で扱う IPsec (IP Security) は、制御する対象が違います。IPsec はパケットの中身を暗号で包み、機密性・完全性・認証 を足す = 中身を守る 仕組みです。通すかどうかではなく、通る中身を守ります。

IPsec を理解する鍵は、暗号アルゴリズムそのものよりも、鍵をどう安全に配るか と、配った鍵で守る通信をどう管理するか の 2 点にあります。前者を担うのが IKE (Internet Key Exchange)、後者を表すのが SA (Security Association) です。本節では csr1000v 3 台を使い、IKE の 2 つのバージョン、すなわち IKEv1 (main mode 6 + quick mode 3 = 9 メッセージ)IKEv2 (IKE_SA_INIT + IKE_AUTH = 4 メッセージ) を実機の show 出力で対比します。あわせて、経路に NAT を挟んだときに IKE が UDP500 から UDP4500 へ移る NAT-T (NAT Traversal) を発火させ、4-6 の伏線を回収します。実際の拠点間トンネルの構成 (crypto map と VTI の比較・PFS) は次節 4-8 に送り、本節は IKE と SA の仕組みに集中します。

2. IPsec とは — 中身を「守る」仕組み

ACL・ZBF・NAT は、パケットの ヘッダ を見て通す・遮断する、あるいはヘッダを 書き換える 機能でした。いずれもパケットの中身 (ペイロード) には手を触れず、中身が平文であることを前提にしています。IPsec は、この前提を覆します。元のパケットを丸ごと暗号化し、新しい IP ヘッダを付けて送り出すため、経路の途中では中身が読めない不透明なパケットになります。

IPsec が守るのは、次の 3 つです。機密性 (Confidentiality) は、中身を暗号化して盗聴者に読ませないこと。完全性 (Integrity) は、途中で改ざんされていないことをハッシュで検証すること。認証 (Authentication) は、通信相手が本物であることを確かめることです。この 3 つを、パケット単位で提供します。

暗号化されたデータを運ぶ実際のカプセル化は、ESP (Encapsulating Security Payload) が担います。ESP は元の IP パケットを暗号化してペイロードに収め、新しい IP ヘッダを付け、末尾に完全性チェック用のハッシュを付けます。本節のトンネルモード (mode tunnel) では、元の IP ヘッダごと暗号化して、送信元・宛先の内部アドレスも外からは見えなくなります。

IPsec の暗号化と復号の流れは以下のとおりです。

IPsec の暗号化・復号フロー。R1 の内部ホスト (192.168.10.1) 発の平文パケットが、R1 で ESP により暗号化され、新しい IP ヘッダ (外側 = GW 間アドレス) を付けた不透明なパケットになる。この暗号化パケットが中間の R2 を通過する間、中身は読めない。相手 GW の R3 が受け取って復号し、元の平文パケットに戻して内部ホスト (192.168.20.1) へ届ける。ACL/ZBF/NAT が通す・遮断する・書き換えるのに対し、IPsec は中身を暗号で守る

暗号化・復号には共通の が要ります。送信側と受信側が同じ鍵を持たなければ、暗号化したものを復号できません。しかし、その鍵をどうやって相手に安全に渡すかが問題になります。平文でネットワークに流せば盗聴されてしまいます。この「鍵を安全に配る」役割を担うのが、次に扱う IKE です。

3. 本ラボのトポロジ

本節の検証で使うトポロジを示します。csr1000v 3 台を直列につなぎ、両端の R1・R3 を VPN ゲートウェイ (GW)、中央の R2 を経路上の中間ルータとします。

4-7 IPsec ラボトポロジ。両端の R1 (左 GW・initiator) と R3 (右 GW・responder) が IPsec トンネルの端点で、間の R2 が中間ルータ。R1 の Loopback10 (192.168.10.0/24) が左の内部ホスト、R3 の Loopback20 (192.168.20.0/24) が右の内部ホスト見立て。GW 間リンクは 10.12.0.0/30 (R1-R2) と 10.23.0.0/30 (R2-R3)。crypto map はデータ IF の Gi2 だけに適用し、管理 IF (Gi1) には当てない。NAT-T のフェーズでは R2 が GW 間の IKE を PAT する中間 NAT を兼ねる

トポロジの構成は以下のとおりです。

  • R1 (左 VPN ゲートウェイ・initiator) — Loopback10 に 192.168.10.1/24 を持ち、これが暗号化して届けたい左の内部ホストです。R2 への Gi2 に 10.12.0.1/30 を持ち、この Gi2 に crypto map を適用します。トンネルを能動的に張りにいく側 = initiator です。
  • R2 (中間ルータ・crypto なし) — R1 への Gi2 に 10.12.0.2/30、R3 への Gi3 に 10.23.0.1/30 を持ちます。IPsec の設定は一切持たず、GW 間のパケットを転送するだけの経路上の第三者です。NAT-T のフェーズでのみ、GW 間の IKE を PAT する中間 NAT を兼ねます。
  • R3 (右 VPN ゲートウェイ・responder) — Loopback20 に 192.168.20.1/24 を持ち、これが右の内部ホストです。R2 への Gi2 に 10.23.0.2/30 を持ち、この Gi2 に crypto map を適用します。トンネル要求を受け付ける側 = responder です。

crypto は データ IF の Gi2 のみ に適用します。管理用の Gi1 (Mgmt) には決して当てません。GW 間のリンク (10.12.0.0/3010.23.0.0/30) と各 Loopback0 は OSPF で相互に広告し、GW 同士が外側アドレスで到達できる土台を作ります。

一方、暗号化して守りたい内部網 (192.168.10.0/24192.168.20.0/24) は、意図的に OSPF で広告しません。平文の OSPF で相互広告してしまうと、内部網が平文経路で直接ルーティングされ、暗号化されずに素通りしてしまうためです。相手内部網への到達は、トンネル経由でのみ成立させます。

トンネルで守る通信を interesting traffic (対象トラフィック) と呼び、拡張 ACL で定義します。本ラボでは R1 の crypto ACL を permit ip 192.168.10.0 0.0.0.255 192.168.20.0 0.0.0.255 とし、左内部から右内部への通信だけを暗号化の対象にします。R3 側はこれを鏡像にします。この ACL にマッチしたパケットだけが ESP でカプセル化され、相手 GW の外側アドレスへ送られます。

crypto を設定する前に、内部ホスト間で ping が通らないことを確認します。R1 の Loopback10 (192.168.10.1) を送信元にして、R3 の 192.168.20.1 へ ping します。

snippet
ping 192.168.20.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.20.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.10.1 
.....
Success rate is 0 percent (0/5)

..... (ドット 5 つ) で成功率 0 パーセントです。内部網を OSPF で広告していないため、まだ相手内部網へ届く手段がありません。この状態から IPsec トンネルを張り、この同じ ping を通すのが本節の目標になります。

4. IKE と SA — 「鍵を安全に配る」2 段構え

IPsec を動かすには、暗号化に使う共通鍵を両端の GW で共有し、どのアルゴリズムでどの通信を守るかを合意する必要があります。この合意を、盗聴される可能性のあるネットワーク越しに安全に行うのが IKE (Internet Key Exchange) です。IKE は UDP のポート 500 で動き、大きく 2 つのことをします。

1 つ目は 鍵の共有 です。IKE は DH (Diffie-Hellman) 鍵交換 を使い、盗聴されている経路の上でも、両端だけが同じ秘密の共有鍵を導出できる数学的な手続きを行います。交換されるのは公開値だけで、鍵そのものはネットワークに流れません。本ラボでは DH の強度を group 14 (MODP2048、2048 ビット) に明示します。

2 つ目は 相手の認証 です。DH で鍵を共有できても、その相手が本物かどうかは別の問題です。本ラボでは、両端に同じ PSK (Pre-Shared Key、事前共有鍵) を設定しておき、それを使ってお互いが本物であることを確認します。

IKE が合意した内容は、SA (Security Association、セキュリティアソシエーション) という形で両端に保持されます。SA は「この相手と、このアルゴリズムで、この鍵を使って、いつまで通信を守る」という 暗号の契約 です。IPsec では、この SA が 2 種類・2 段構えになっている点が要点です。

  • IKE SA (管理用) — IKE 自身の通信を守る SA。IKEv1 では ISAKMP SA とも呼びます。鍵交換と認証の合意そのもの = 制御チャネルの契約で、両端で 1 本を共有します。
  • IPsec SA (データ用) — 実際のユーザーデータ (ESP パケット) を守る SA。こちらは 方向別 で、行き (outbound) と戻り (inbound) にそれぞれ 1 本ずつ、計 2 本が立ちます。

まず IKE SA を確立して安全な制御チャネルを作り、その保護された中で IPsec SA を交渉する、という 2 段構えになります。この「管理用 1 本の下にデータ用 2 本がぶら下がる」構造を、次の IKEv1 の実機出力で確かめます。

5. IKEv1 — Phase1 main mode (6) + Phase2 quick mode (3)

IKEv1 は、SA の確立を 2 つのフェーズ に分けて行います。Phase1 で IKE SA (ISAKMP SA) を確立し、Phase2 でその保護下に IPsec SA を確立します。Phase1 には交換方法が 2 通りあり、6 メッセージを使う main mode と、3 メッセージに省略する aggressive mode があります。本ラボでは、より安全でサイト間 VPN の標準である main mode を使います。

Phase1 の main mode は 6 メッセージで、内訳は次のとおりです。最初の 2 メッセージ (msg1-2) で使用するアルゴリズムを交渉し、続く 2 メッセージ (msg3-4) で DH の公開値を交換して共有鍵を導出し、最後の 2 メッセージ (msg5-6) で PSK を使った相互認証を行います。この 6 メッセージが完了すると ISAKMP SA が立ちます。続く Phase2 の quick mode は 3 メッセージで、ISAKMP SA の保護下に IPsec SA (方向別 2 本) を交渉します。main mode 6 + quick mode 3 で、合計 9 メッセージ です。

この 9 メッセージの流れは以下のとおりです。

IKEv1 の 9 メッセージ。Phase1 main mode の 6 メッセージ (msg1-2 = アルゴリズム交渉 / msg3-4 = DH 公開値の交換で共有鍵を導出 / msg5-6 = PSK による相互認証) で ISAKMP SA が立ち、続く Phase2 quick mode の 3 メッセージで方向別の IPsec SA 2 本が立つ。管理用の ISAKMP SA 1 本の下に、データ用の IPsec SA が inbound/outbound の 2 本ぶら下がる二層構造を右側のテーブルで示す

R1 に IKEv1 の crypto 設定 (isakmp policy・PSK・transform-set・crypto ACL・crypto map) を投入し、Gi2 に crypto map を適用してから、§3 と同じ ping を撃ちます。

snippet
ping 192.168.20.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.20.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.10.1 
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 1/4/15 ms

.!!!! で成功率 80 パーセントです。§3 で 0 パーセントだった同じ ping が通るようになりました。先頭 1 発だけがドット (失敗) になっているのは、その 1 発目が SA の確立を引き起こしている最中に落ちた ためで、これは正常です。IPsec は interesting traffic が発生した瞬間に IKE のネゴを始めるため、初弾はトンネルがまだ立っていません。SA が立った 2 発目以降は 100 パーセントで通ります。

まず Phase1 の成果物、ISAKMP SA を確認します。

snippet
show crypto isakmp sa
IPv4 Crypto ISAKMP SA
dst             src             state          conn-id status
10.23.0.2       10.12.0.1       QM_IDLE           1001 ACTIVE

dst 10.23.0.2 / src 10.12.0.1 の間に、ISAKMP SA が 1 本 立っています。状態 QM_IDLE は「quick mode が完了してアイドルになった」状態で、Phase1・Phase2 とも正常に終わって確立していることを表します。ACTIVE は稼働中を意味します。これが管理用の SA (制御チャネル) で、両端で 1 本です。

このアルゴリズムの中身は show crypto isakmp sa detail で確認できます。

snippet
show crypto isakmp sa detail
Codes: C - IKE configuration mode, D - Dead Peer Detection
       K - Keepalives, N - NAT-traversal
       T - cTCP encapsulation, X - IKE Extended Authentication
       psk - Preshared key, rsig - RSA signature
       renc - RSA encryption
IPv4 Crypto ISAKMP SA

C-id  Local           Remote          I-VRF  Status Encr Hash   Auth DH Lifetime Cap.

1001  10.12.0.1       10.23.0.2              ACTIVE aes  sha256 psk  14 23:58:35     
       Engine-id:Conn-id =  SW:1

Encr aes / Hash sha256 / Auth psk / DH 14 と並んでいます。Phase1 で合意した内容がそのまま読み取れます。暗号化は AES、ハッシュは SHA256、認証は PSK、DH は group 14 です。Lifetime 23:58:35 は SA の残り寿命で、既定の 86400 秒 (24 時間) から少し減った値です。

次に Phase2 の成果物、IPsec SA を確認します。ここに二層構造のデータ側が現れます。

snippet
show crypto ipsec sa

interface: GigabitEthernet2
    Crypto map tag: CMAP, local addr 10.12.0.1

   protected vrf: (none)
   local  ident (addr/mask/prot/port): (192.168.10.0/255.255.255.0/0/0)
   remote ident (addr/mask/prot/port): (192.168.20.0/255.255.255.0/0/0)
   current_peer 10.23.0.2 port 500
     PERMIT, flags={origin_is_acl,}
    #pkts encaps: 4, #pkts encrypt: 4, #pkts digest: 4
    #pkts decaps: 4, #pkts decrypt: 4, #pkts verify: 4
    ...
     current outbound spi: 0xFF1BE21E(4280017438)
     PFS (Y/N): N, DH group: none

     inbound esp sas:
      spi: 0x48EC19EF(1223432687)
        transform: esp-256-aes esp-sha256-hmac ,
        in use settings ={Tunnel, }
        ...
     outbound esp sas:
      spi: 0xFF1BE21E(4280017438)
        transform: esp-256-aes esp-sha256-hmac ,
        in use settings ={Tunnel, }

読み取る点が 3 つあります。1 つ目は local identremote ident で、暗号化の対象が 192.168.10.0/24 → 192.168.20.0/24 = crypto ACL で定義した interesting traffic に一致していることが分かります。2 つ目は #pkts encaps: 4 / #pkts decaps: 4 のカウンタで、実際に 4 パケットが暗号化 (encaps) されて送られ、4 パケットが復号 (decaps) されて受け取られたこと = 暗号化が本当に起きていることを示します。3 つ目が二層構造で、inbound esp sas の SPI が 0x48EC19EF (1223432687)、outbound esp sas の SPI が 0xFF1BE21E (4280017438) と、方向別に 2 本の ESP SA が別々の SPI で立っています。SPI (Security Parameter Index) は SA を識別する番号で、行きと戻りで別々です。いずれも transform: esp-256-aes esp-sha256-hmac (AES256 で暗号化・SHA256 で完全性保護) で、in use settings ={Tunnel, } = トンネルモードです。

セッション全体は show crypto session にまとまります。

snippet
show crypto session
Crypto session current status

Interface: GigabitEthernet2
Session status: UP-ACTIVE     
Peer: 10.23.0.2 port 500 
  Session ID: 0  
  IKEv1 SA: local 10.12.0.1/500 remote 10.23.0.2/500 Active 
  IPSEC FLOW: permit ip 192.168.10.0/255.255.255.0 192.168.20.0/255.255.255.0 
        Active SAs: 2, origin: crypto map

Session status: UP-ACTIVE でトンネルが確立し、IKEv1 SA: local 10.12.0.1/500 remote 10.23.0.2/500 = IKE が ポート 500 で立っていること、Active SAs: 2 = データ用 IPsec SA が 2 本 (方向別) であることが一覧されます。ここまでで、管理用の ISAKMP SA 1 本の下にデータ用の IPsec SA 2 本がぶら下がる、IKEv1 の二層構造を実機で確認できました。

6. IKEv2 — IKE_SA_INIT + IKE_AUTH (4) に統合

IKEv2 は、IKEv1 の 2 フェーズ・9 メッセージを 4 メッセージ に統合した後継です。IKEv1 の main mode + quick mode という段階を分けず、IKE_SA_INIT (2 メッセージ)IKE_AUTH (2 メッセージ) の 2 往復で、IKE SA と最初の IPsec SA (IKEv2 では Child SA と呼びます) をまとめて確立します。

  • IKE_SA_INIT (request / response の 2 メッセージ) — アルゴリズムの交渉と DH 鍵交換を 1 往復で行い、IKE SA の鍵を作ります。
  • IKE_AUTH (request / response の 2 メッセージ) — 作った鍵で暗号化した中で相互認証を行い、同時に Child SA (最初の IPsec SA) も交渉します。

IKEv1 で 3 往復 (msg1-2 / msg3-4 / msg5-6) かけた Phase1 を IKE_SA_INIT の 1 往復にまとめ、認証と IPsec SA 交渉を IKE_AUTH の 1 往復に統合しています。

この 4 メッセージの流れは以下のとおりです。

IKEv2 の 4 メッセージ。IKE_SA_INIT (request/response) でアルゴリズム交渉と DH 鍵交換を 1 往復にまとめて IKE SA を作り、続く IKE_AUTH (request/response) で相互認証と Child SA (IPsec SA) の交渉を 1 往復で行う。IKEv1 (図3) と同じ上段経路図で、下段のステップ数だけが 9 から 4 に減る双子レイアウト。IKE SA と Child SA が右側テーブルで同時に立つ

R1 の IKEv1 設定を撤去し、IKEv2 の設定 (ikev2 proposal・policy・keyring・profile・transform-set) に載せ替えて、同じ crypto map で Gi2 に適用します。同じ ping を撃ちます。

snippet
ping 192.168.20.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.20.1, timeout is 2 seconds:
Packet sent with a source address of 192.168.10.1 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms

!!!!! で成功率 100 パーセントです。IKEv2 でも同じトンネルが張れています。IKEv2 の SA は専用の show crypto ikev2 sa で確認します。

snippet
show crypto ikev2 sa
 IPv4 Crypto IKEv2  SA 

Tunnel-id Local                 Remote                fvrf/ivrf            Status 
1         10.12.0.1/500         10.23.0.2/500         none/none            READY  
      Encr: AES-CBC, keysize: 256, PRF: SHA256, Hash: SHA256, DH Grp:14, Auth sign: PSK, Auth verify: PSK
      Life/Active Time: 86400/12 sec

IKEv1 では ISAKMP SA と IPsec SA を別々の show で見ましたが、IKEv2 では 1 行に統合 されています。Status READY = 確立済みで、Encr: AES-CBC, keysize: 256, PRF: SHA256, DH Grp:14, Auth sign/verify: PSK = 合意したアルゴリズムが 1 行にまとまっています。トランスフォーム (AES256・SHA256・DH14・PSK) は §5 の IKEv1 とまったく同じで、変わったのは IKE の交換方法だけ であることが分かります。

ここで、IKEv2 が IKEv1 と別のテーブルで管理されていることを確かめます。IKEv2 でトンネルが立っている状態で、IKEv1 用の show crypto isakmp sa を見ます。

snippet
show crypto isakmp sa
IPv4 Crypto ISAKMP SA
dst             src             state          conn-id status

IPv6 Crypto ISAKMP SA

空です。§5 では同じコマンドで QM_IDLE の SA が 1 本見えましたが、IKEv2 使用時は 1 本もありません。IKEv2 の SA は show crypto ikev2 sa の側にだけ現れ、IKEv1 の show crypto isakmp sa には出ません。両者はテーブルが分離されているため、トラブルシュートのときは どちらの IKE を使っているかで見るコマンドを変える 必要があります。

一方、Phase2 の成果物である IPsec SA (ESP) は、IKE 版に依存しません。IKEv2 でも show crypto ipsec sa は §5 と同じ形式で、方向別 2 本の ESP SA が立ちます。IKE の交換で作った鍵を使って ESP がデータを守る、という後半の仕組みは IKEv1 でも IKEv2 でも共通だからです。

7. IKEv1 と IKEv2 の対比 — なぜ 9 から 4 になったか

IKEv1 の 9 メッセージと IKEv2 の 4 メッセージを、同じ横軸で並べて対比します。

IKEv1 と IKEv2 のメッセージ数対比。上段が IKEv1 の 9 メッセージ (main mode 6 + quick mode 3)、下段が IKEv2 の 4 メッセージ (IKE_SA_INIT 2 + IKE_AUTH 2)。同一の横軸に並べ、9 対 4 の圧縮を数値カードで併記する。IKEv2 は IKE_SA_INIT で cookie による DoS 耐性を持つ点も注記。トランスフォーム (AES256・SHA256・DH14・PSK) は両者で同一で、変わったのは IKE の交換効率だけ

IKEv1 から IKEv2 で変わった点を整理すると、以下のとおりです。

項目IKEv1IKEv2
Phase1 の交換main mode 6 メッセージ (または aggressive mode 3)IKE_SA_INIT 2 メッセージ
Phase2 の交換quick mode 3 メッセージIKE_AUTH に統合 (2 メッセージ)
合計メッセージ数9 (main mode 時)4
管理 SA の名称ISAKMP SAIKE SA
最初のデータ SA の名称IPsec SAChild SA
確認コマンドshow crypto isakmp sashow crypto ikev2 sa
DoS 耐性弱いcookie 機構で強化

メッセージ数が 9 から 4 に減った理由は、フェーズの統合にあります。IKEv1 は Phase1 (ISAKMP SA の確立) と Phase2 (IPsec SA の確立) を明確に分け、Phase1 だけで 6 メッセージを使いました。IKEv2 は、鍵交換 (IKE_SA_INIT) と認証+IPsec SA 交渉 (IKE_AUTH) の 2 往復にまとめ、5 メッセージ分を削減しました。

IKEv2 は効率だけでなく堅牢性でも改善しています。IKE_SA_INIT では cookie 機構 により、大量の偽の初期メッセージで相手のリソースを枯渇させる DoS 攻撃に対する耐性を持ちます。また、SA の削除や設定情報のやりとりが標準化され、状態管理が明快になりました。

重要なのは、§6 で見たとおり トランスフォーム (AES256・SHA256・DH group14・PSK) は両者で同一 だということです。守り方 (ESP でどう暗号化するか) は変わっておらず、変わったのは 鍵を配る IKE の交換の効率と堅牢性 だけです。IPsec そのものが強くなったのではなく、その入口である IKE が洗練されたと捉えるのが正確です。

8. NAT-T — 経路に NAT がいると何が起きるか

ここで 4-6 の伏線を回収します。前節の末尾で、NAT が経路の途中でヘッダを書き換えると IPsec の検証が壊れる、と述べました。この矛盾を実際に起こし、それを解く NAT-T (NAT Traversal) を発火させます。

問題の構造は次のとおりです。IPsec の ESP はプロトコル番号 50 で運ばれ、TCP や UDP のような ポート番号を持ちません。PAT (ポートで多重化する NAT) は送信元ポートを付け替えて多重化しますが、ポートを持たない生の ESP はポートで区別できず、PAT を素直に通れません。これが NAT と生の ESP が相性の悪い主因です (RFC 3948)。加えて、ESP 自体の完全性チェック (ICV) は外側 IP ヘッダを対象に含まないものの、TCP/UDP のチェックサムのように内側ペイロードが外側アドレスに依存する場合や、複数拠点が同一 PAT アドレスに集約されるケースでは、NAT を挟むと復元・区別が破綻し得ます。なお、IP ヘッダの不変フィールドまで認証対象に含むのは AH (Authentication Header) の方で、AH は NAT と原理的に両立しません (ESP は外側 IP ヘッダを認証しないため、両立不能なのは AH)。

NAT-T は、この問題を ESP を UDP のポート 4500 でさらにカプセル化する ことで解決します。生の ESP (プロトコル 50) の代わりに、UDP4500 のパケットの中に ESP を包んで運べば、ポート番号を持つ普通の UDP として PAT を通れるようになります。この UDP4500 への切り替えは、IKE のネゴの中で 両端が経路上に NAT がいることを検出したときにだけ自動で発生 します。

検出は、IKE の初期メッセージに NAT 検出ペイロード (NAT-D) を載せて行います。送信元・宛先のアドレスとポートのハッシュを相手に送り、受け取った側が「自分が計算したハッシュと違う = 途中で誰かがアドレスを書き換えた = NAT がいる」と判断します。IKEv2 では最初の IKE_SA_INIT の中で、この検出が完了します。

本ラボでは、中間の R2 に PAT を投入して NAT-T を発火させます。R2 が GW 間の IKE (UDP500/4500) を PAT すると、R3 から見た R1 の送信元が R2 の Gi3 (10.23.0.1) に化けます。まず R1 の側の IKE_SA_INIT の debug を見ます。

snippet
IKEv2 IKE_SA_INIT Exchange REQUEST 
Payload contents: 
 SA KE N VID VID VID VID NOTIFY(NAT_DETECTION_SOURCE_IP) NOTIFY(NAT_DETECTION_DESTINATION_IP) 
...
Checking NAT discovery
NAT INSIDE found
NAT detected float to init port 4500, resp port 4500

IKE_SA_INIT の REQUEST に NOTIFY(NAT_DETECTION_SOURCE_IP)NOTIFY(NAT_DETECTION_DESTINATION_IP) = NAT 検出ペイロードが載っています。相手からの応答を処理する Checking NAT discoveryNAT INSIDE found (経路上に NAT を検出) となり、NAT detected float to init port 4500, resp port 4500 = UDP500 から UDP4500 へ移る (float する) ことが決まりました。この検出は生の ESP が流れる前の IKE_SA_INIT で完結しています。

SA が確立した後の show crypto ikev2 sa を見ます。

snippet
show crypto ikev2 sa
 IPv4 Crypto IKEv2  SA 

Tunnel-id Local                 Remote                fvrf/ivrf            Status 
1         10.12.0.1/4500        10.23.0.2/4500        none/none            READY  
      Encr: AES-CBC, keysize: 256, PRF: SHA256, Hash: SHA256, DH Grp:14, Auth sign: PSK, Auth verify: PSK

§6 では 10.12.0.1/500 ... 10.23.0.2/500 = ポート 500 だった Local/Remote が、10.12.0.1/4500 ... 10.23.0.2/4500 = ポート 4500 に移っています。これが NAT-T が発火した決定的な証拠です。同じ GW 設定のまま経路に NAT を挟んだだけで、IKE が UDP4500 に移りました。

ESP 側の変化は show crypto ipsec sa に出ます。

snippet
show crypto ipsec sa
...
   current_peer 10.23.0.2 port 4500
...
     inbound esp sas:
      spi: 0x401235AC(1074935212)
        transform: esp-256-aes esp-sha256-hmac ,
        in use settings ={Tunnel UDP-Encaps, }

current_peer 10.23.0.2 port 4500 とポートが 4500 になり、in use settings ={Tunnel UDP-Encaps, } = ESP が UDP でカプセル化 (UDP-Encaps) されている ことが読み取れます。§5 では ={Tunnel, } だけだったのに対し、UDP-Encaps が加わりました。ESP が UDP4500 に包まれてトンネルモードで運ばれる、NAT-T の状態です。

NAT を実行している R2 の変換テーブルを見ると、UDP500 と UDP4500 の両方が並びます。

snippet
show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
udp  10.23.0.1:5062        10.12.0.1:4500        10.23.0.2:4500        10.23.0.2:4500
udp  10.23.0.1:512         10.12.0.1:500         10.23.0.2:500         10.23.0.2:500
Total number of translations: 2

2 行あります。下の行が UDP500 (NAT 検出を行った IKE_SA_INIT のやりとり)、上の行が UDP4500 (float 後の IKE と ESP) です。両方が並ぶのが「まず UDP500 で NAT を検出し、その後 UDP4500 に移行した」証跡です。R1 の送信元 (10.12.0.1) が、R2 の外側 = Inside global の 10.23.0.1 に PAT されて R3 に届いていることも読み取れます。この NAT 越えのトンネルで、内部間の ping は 100 パーセントで通ります。

responder は相手の実アドレスを事前に知れない — wildcard 受けと dynamic crypto map

NAT-T を成立させるには、responder 側 (R3) の設定に踏み込んだ変更が要ります。ここが本節で最も実務的な学びです。

§5・§6 の NAT なしの構成では、R3 は R1 の実アドレス (10.12.0.1) を set peer で固定していました。相手が誰か分かっているからです。ところが NAT が入ると、R3 から見た R1 の送信元は R2 に PAT された 10.23.0.1 に化けます。R3 は、着信してくる相手が本当は R1 だと事前には知りようがありません。PAT の変換後アドレスは動的に決まるからです。相手を固定する設定のままでは、化けた送信元からの着信を受け付けられず、SA が立ちません。

このため、responder の R3 を 2 つの点で「不特定の相手を受ける」形 に変更します。1 つ目は認証で、特定アドレスに紐づいた PSK ではなく、任意のアドレスからの着信を受ける wildcard の PSK にします (IKEv2 なら keyring を address 0.0.0.0 0.0.0.0match identity remote address 0.0.0.0 0.0.0.0、IKEv1 なら crypto isakmp key … address 0.0.0.0 0.0.0.0)。2 つ目が SA の受け方で、peer を固定する static crypto map では受けられず、dynamic crypto map が必要 になります。

実機では、認証を wildcard にしても、まだトンネルが立たない状態が起きました。R3 が IKE_AUTH の応答で NOTIFY(NO_PROPOSAL_CHOSEN) = 提案された IPsec ポリシーに一致するものが見つからない、を返して落ちていたのです。原因は、R3 の static crypto map が peer を 10.12.0.1 に固定していたことにあります。static crypto map は「この決まった相手とだけトンネルを張る」宣言なので、NAT で送信元が 10.23.0.1 に化けた 未知アドレスからの Child SA 提案を検証できず に拒否していました。

これを解くのが dynamic crypto map です。dynamic crypto map は peer を固定せず、着信してきた相手に合わせて動的に SA を作れます。R3 を dynamic crypto map に置き換えると、化けた送信元からの提案を受け付け、トンネルが立ちました。R3 の crypto map を確認します。

snippet
show crypto map
Crypto Map IPv4 "CMAP" 10 ipsec-isakmp
	Dynamic map template tag: DMAP

Crypto Map IPv4 "CMAP" 65536 ipsec-isakmp
	Peer = 10.23.0.1
	Access-List SS dynamic: False
	Extended IP access list 
	    access-list  permit ip 192.168.20.0 0.0.0.255 192.168.10.0 0.0.0.255
	Current peer: 10.23.0.1
	    dynamic (created from dynamic map DMAP/10)
	...
	Responder-Only (Y/N): N

R3 の crypto map が Dynamic map template tag: DMAP を持ち、着信を受けてから動的に生成されたエントリの Current peer: 10.23.0.1 = R2 に PAT された送信元アドレスを相手として SA を張っていることが分かります。NAT 越えでは、responder は相手の実アドレスを事前に知れないため、wildcard 受け + dynamic crypto map で「動的に決まる相手」を受け入れる 必要がある、という運用の勘所です。これは、相手が分かっている前提の static crypto map の限界を NAT-T が突いた形です。

なお、initiator の R1 側は変更が要りません。R1 から R3 への向きには NAT がなく (片方向 NAT・R1 が常に initiator)、R1 は R3 の実アドレス (10.23.0.2) を固定したままトンネルを張れます。

NAT-T は IKE のバージョンに依存しない

ここまでは IKEv2 で NAT-T を発火させました。同じ NAT の経路のまま IKEv1 に戻しても、NAT-T は同様に動きます。R3 を IKEv1 の wildcard PSK + dynamic crypto map にして、同じ ping を撃つと 100 パーセントで通り、show crypto isakmp sa に SA が立ち、show crypto ipsec sa の ESP は同じく in use settings ={Tunnel UDP-Encaps, } になります。R2 の変換テーブルにも UDP4500 が現れます。

NAT-T は ESP を UDP でカプセル化する仕組みであり、その入口の IKE が v1 か v2 かとは独立しています。したがって NAT-T は IKE のバージョンに依存せず、IKEv1 でも IKEv2 でも、経路に NAT があれば同じように UDP4500 へ移ります。NAT-T のフローは以下のとおりです。

NAT-T の UDP4500 フロー。ステップ順は NAT 検出 (IKE の初期メッセージに NAT-D ペイロードを載せ、UDP500 で相手のハッシュと突き合わせて経路上の NAT を検出) → UDP500 から UDP4500 への float → ESP を UDP4500 でカプセル化 (ESP-in-UDP)、の 3 段。R2 の PAT を UDP4500 の普通の UDP として越えていく様子を矢印の色変化で示す。生の ESP (プロトコル 50) が NAT-T なしでは PAT を越えられない様子は、点線の反実仮想として別枠で描く

9. 落とし穴・補足

IPsec は設定項目が多く、1 か所の食い違いで静かに立たないことが多い機能です。本ラボの実機検証で実際に踏んだものを含め、押さえておきたい点をまとめます。

内部網への static route は next-hop を IP で指定する (最重要)。 本ラボで最も嵌まったのがこれです。crypto の設定 (isakmp policy・PSK・transform-set・crypto map・peer・ACL) がすべて正しく、GW 間の外側疎通も 100 パーセントなのに、interesting traffic の ping を撃っても IKE が 1 メッセージも発火しない 事象が起きました。show crypto isakmp sa は空、show crypto sessionSession status: DOWN のままです。原因は、相手内部網への static route を ip route 192.168.20.0 255.255.255.0 GigabitEthernet2インターフェース指定 にしていたことでした。これだと R1 は宛先を「直結」と誤認して Gi2 上で ARP 解決を試み、失敗してパケットを捨て、crypto map に到達しません。修正は next-hop を IP で指定 すること (ip route 192.168.20.0 255.255.255.0 10.12.0.2) です。これで crypto map を通過して IKE が発火します。4-6 で「NAT は変換後・変換前の両方に戻り経路が要る」を踏んだのと対応する、経路の落とし穴です。

内部網を OSPF で平文広告しない。 §3 で述べたとおり、暗号化して守りたい内部網を OSPF で相互広告すると、平文経路で直接ルーティングされて crypto ACL にマッチせず、暗号化されないまま素通りしてしまいます。内部網は非広告にし、相手内部網への到達はトンネル経由 (と上記の static route) だけで成立させます。

crypto は Mgmt (Gi1) に当てない。 crypto map は必ずデータ IF (Gi2) に適用します。管理 IF に当てると、管理用の SSH 自体が暗号化対象に巻き込まれて接続が壊れます。

IKEv1 と IKEv2 は同じ IF に同時投入しない。 両者はテーブルが分離されており (§6)、片方の設定を残したまま他方を入れると SA が中途半端に残ることがあります。切り替えるときは前バージョンの crypto map・SA・定義を撤去してから入れます。アクティブな SA が残っていると定義の削除が拒否されることがあるため、clear crypto sa を定義削除より先に打ちます。

SA 確立の初弾 drop は正常。 §5 で見たとおり、interesting traffic の 1 発目は IKE のネゴを引き起こしている最中に落ち、.!!!! になります。IPsec は対象トラフィックが発生してから SA を張り始めるため、初弾が落ちるのは仕様です。repeat を増やして 2 発目以降が通ることを確認します。

encaps/decaps カウンタが 0 のままなら ACL 未マッチを疑う。 show crypto ipsec sa#pkts encaps が 0 のまま増えない場合、interesting traffic の ACL に ping がマッチしていません。ping の送信元を crypto ACL の対象 (本ラボなら Loopback10 = 192.168.10.1) にしているかを先に確認します。

IKE の PSK と SSH 用の RSA 鍵は無関係。 装置の初期設定で作る crypto key generate rsa は SSH 接続のための鍵で、IKE の PSK 認証とは無関係です。IKE が立たないときに RSA 鍵の有無を疑って迷走しないよう、両者を分けて考えます。

10. 次節

本節では、通信の中身を暗号で守る IPsec を扱いました。鍵を安全に配る IKE と、方向別・寿命別の暗号契約である SA の関係 (§4)、IKEv1 の main mode 6 + quick mode 3 = 9 メッセージと二層の SA 構造 (§5)、IKEv2 が IKE_SA_INIT + IKE_AUTH = 4 メッセージに統合したこと (§6)、両者でトランスフォームは同一で変わったのは IKE の効率だけであること (§7)、経路に NAT を挟むと UDP500 から UDP4500 へ移る NAT-T と、responder に wildcard 受け + dynamic crypto map が要ること (§8) を、csr1000v の show 出力で確認しました。とりわけ、NAT-T では responder が相手の実アドレスを事前に知れないという点が、static crypto map の限界を突く運用の勘所でした。

本節は IKE と SA の仕組みに徹し、トンネルを 1 本張って観察することに集中しました。次節 4-8 Site-to-Site VPN では、実際の拠点間トンネルの構成に進みます。本節で使った crypto map 方式と、より新しい VTI (Virtual Tunnel Interface) 方式の運用比較、鍵を定期的に作り直して過去の通信を守る PFS (Perfect Forward Secrecy)、複数拠点をつなぐ実構成を扱い、IKE と SA の土台の上に実運用の VPN を組み立てていきます。