STUDY · NETWORK GUIDE

4-6 NAT/PAT — プライベートとグローバルを変換する仕組み

inside と outside の向きでアドレスを変換する NAT を扱う。static/dynamic/PAT の 3 方式と、変換テーブルに現れる 4 象限 (inside local/global・outside local/global) を csr1000v で検証し、変換後・変換前の両方に戻り経路が要る勘所を実機で確かめる。

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

前節 4-5 ZBF では、インターフェースをゾーンにまとめ、ゾーン間の通信をゾーンペアの向きでステートフルに制御する Zone-Based Firewall を扱いました。inside から outside へ出た通信をセッションとして記憶し、その戻りを自動で許可する一方、outside 発の新規通信は既定 deny で遮断する、という 向き状態 (セッション) の考え方が中心でした。

本節で扱う NAT (Network Address Translation) も、この 2 つの考え方を引き継ぎます。NAT は、内部で使うプライベートアドレスと、外部で使うグローバルアドレスを 変換 する仕組みです。ここでも inside と outside という向き が中心になります。内部から外部へ出る通信では送信元アドレスを内部の実アドレスから変換後のアドレスへ書き換え、外部から戻ってくる通信では宛先アドレスを逆に書き換えて内部へ戻します。ZBF がセッションを記憶して戻りを通したのと同じように、NAT も変換の対応を 変換テーブル に記憶し、戻りの通信を逆変換します。

NAT が生まれた背景には、IPv4 アドレスの枯渇があります。世界中の機器に一意のグローバルアドレスを配るには IPv4 の 32 ビットは足りず、組織内ではプライベートアドレス (RFC1918 の 10.0.0.0/8 / 172.16.0.0/12 / 192.168.0.0/16) を使い、外部と通信するときだけ限られたグローバルアドレスに変換する、という運用が広まりました。本節では csr1000v 3 台を使い、Static NAT (1:1 の固定変換)Dynamic NAT (プールからの動的割り当て)PAT (1 つのグローバルアドレスをポート番号で多重化) の 3 方式を、実機の show ip nat translations の出力とともに検証します。あわせて、外部から内部の特定サービスを公開する Static PAT (ポートフォワーディング)、プールを使い切ったときの挙動、そして NAT で最も嵌まりやすい 戻り経路 の設計を扱います。

2. なぜ変換が要るのか — プライベートアドレスと inside/outside/local/global

NAT を理解する第一歩は、同じ 1 台のホストが、見る場所によって違うアドレスで呼ばれる ことを受け入れることです。内部から見た内部ホストのアドレスと、外部から見た同じホストのアドレスは異なります。NAT はこの「場所による呼び名の違い」を管理する仕組みで、Cisco はこれを inside/outside (内部か外部か) と local/global (変換前か変換後か) の 2 軸、計 4 象限で整理します。

  • Inside Local — 内部から見た内部ホストの実アドレス。組織内で実際に設定されているプライベートアドレスです。
  • Inside Global — 外部から見た内部ホストのアドレス。NAT で変換された後のグローバルアドレスで、外部にはこのアドレスとして見えます。
  • Outside Local — 内部から見た外部ホストのアドレス。
  • Outside Global — 外部から見た外部ホストの実アドレス。

本節のラボでは外部ホスト (R3) 側は変換しないため、Outside Local と Outside Global は同じ値になります。観察の焦点は左 2 象限、すなわち Inside Local (内部の実アドレス) が Inside Global (変換後のアドレス) にどう変換されるか に集約されます。この 2 象限の対応が show ip nat translations に 1 行ずつ現れる様子を、本節を通じて追いかけます。

用語で注意したいのは、local と global は「プライベート/パブリック」と必ずしも一致しない ことです。local は「変換前 (NAT の内側から見た値)」、global は「変換後 (NAT の外側から見た値)」を指す相対的な呼び名であり、アドレスが RFC1918 かどうかとは別の概念です。本節では教材として分かりやすくするため、Inside Local に RFC1918 のプライベートアドレス、Inside Global にグローバルアドレスを割り当てますが、この対応は「そう設定したから」であって、local/global の定義そのものではない点を押さえておきます。

3. ラボトポロジ

本節の検証で使うトポロジを示します。csr1000v 3 台を直列につなぎ、中央の R2 に NAT を適用します。

4-6 NAT/PAT ラボトポロジ。R2 (csr1000v) が NAT 変換点で、R1 方向の Gi2 を ip nat inside (内部プライベート側)、R3 方向の Gi3 を ip nat outside (グローバル見立て側) に割り当てる。R1 は内部ホスト (Lo10 192.168.10.1 ほか、RFC1918)、R3 は外部サーバ (Lo20 198.51.100.1)。R2 を境に、左の inside local (192.168.x) が右の inside global (203.0.113.x) に変換される。内部プライベートは OSPF で外に広告せず、変換後アドレスへの戻り経路は static route で作る

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

  • R1 (内部ホスト) — Loopback10 に 192.168.10.1、Loopback11 に 192.168.11.11、Loopback12 に 192.168.12.12 を持ちます。いずれも RFC1918 のプライベートアドレスで、Inside Local を表す内部ホストの代わりです。R2 への Gi2 に 10.12.0.1 を持ちます。
  • R2 (NAT ルータ) — R1 への Gi2 に 10.12.0.2 を持ち、これを ip nat inside に指定します。R3 への Gi3 に 10.23.0.1 を持ち、これを ip nat outside に指定します。この 2 つのインターフェースが「変換の境界」になります。
  • R3 (外部サーバ) — Loopback20 に 198.51.100.1 を持ち、ip http server で TCP80 を待ち受けます。外部の通信相手 (宛先) を表します。

アドレスは、内部プライベートに RFC1918 の 192.168.x.0/24 を、変換後のグローバルと外部サーバの見立てには RFC5737 のドキュメント用ブロック (203.0.113.0/24 = TEST-NET-3 を変換後のグローバル、198.51.100.0/24 = TEST-NET-2 を外部サーバ) を割り当てています。CML は実インターネットではないため、これらはすべて同じラボ内のアドレスで、「グローバルに見立てている」だけです。この点は §5 の戻り経路の設計で重要になります。

R1・R2・R3 のリンクと Loopback0 は OSPF area 0 で相互に広告し、透過的な疎通の土台を作っています。ただし後述するように、R1 の 192.168.x.0/24 は意図的に OSPF で広告しません。これが NAT の前提を作ります。R3 が学習している経路を確認します。

snippet
show ip route
      10.0.0.0/8 is variably subnetted, 6 subnets, 2 masks
O        10.0.1.1/32 [110/3] via 10.23.0.1, 00:03:50, GigabitEthernet2
O        10.0.2.1/32 [110/2] via 10.23.0.1, 00:03:50, GigabitEthernet2
C        10.0.3.1/32 is directly connected, Loopback0
O        10.12.0.0/30 [110/2] via 10.23.0.1, 00:03:50, GigabitEthernet2
C        10.23.0.0/30 is directly connected, GigabitEthernet2
L        10.23.0.2/32 is directly connected, GigabitEthernet2

R3 は R1・R2 の Loopback0 やリンク (10.x) を OSPF で学習していますが、R1 の内部プライベート 192.168.x.0/24 はここに現れません。R3 から見て、内部ホストの実アドレスは存在しないのと同じです。この状態が NAT の出発点になります。

4. NAT なしでは届かない — 変換の動機

NAT を設定する前に、内部ホストから外部サーバへ ping を撃ってみます。R1 の Loopback10 (192.168.10.1) を送信元にして、R3 の 198.51.100.1 へ ping します。

snippet
ping 198.51.100.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 198.51.100.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 パーセントです。届きません。理由は §3 で確認したとおり、R3 が送信元の 192.168.10.1 への戻り経路を持たない ためです。R1 が送った ICMP echo は R3 まで届きますが、R3 が返そうとする echo reply は宛先が 192.168.10.1 であり、R3 はこのプライベートアドレスへの経路を知りません。行きは届いても帰りが返せない、という状態です。

これが NAT の動機です。プライベートアドレスをそのまま外部に出しても、外部はその実アドレスへの戻り方を知りません。そこで、外部と通信するときだけ送信元をグローバルアドレスに変換し、外部からはそのグローバルアドレスとしてやりとりする必要があります。以降、この変換を 3 つの方式で構築していきます。

5. 戻り経路の設計 — 変換後と変換前の両方に経路が要る

NAT の設定に入る前に、最も嵌まりやすい 戻り経路 を先に押さえます。NAT は送信元・宛先を書き換えるため、パケットの往復が異なるアドレスで評価されます。このため、変換後のアドレス変換前のアドレス の両方に、それぞれ戻る経路が必要になります。

内部ホスト 192.168.10.1 からの通信を、R2 が 203.0.113.5 (グローバル) に変換して外へ出すとします。このとき戻りのために必要な経路は 2 本です。

  1. R3 (外部) に、変換後アドレス 203.0.113.0/24 への経路 — R3 が受け取るパケットの送信元は 203.0.113.5 です。R3 が応答を返すには、この 203.0.113.0/24 を R2 (Gi3 = 10.23.0.1) へ向ける経路が要ります。
  2. R2 に、変換前アドレス 192.168.x.0/24 への経路 — R2 は外部から戻ってきた 203.0.113.5 宛のパケットを 192.168.10.1 に逆変換した後、内部へ送る必要があります。ところが §3 で 192.168.x.0/24 を OSPF で広告しないようにしたため、R2 自身もこのプライベート網への経路を失います。そこで R2 に、変換前アドレスへの経路を明示的に用意します。

本ラボでは、この 2 本を static route で作ります。R2 には変換前アドレス (内部プライベート 3 網) への経路を、R3 には変換後アドレス (グローバルプール) への経路を置きます。

snippet
! R2: 逆変換後に内部プライベートへ戻すための経路 (R1 = 10.12.0.1 向き)
ip route 192.168.10.0 255.255.255.0 10.12.0.1
ip route 192.168.11.0 255.255.255.0 10.12.0.1
ip route 192.168.12.0 255.255.255.0 10.12.0.1
snippet
! R3: 変換後アドレス宛の応答を R2 へ返すための経路 (R2 = 10.23.0.1 向き)
ip route 203.0.113.0 255.255.255.0 10.23.0.1

R2 の 3 本の static route は R2 のローカルな経路であり、OSPF で R3 に広告されません。したがって R3 は内部プライベートを知らないまま (NAT の前提を保ったまま)、R2 だけが逆変換後の戻り先を知っている状態になります。

NAT の設定を入れても通信が成立しないとき、多くの場合この戻り経路が原因です。変換テーブルには行が載る (変換自体は起きている) のに ping だけが返らない という症状が出たら、show ip route で変換後アドレスと変換前アドレスの両方に経路があるかを確認するのが定石です。この「往復で異なるアドレスに経路が要る」ことこそ、NAT がステートレスなルーティングと決定的に違う点です。

6. Static NAT — 1 対 1 の固定変換

最初の方式は Static NAT です。1 つの内部アドレスを 1 つのグローバルアドレスに固定で対応づけます。R2 に次の 1 行を設定します。

snippet
ip nat inside source static 192.168.10.1 203.0.113.5

ip nat inside source static <内部> <グローバル> は、内部から外部へ出る通信 (inside source) の送信元を、192.168.10.1 から 203.0.113.5 へ静的に変換する、という意味です。設定した瞬間から、この対応は変換テーブルに常設されます。同じ ping をもう一度撃ってみます。

snippet
ping 198.51.100.1 source Loopback10 repeat 5
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 198.51.100.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

!!!!! (感嘆符 5 つ) で成功率 100 パーセントです。§4 で 0 パーセントだった同じ ping が、Static NAT を 1 行入れただけで通るようになりました。R1 が送る送信元 192.168.10.1 が R2 で 203.0.113.5 に変換され、R3 は 203.0.113.5 を送信元として受け取ります。R3 が 203.0.113.5 宛に返す応答は、§5 で用意した戻り経路を通って R2 に戻り、R2 が宛先を 192.168.10.1 に逆変換して R1 へ届けます。この 0 パーセントから 100 パーセントへの反転が、NAT が何をしているかを最も端的に示しています。

変換テーブルを確認します。

snippet
show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
---  203.0.113.5           192.168.10.1          ---                   ---
icmp 203.0.113.5:1         192.168.10.1:1        198.51.100.1:1        198.51.100.1:1
Total number of translations: 2

2 行あります。1 行目は Pro 列が --- で、Inside global = 203.0.113.5Inside local = 192.168.10.1 の対応だけを示し、Outside 列は --- です。これは Static NAT の常設マッピング で、通信の有無に関わらず設定した時点から存在します。2 行目は Pro = icmp で、実際に流れた ICMP のフローを表す動的なエントリです。こちらは Outside 列に相手の 198.51.100.1 が入り、送信元・宛先の 4 象限がすべて埋まっています。「--- 行 = 常設の対応」「プロトコル行 = 実際に流れたフローのセッション」という 2 種類のエントリの違いを、この出力で押さえておきます。

7. Dynamic NAT — プールから動的に割り当てる

Static NAT は 1 対 1 の固定対応でしたが、内部ホストが多いと 1 つずつ静的に書くのは現実的ではありません。Dynamic NAT は、グローバルアドレスの プール (pool) を用意し、内部ホストが通信を始めたときに空いているアドレスを動的に割り当てます。R2 に次のように設定します。

snippet
ip access-list standard NAT-INSIDE
 permit 192.168.0.0 0.0.255.255
!
ip nat pool GLOBALPOOL 203.0.113.20 203.0.113.29 netmask 255.255.255.0
!
ip nat inside source list NAT-INSIDE pool GLOBALPOOL

まず、変換対象の内部アドレスを ACL NAT-INSIDE で指定します。ここでは 3 つの内部網 (192.168.10/11/12.0/24) をまとめて 192.168.0.0 0.0.255.255 で拾っています。NAT が参照する ACL は permit した範囲を「変換する」 という意味で、ACL のようにトラフィックを遮断するわけではない点に注意します。次に ip nat pool で変換後に使うグローバルアドレスの範囲 (203.0.113.20203.0.113.29 の 10 個) を定義します。最後の ip nat inside source list <ACL> pool <プール名> が、「ACL にマッチした内部アドレスを、プールから割り当てたグローバルアドレスに変換する」という指定です。

Static NAT と違い、Dynamic NAT の対応は 通信が始まるまで存在しません。設定直後の変換テーブルを見ます。

snippet
show ip nat translations
Total number of translations: 0

空です。ここで R1 の Loopback10 (192.168.10.1) と Loopback11 (192.168.11.11) から順に ping を撃ち、もう一度テーブルを見ます。

snippet
show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
---  203.0.113.20          192.168.10.1          ---                   ---
---  203.0.113.21          192.168.11.11         ---                   ---
icmp 203.0.113.20:2        192.168.10.1:2        198.51.100.1:2        198.51.100.1:2
icmp 203.0.113.21:3        192.168.11.11:3       198.51.100.1:3        198.51.100.1:3
Total number of translations: 4

通信を始めた 2 つの内部ホストに、プールの先頭から順に 203.0.113.20203.0.113.21 が割り当てられました。ここが Dynamic NAT の要点で、overload を付けていないこの設定では、内部ホスト 1 つにつきグローバルアドレスを 1 つ、1 対 1 で割り当てます。3 台目の内部ホストが通信を始めればプールの 3 番目 203.0.113.22 が割り当てられ、プールを使い切ると次のホストは変換できなくなります (この限界は §9 で確認します)。

プールの使用状況は show ip nat statistics で確認できます。

snippet
show ip nat statistics
Total active translations: 4 (0 static, 4 dynamic; 2 extended)
...
Dynamic mappings:
-- Inside Source
[Id: 1] access-list NAT-INSIDE pool GLOBALPOOL refcount 4
 pool GLOBALPOOL: id 1, netmask 255.255.255.0
	start 203.0.113.20 end 203.0.113.29
	type generic, total addresses 10, allocated 2 (20%), misses 0

pool GLOBALPOOL の行に total addresses 10, allocated 2 (20%) とあり、10 個中 2 個 (20 パーセント) を割り当て済みと分かります。プールの消費状況を把握する重要な出力です。

8. PAT — 1 つのアドレスをポート番号で多重化する

Dynamic NAT は内部ホスト 1 つにグローバル 1 つを割り当てるため、同時に通信できる内部ホスト数がプールのアドレス数で頭打ちになります。これでは IPv4 の節約という目的を十分には果たせません。そこで登場するのが PAT (Port Address Translation) です。PAT は、1 つのグローバルアドレスを、送信元ポート番号で多重化 することで、多数の内部ホストを 1 つのアドレスに集約します。Cisco の設定では overload キーワードで有効化するため、NAT overload とも呼ばれます。

最も実務的な設定は、変換後アドレスに 出口インターフェースのアドレスをそのまま使う 形です。R2 に次のように設定します。

snippet
ip nat inside source list NAT-INSIDE interface GigabitEthernet3 overload

interface GigabitEthernet3 overload は、「ACL にマッチした内部アドレスを、Gi3 のアドレス (10.23.0.1) に変換し、ポート番号で多重化する」という指定です。プールを別途用意する必要がなく、ルータが外部に持つ 1 つのアドレスだけで内部の多数を賄えます。R1 の Loopback10・Loopback11 の両方から ping と TCP80 への接続を行い、変換テーブルを見ます。

snippet
show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
tcp  10.23.0.1:5063        192.168.11.11:11266   198.51.100.1:80       198.51.100.1:80
tcp  10.23.0.1:5062        192.168.10.1:37889    198.51.100.1:80       198.51.100.1:80
icmp 10.23.0.1:11          192.168.11.11:11      198.51.100.1:11       198.51.100.1:11
icmp 10.23.0.1:10          192.168.10.1:10       198.51.100.1:10       198.51.100.1:10

すべての Inside global が 同じ 10.23.0.1 になっています。そして各行はポート番号 (または ICMP の識別子) が異なります。2 つの内部ホスト 192.168.10.1192.168.11.11 が、どちらも 10.23.0.1 に変換されつつ、TCP なら送信元ポート (50625063)、ICMP なら識別子 (1011) で区別されています。これが PAT の多重化です。1 つのグローバルアドレスに、理論上はポート番号の数だけフローを載せられます。

ここで TCP のポート番号が書き換えられている ことに注目します。1 行目の TCP は内部側が 192.168.11.11:11266 で、変換後が 10.23.0.1:5063 です。アドレスだけでなく ポート番号も 11266 から 5063 へ書き換わっています。PAT は、複数の内部ホストが偶然同じ送信元ポートを使っても衝突しないように、変換後のポートを付け替えます。多重化を成立させるための仕組みです。

3 つのプロトコルの追跡 — ICMP は識別子で区別する

PAT が扱うのは TCP だけではありません。TCP・UDP・ICMP の 3 つを同時に流したときの変換テーブルを見ます。

snippet
show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
tcp  10.23.0.1:5062        192.168.10.1:23042    198.51.100.1:80       198.51.100.1:80
udp  10.23.0.1:5063        192.168.10.1:49162    198.51.100.1:33437    198.51.100.1:33437
icmp 10.23.0.1:12          192.168.10.1:12       198.51.100.1:12       198.51.100.1:12
udp  10.23.0.1:5062        192.168.10.1:49161    198.51.100.1:33436    198.51.100.1:33436

TCP と UDP は、それぞれの ポート番号 で多重化されます (TCP の 230425062 に、UDP の 491615062 に、というように書き換わります)。一方、ICMP にはポート番号がありません。ping (ICMP echo) はポートを使わないため、PAT は ICMP パケットの Identifier フィールド を擬似的なポートとして使い、フローを区別します。この例では icmp 10.23.0.1:1212 が Identifier で、内部側の 192.168.10.1:1212 と一致していますが、これはポート番号ではなく識別子である点に注意します。PAT はプロトコルごとに「何を使ってフローを区別するか」を変えており、ポートを持たない ICMP では識別子で代用しているわけです。

9. プールを使い切ると — Dynamic NAT の限界

§7 の Dynamic NAT (overload なし) は内部ホストとグローバルアドレスを 1 対 1 で割り当てるため、プールを使い切ると次のホストは変換できません。これを実際に起こしてみます。プールを 2 個だけ (203.0.113.20203.0.113.21) に絞り、overload なしで、内部ホスト 3 台から順に通信を始めます。

snippet
! 1 台目 (192.168.10.1) → 203.0.113.20 が割り当てられる
Success rate is 100 percent (3/3), round-trip min/avg/max = 1/1/2 ms
! 2 台目 (192.168.11.11) → 203.0.113.21 が割り当てられる
Success rate is 100 percent (3/3), round-trip min/avg/max = 1/1/2 ms
! 3 台目 (192.168.12.12) → プールが空でない
Success rate is 0 percent (0/3)

1 台目・2 台目は成功しますが、3 台目は 0 パーセントで失敗 します。プールの 2 個をすでに使い切っているため、3 台目に割り当てるグローバルアドレスが無く、変換できずに通信が成立しません。show ip nat statistics で状況を確認します。

snippet
show ip nat statistics
Hits: 10  Misses: 2
...
[Id: 1] access-list NAT-INSIDE pool GLOBALPOOL refcount 4
 pool GLOBALPOOL: id 1, netmask 255.255.255.0
	type generic, total addresses 2, allocated 2 (100%), misses 3
In-to-out drops: 0  Out-to-in drops: 0

pool GLOBALPOOL の行が total addresses 2, allocated 2 (100%) となっています。プールの 2 個をすべて割り当て済み (100 パーセント) で、これが枯渇の直接の証拠です。あわせて misses 3 は、変換しようとしたが割り当てられなかった回数を示します。プールが枯渇したとき、Cisco は専用の派手なログを出すわけではなく、静かに変換に失敗して通信が落ちる だけです。だからこそ、allocated (100%) を主な手がかりとして把握することが運用上重要になります。この限界を解くのが、§8 の PAT (ポートで多重化) だったわけです。

10. Static PAT — 外から内の特定サービスを公開する

ここまでは内部から外部への通信 (inside から outside) を扱いました。逆に、外部から内部の特定のサービスへアクセスさせたい 場合があります。内部の Web サーバを外部に公開する、といったケースです。これを実現するのが Static PAT (ポートフォワーディング) です。特定のグローバルアドレスの特定ポート宛の通信を、内部の特定ホストの特定ポートへ転送します。R2 に次のように設定します。

snippet
ip nat inside source static tcp 192.168.10.1 80 203.0.113.10 80 extendable

ip nat inside source static tcp <内部> <内部ポート> <グローバル> <グローバルポート> は、「外部から 203.0.113.10 の TCP80 宛に来た通信を、内部の 192.168.10.1 の TCP80 へ転送する」という指定です。末尾の extendable は、同じグローバルアドレスを複数のポートフォワードで共有できるようにするオプションです。この設定も Static NAT と同様、通信の前から変換テーブルに常設されます。

snippet
show ip nat translations
Pro  Inside global         Inside local          Outside local         Outside global
tcp  203.0.113.10:80       192.168.10.1:80       ---                   ---
Total number of translations: 1

tcp 203.0.113.10:80 ← 192.168.10.1:80 の対応が、通信の前から 1 行載っています。ここで外部の R3 から、公開アドレス 203.0.113.10 の TCP80 へ接続してみます。

snippet
Trying 203.0.113.10, 80 ... Open
Server: openresty

Open となり、TCP セッションが確立しました。外部の R3 が 203.0.113.10:80 へ送った通信が、R2 で 192.168.10.1:80 に変換され、内部の Web サーバに到達しています。一方、公開していない別のポート (たとえば TCP23) へ接続しようとすると、変換テーブルに対応が無いため到達しません。Static PAT は「公開したポートだけ」を外部に開ける仕組みで、それ以外は内部に届かないという点が、セキュリティ上も重要です。

なお、これは outside から inside への通信であり、NAT の変換順序が内部発とは逆になります。内部発 (inside → outside) では「ルーティングで出口を決めてから送信元を変換」しますが、外部発 (outside → inside) では「宛先を先に変換してから内部へルーティング」します。Static PAT が成立するのは、外部から届いた宛先 203.0.113.10 を、ルーティングの前に 192.168.10.1 へ変換できるからです。

11. NAT の変換をアニメーションで追う

Static NAT の変換と戻りの逆変換を、時間を追って可視化します。

NAT の変換フロー。R1 の inside local (192.168.10.1) 発のパケットが R2 の inside 側 (Gi2) に入り、ルーティングで出口 (Gi3) を決めた後に送信元が inside global (203.0.113.5) に書き換えられて R3 へ届く。R3 の応答は 203.0.113.5 宛で返り、R2 が宛先を 192.168.10.1 に逆変換して内部へ戻す。inside→outside はルーティングの後に変換、outside→inside は変換の後にルーティング、という順序の非対称を示す

PAT の多重化も同様に追います。

PAT (overload) のポート多重化フロー。複数の内部ホスト (192.168.10.1・192.168.11.11) の通信が、すべて同じ inside global (10.23.0.1 = Gi3 のアドレス) に変換されつつ、送信元ポート番号 (5062・5063) で区別される。ポートを持たない ICMP は Identifier で識別する。最後に、overload なしの Dynamic NAT はアドレス数で頭打ちになり、PAT がその限界をポート多重で解くことを対比で示す

12. NAT の位置づけ — セキュリティ機能ではない

本章のここまでで扱った ACL・ZBF はトラフィックを許可・拒否するセキュリティ機能でした。NAT はそれらと同じ第 4 章に置いていますが、NAT の一次的な目的はセキュリティではなくアドレスの変換 (IPv4 の節約と接続性の確保) です。この違いを整理します。

項目ACLZBFNAT/PAT
一次目的トラフィックの許可・拒否ステートフルな境界防御アドレス変換 (枯渇対策・接続性)
状態を持つか持たない (ステートレス)持つ (セッション)持つ (変換テーブル)
「向き」の定義インターフェース + 方向 (in/out)ゾーン間 (zone-pair の向き)inside / outside の向き
セキュリティ機能か× (副次的な効果はある)

NAT には、内部のプライベートアドレスを外部から隠す アドレス隠蔽 の副次効果があります。外部からは変換後のグローバルアドレスしか見えず、内部の構成が直接は分かりません。しかしこれをセキュリティの主軸にするのは危険です。第一に、Static NAT や Static PAT で外部に穴を開けた瞬間、その隠蔽効果は消えます (§10 で 203.0.113.10:80 を公開したとおりです)。第二に、内部発の通信に便乗する戻りは通してしまい、ペイロードの中身は検査しません。したがって「NAT があるからファイアウォールは要らない」という考えは誤りです。境界の防御は ACL や ZBF の仕事であり、NAT はアドレス変換の仕事です。両者は同じ R2 の上で役割を分けて共存します。

第 4 章を通じて、4-1 ACL の in/out、4-5 ZBF の zone-pair、そして本節の inside/outside と、通信を制御する 向き の概念が繰り返し現れました。ZBF のセッションテーブルと NAT の変換テーブルは、どちらも「往きを覚えて戻りを扱う」状態機械であるという点でも共通しています。制御するもの (通信の可否か、アドレスの変換か) は違っても、向きと状態でネットワークを設計する考え方は一貫しています。

13. 次節

本節では、プライベートアドレスとグローバルアドレスを変換する NAT を扱いました。NAT なしでは内部プライベートが外部に届かないこと (§4)、Static NAT が 1 対 1 の固定変換を常設マッピングとして持つこと (§6)、Dynamic NAT がプールから 1 対 1 で動的に割り当てること (§7)、PAT が 1 つのグローバルアドレスをポート番号で多重化すること (§8)、プールを使い切ると静かに変換に失敗すること (§9)、Static PAT が外部から内部の特定サービスを公開すること (§10) を、csr1000v の show ip nat translations の出力で確認しました。とりわけ、NAT は変換後・変換前の両方のアドレスへの戻り経路が要る (§5) という点が、ステートレスなルーティングと NAT を分ける勘所です。

次節 4-7 IPsec 基礎 では、通信を暗号化して保護する IPsec を扱います。ここで NAT が伏線になります。IPsec は経路上でパケットのヘッダを守るため、NAT が経路の途中でヘッダ (アドレスやポート) を書き換えると、IPsec の検証が壊れてしまいます。この矛盾を解く NAT-T (NAT Traversal) の仕組みを含め、NAT と暗号化がどう両立するかを次節以降で見ていきます。