Dev Study
← ネットワークの仕組み
レッスン 7 / 13·約 19 分·第2期 ネットワークの仕組み

NAT — アドレスが足りない世界の辻褄合わせ

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択今ここ
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理
  7. DB保存

第18週で「ルータが宛先を見て次の行き先を決める」ところまで見ました。今回は同じルータが、通り抜けるパケットの送信元を書き換えている、という話です。宛先を見て転送するだけではなく、アドレスそのものに手を入れている段になります。

まず結論

家庭や社内から外へ出る通信は、途中で送信元のアドレスとポート番号が書き換えられています。書き換えの対応表は、通信を始めた瞬間に作られ、使われなくなると消えます。この「勝手に生まれて勝手に消える」性質が、NATのふるまいのほとんどを説明します。

そして本レッスンの山場は、NATがセキュリティ機能ではないということです。外から入れないように見えるのは、アドレス不足の辻褄合わせから生まれた副作用であって、守る意図をもって設計された仕組みではありません。

? 読む前に予測

「自宅のルータにはNATがあるので、外部から勝手に入られることはない。だからファイアウォールは要らない」——この説明を、RFCはどう扱っているでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

足りないものを、使い回しでごまかす

第17週で見たとおり、IPv4のアドレスは32ビットしかなく、世界中の端末に1つずつ配るには足りません。

そこで採られたのが、内側では好きなアドレスを使い、外へ出るときだけ本物に付け替えるという方法です。内側で使ってよいアドレスは RFC 1918 が3範囲を定めています。

RFC 1918 が定める私的アドレスの3範囲表
範囲 表記 大きさの目安
10.0.0.0 - 10.255.255.255 10/8 class A 1個分
172.16.0.0 - 172.31.255.255 172.16/12 連続する class B 16個分
192.168.0.0 - 192.168.255.255 192.168/16 連続する class C 256個分

同じ 192.168.1.5 が世界中に何百万台とあります。それで問題が起きないのは、このアドレスが外へ出る前に必ず書き換えられるからです。

そして書き換えには2つの方式があり、RFC 3022 はこれをはっきり区別しています。

Basic NAT は変換の対象が「IPアドレスのみ(limited to IP addresses alone)」で、内側1台に外側1つを対応させます。内側に100台あれば外側にも100個要るので、アドレスの節約になりません。

NAPT は対象を「IPアドレスとトランスポート識別子」まで広げます。ポート番号も書き換えてよいことにすると、多数の端末を1つの外部アドレスに畳み込めます。 家庭用ルータやテザリングで動いているのは、正確にはこちらです。

具体実物

実際の端末で、変換される前の姿を見る

実機で確かめます。まず自分のアドレスです。

$ ipconfig getifaddr en0コマンド出力
192.168.1.5

192.168.x なので、RFC 1918 の私的アドレスです。このまま外へは出られません。 次に、変換を行っている装置を確かめます。

$ netstat -rn -f inet | grep defaultコマンド出力
default 192.168.1.1 UGScg en0

第18週で見た 0.0.0.0/0 の行です。この next hop 192.168.1.1 が、NAPTを行っている箱にあたります。経路を決める装置と、アドレスを書き換える装置が同じなのが家庭用ルータの姿です。次に、そこから今出ている通信を見ます。

$ netstat -an -p tcp | grep ESTABLISHED (実機出力から抜粋)コマンド出力
tcp4 0 0 192.168.1.5.60464 146.75.115.10.443 ESTABLISHED
tcp4 0 0 192.168.1.5.60420 160.79.104.10.443 ESTABLISHED
tcp4 0 0 192.168.1.5.60397 160.79.104.10.443 ESTABLISHED
tcp4 0 0 192.168.1.5.60294 18.97.36.46.443 ESTABLISHED
tcp4 0 0 192.168.1.5.59625 35.75.32.93.443 ESTABLISHED

注目してほしいのは2行目と3行目です。相手が同じ 160.79.104.10 の443番なのに、自分側のポートが 60420 と 60397 で違います。 同じ相手への複数の接続を区別しているのが、自分側のポート番号です。そしてこの1行の形が重要で、1つの通信は4つの値の組で決まっています。

1つの通信を識別する4つ組表
位置 値 役割
送信元IP 192.168.1.5 どの端末か
送信元ポート 60420 その端末の中のどの通信か
宛先IP 160.79.104.10 どの相手か
宛先ポート 443 相手のどのサービスか

この4つ組が、後で「収容できるセッション数」を考えるときに効いてきます。

抽象原理

変換表は、誰も作っていないのに存在する

ここがNATのいちばん大事な性質です。

NAPTの変換表は、あらかじめ用意されているものではありません。 管理者が登録するのでも、起動時に作られるのでもなく、内側の端末が通信を始めた瞬間に、その通信のぶんだけ1行が作られます。 そして通信が終わるか、しばらく使われないでいると、その行は消えます。

このように、出来事をきっかけに自動的に生まれ、使われなくなると勝手に消えていく状態をソフトステートと呼びます。

変換表の1行が生まれてから消えるまで
内側の端末が外へ通信を始める192.168.1.5:60420 → 160.79.104.10:443
この瞬間に行が作られる
変換表に1行追加内側の(IP,ポート) ↔ 外側の(IP,ポート)
戻りのパケットは、この行を逆引きして内側へ戻される
通信が続く間、行は維持される
通信が終わる / 一定時間使われない
行が消える以後この対応は存在しない
  • ・行を作るきっかけは、必ず内側から外への通信
  • ・外から先に来たパケットには、逆引きすべき行がまだ存在しない

この図から、2つの重要な帰結がそのまま出てきます。

1つ目。外から先に繋ぐことができません。 外から届いたパケットを内側の誰に渡すかは、行を逆引きして初めて分かります。行は内側からの通信でしか作られないので、外から先に来たパケットには渡す先を決める手がかりがありません。 ポートフォワーディングという設定が要るのは、この「最初から存在する行」を人手で1本用意する作業にほかなりません。

2つ目。行は有限の資源を消費します。 外側のポート番号には限りがあるので、行が増え続ければいつか作れなくなります。とくに事業者側でまとめて変換するCGNでは、多数の加入者が同じ外部アドレスを分け合うため現実の問題になります。RFC 6888 は、加入者あたりの外部ポート数に上限を設けて設定可能にすること(REQ-4)、マッピングを作れないときは破棄してICMPで通知すべきこと(REQ-11)を挙げています。利用者からは「なぜか繋がらない」として現れます。

✓ ここまでの確認

NAPTの変換表の行は、いつ作られますか。

⇄ 2つを見比べる
具体例 A

NAPTの変換表

内側の端末が外へ通信を始めると、その通信のぶんだけ1行が作られます。戻ってきたパケットはこの行を逆引きして内側へ配られます。通信が終われば行は消えます。外から先に届いたパケットには、逆引きすべき行がまだ存在しません。

ある瞬間の変換表(概念)表
内側 外側 状態
192.168.1.5:60420 ↔ 203.0.113.9:51001 通信中
192.168.1.5:60397 ↔ 203.0.113.9:51002 通信中
192.168.1.7:52310 ↔ 203.0.113.9:51003 通信中
(外から来たパケット) 該当する行なし 渡す先が決まらない
具体例 B

会社の代表電話と内線の取次ぎ表

外の世界からは代表番号1つしか見えません。社員が外線をつかんで電話をかけると、交換台は「今どの内線が、どの外線を使っているか」を控えます。通話が終われば、その控えは消えます。外部の人が内線番号を直接呼ぶことはできず、必ず代表番号にかけて取り次いでもらう必要があります。

交換台が持っている、その時点の取次ぎ表表
内線 外線 状態
内線 4102 ↔ 代表番号 回線1 通話中
内線 4102 ↔ 代表番号 回線2 通話中(2本目)
内線 4310 ↔ 代表番号 回線3 通話中
(外部からの着信) 該当する控えなし 誰に回すか決まらない

NAPTの変換表と、会社の交換台の取次ぎ表。この2つに共通している構造は何でしょうか。とくに「表がいつ作られるか」と「外から内側を名指しできるか」に注目してください。

交換台の取次ぎ表は、朝礼で全社員ぶんを書き出しておくものでしょうか。それとも、電話がかかった瞬間に書かれるものでしょうか。

抽象原理

ここが山場 — NATはセキュリティ機能ではない

前の比較の最後の一文が、本レッスンの核心です。交換台はセキュリティ装置ではありません。 同じことがNATにも言えます。この点について、RFCははっきりした書き方をしています。

RFCが実際に述べていること表
文書 述べていること
RFC 2993 §9 NAT(とくにNAPT)は「安全の壁があるという錯覚」を作り出すため、
全体の安全性をむしろ下げうる
RFC 4787 マッピングの方式をどう選んでも「安全性の性質には何の違いも生まない」。
安全性は「どのパケットを通し、どれを通さないか」で完全に決まる

RFC 4787 の言い方が決定的です。安全性を決めているのは、どのパケットを通しどれを通さないかという「フィルタリングの方針」であって、アドレスを書き換える操作そのものではありません。

では、なぜこれほど広く誤解されるのでしょうか。 誤解する側を雑に否定せず、正確に扱う必要があります。

片方向性が生じること自体は事実です。 RFC 3022 §6.1 は、従来型NATが「プライバシーの仕組み(privacy mechanism)」を提供していると見なせる、と正直に認めています。セッションが内側から外向きにしか始まらないためで、先ほど図で見たとおり外から先に来たパケットには渡す先がありません。「結果として外から入れない」は正しい観察です。

問題は、それが何のために生まれた性質なのかです。

「NATがあるからファイアウォールは不要」という結論が危ういのは、まさにここです。守るという約束をしていないものに、守る役割を期待していることになります。RFC 2993 が「錯覚」という強い語を使い、安全性をむしろ下げうるとまで述べるのは、この期待のずれが問題だからです。

✓ ここまでの確認

「NATがアドレスを変換していること自体が、外部からの攻撃を防いでいる」という説明は妥当ですか。

具体実物

NATが壊すもの — 第14週の伏線が回収される

第14週で「層は完全に独立ではない」と述べ、TCPのチェックサムの計算範囲にIPの疑似ヘッダ(送信元・宛先IPアドレス)が含まれるという RFC 9293 §3.1 の規定を挙げました。そのとき「第20週でNATを扱うとき、この結合がそのまま効いてきます」と予告しました。ここで回収します。

もし層が完全に独立なら、IP層の値を書き換えてもTCP層は何も知らずに済むはずです。ところが実際には——

NATがアドレスを書き換えたとき、何が起きるか
IPヘッダを書き換え送信元IPを私的アドレスからグローバルへ○ IP層としてはこれで完了
TCPのチェックサム計算範囲に送信元IPが含まれている× 辻褄が合わなくなる
再計算が必要NATがTCPヘッダにも手を入れる○ 上の層まで踏み込まざるを得ない
↓
アドレスだけ書き換えて済ませることができない。層をまたぐ結合が規格に組み込まれているため
  • ・NAPTはさらにポート番号も書き換えるので、いずれにせよTCPヘッダに触れる
  • ・「上の層は下の層を知らなくてよい」が成り立たない実例

つまりNATは、本来そこに手を出さないはずの層にまで踏み込まないと成立しません。 「層は影響範囲を局所化する仕組みであって、完全に独立ではない」ことの、いちばん分かりやすい帰結です。

この踏み込みは、端から端までが素通しであるという前提(エンドツーエンド性)を崩します。途中でヘッダが書き換えられることを想定していない仕組みは、NATの下でうまく動きません。

具体実物

二重に変換されるとどうなるか

アドレス不足が進むと、家庭で1回変換したものを事業者側でもう一度変換する構成が出てきます。これがCGNです。素朴には事業者側も RFC 1918 を使えばよさそうですが、それができません。

私的アドレスを再利用できない理由
家庭内192.168.1.5
1回目の変換(家庭用ルータ)
宅内ルータの外側ここに何を割り当てるか
2回目の変換(事業者のCGN)
グローバルアドレスようやく本物
  • ・もし中段にも 192.168.x を使うと、宅内と同じ範囲が装置の両側に現れて衝突しうる
  • ・そこで RFC 6598 が 100.64.0.0/10 を別途確保した

RFC 6598 が 100.64.0.0/10 を Shared Address Space として確保したのは、この衝突を避けるためです。既存の私的アドレスを流用すると、同じ範囲が装置の内側と外側の両方に現れうるためです。

この章のまとめ

  • Basic NAT と NAPT は別物。 Basic NAT の変換は「IPアドレスのみ」で1対1なので節約にならない。ポート番号まで含める NAPT が多数を1つに畳み込む。家庭用ルータやテザリングで動いているのは NAPT。
  • ポート番号は16ビットで 0-65535 の 65,536個(RFC 6335)。
  • 変換表はソフトステート。 内側からの通信で行が生まれ、使われなくなると消える。外から先に繋げないのも、ポートフォワーディングが要るのも、枯渇が起きるのも、すべてこの性質からの帰結。
  • セッション数の上限に具体的な数値を書かない。 RFC 3022・RFC 6888 ともに規定していない。鍵は4つ組で、収容数は実装方式に依存する。
  • ★NATはセキュリティ機能ではない。 RFC 4787 は、安全性が「どのパケットを通し、どれを通さないか」で完全に決まると述べる。決めているのはフィルタリングの方針であって、アドレス変換そのものではない。
  • 片方向性が生じること自体は事実(RFC 3022 §6.1 は privacy mechanism と認める)。しかし設計目標ではなく副作用。ファイアウォールの「明示的な意図」に対し、NATは「透過的」なものとして提示される——この差が決定的。RFC 2993 は「安全の壁があるという錯覚」を生むとまで述べる。
  • NATはIPアドレスを書き換えるため、TCPのチェックサムの再計算が要る(第14週の疑似ヘッダの結合)。層は完全に独立ではないことの実例。
  • 100.64.0.0/10 は RFC 1918 の4つめではない。 RFC 6598 が CGN 向けに確保した Shared Address Space。
  • RFC 3022 は Informational であって Standards Track ではない。NATが設計された解決策ではなく、現実への対処として広まったことを表している。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

環境:

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 4正解: 0

家庭用ルータやスマートフォンのテザリングで動いている変換の、正確な名前はどれですか。

用語集(7語)
NAT (Network Address Translation)
通り抜けるパケットのIPアドレスを書き換える仕組み。RFC 3022 が記述している。ただし同文書は Informational で、守るべき標準(Standards Track)ではない。
Basic NAT
変換の対象がIPアドレスだけに限られる方式。RFC 3022 は「limited to IP addresses alone」と述べている。内と外が1対1で対応するため、アドレスの節約にはならない。
NAPT
変換の対象をIPアドレスとトランスポート識別子(TCP/UDPのポート番号、ICMPのクエリID)まで広げた方式。多数の内側の端末を1つの外部アドレスに多重化できる。家庭用ルータやテザリングで動いているのはこちら。
4つ組 (4-tuple)
1つの通信を識別する組。送信元IP・送信元ポート・宛先IP・宛先ポートの4つからなる。セッションの鍵がこの4つであることが、NAPTの収容数を「ポート数」だけでは語れない理由になる。
ソフトステート
誰かが明示的に作ったのではなく、通信が始まったことをきっかけに自動的に生まれ、使われなくなると時間経過で消える状態のこと。NAPTの変換表の行がこれにあたる。
Shared Address Space (100.64.0.0/10)
RFC 6598 が CGN 向けに確保した範囲。RFC 1918 の私的アドレスとは別物で、サービスプロバイダの境界を越えて転送してはならないと規定されている。
CGN (Carrier-Grade NAT)
事業者側でさらにまとめて変換を行う構成。RFC 6888 が要件を定めており、加入者あたりの外部ポート数に上限を設けられること、マッピングを作れないときはパケットを破棄してICMPで通知すべきこと、PCPをサポートすべきことなどが挙げられている。