NAT(Network Address Translation)
プライベートアドレスとグローバルアドレスを変換する仕組み。IPv4 を延命する救世主であり、 End-to-End 通信を壊す元凶でもある。種類、ホールパンチング、CGN、IPv6 との関係まで。
NAT が必要になった理由
- IPv4 アドレスは 約 43 億個。1990 年代から「足りなくなる」と言われていた
- 家庭内に 5 台あったら 5 個のグローバル IP が必要 → 現実的でない
- 1 つのグローバル IP を家庭内全員で共有する仕組みが NAT
NAT の種類
静的 NAT (Static NAT)
プライベート IP ↔ グローバル IP を1:1 で固定マッピング。
内部 192.168.1.10 ⇔ 外部 203.0.113.10
内部 192.168.1.11 ⇔ 外部 203.0.113.11
- 外部から直接到達可能
- サーバ公開で使う
- IP アドレスを節約しない
動的 NAT (Dynamic NAT)
グローバル IP のプールから都度割り当て。1:1 だが時間で変わる。
NAPT / PAT(Port Address Translation)
家庭用ルータが行うのはこれ。
IP + ポート番号で多対 1 のマッピング。
内部 192.168.1.10:50000 ⇔ 外部 203.0.113.10:60001
内部 192.168.1.11:50000 ⇔ 外部 203.0.113.10:60002
内部 192.168.1.10:50001 ⇔ 外部 203.0.113.10:60003
→ 1 つのグローバル IP を 数千〜数万 のセッションで共有可能
NAT テーブル
NAT 機器はセッションごとに変換ルールを覚える。
内部 IP 内部 Port 外部 IP 外部 Port 宛先 IP 宛先 Port プロトコル
192.168.1.10 52341 203.0.113.10 60001 93.184.216.34 443 TCP
192.168.1.11 53000 203.0.113.10 60002 8.8.8.8 53 UDP
- TCP はセッション終了 (FIN/RST)で削除
- UDP はタイマー(数十秒〜数分)で削除
- 容量が有限なので、長期接続が多いとあふれる
NAT の動作(送信側)
- 内部 PC が
192.168.1.10:52341 → 93.184.216.34:443でパケットを送出 - NAT 機器が受け取り、空きポート(例: 60001)を割り当てる
- IP ヘッダの送信元を
203.0.113.10:60001に書き換え - チェックサムを再計算
- NAT テーブルに登録
- 外側へ送出
NAT の動作(受信側)
- 外部からパケット
93.184.216.34:443 → 203.0.113.10:60001が到着 - NAT 機器が NAT テーブルを引き、宛先を
192.168.1.10:52341に書き換え - 内部へ転送
NAT の挙動分類(RFC 3489)
STUN(後述)の世界では NAT を 4 種類に分類する。外側のフィルタリング規則の違い。
| 種類 | 規則 | P2P |
|---|---|---|
| Full Cone | 同じ内部 IP:Port から外向きにマッピングされたら、外部の誰からでも戻ってこられる | 易 |
| Restricted Cone | 同じ宛先 IP からの戻りだけ受け付ける(ポート問わず) | 中 |
| Port-Restricted Cone | 同じ宛先 IP + Port からの戻りだけ受け付ける | 難 |
| Symmetric | 宛先ごとに外部ポートが変わる。最も厳しい | 非常に難 |
Symmetric NAT 同士の P2P は事実上不可能に近く、TURN リレーが必要。
ホールパンチング
NAT 越しの P2P を成立させる技。両側が同時に外向きにパケットを出すことで、 互いの NAT に「戻り口」を作る。
A (内部 NAT) シグナリング B (内部 NAT)
| 外向き SYN ─────────────────→ |
| |
| ←───── 外向き SYN |
| |
← ─ ─ 双方向に通せる ─ ─ →
STUN
Session Traversal Utilities for NAT。サーバが「あなたの外側 IP:Port は X です」と教えてくれる。 WebRTC や VoIP で必須。
TURN
Traversal Using Relays around NAT。STUN で繋げないとき中継サーバが代わりに通す。 帯域コストが高い。
ICE
Interactive Connectivity Establishment。STUN / TURN を組み合わせて最善の経路を選ぶ手順。 WebRTC のコネクション確立に使われる。詳細は WebRTC。
UPnP / NAT-PMP / PCP
アプリがNAT 機器に「このポートを開けて」と頼むプロトコル群。
- UPnP IGD: 古典。家庭用ルータで対応多い
- NAT-PMP: Apple 由来、シンプル
- PCP: NAT-PMP の後継、IPv6 対応(RFC 6887)
ゲーム機やオンラインアプリが「ポート開放」と言って自動でこれを使う。セキュリティ上は無効化推奨される現場もある。
ポートフォワーディング(DNAT / Port Mapping)
外部からのアクセスを内部の特定ホスト・ポートに振り向ける設定。
外部 203.0.113.10:80 → 内部 192.168.1.10:8080
外部 203.0.113.10:22 → 内部 192.168.1.20:22
- 家庭内サーバ公開、SSH
- iptables / nftables / ufw / ルータ GUI で設定
- Linux で実装するなら DNAT + MASQUERADE の組合せ
ヘアピン NAT(NAT Loopback)
内部から外部の自グローバル IP に対してアクセスしたとき、NAT が折り返して内部サーバへ届ける機能。 非対応のルータでは「外からは繋がるが家からは繋がらない」が起きる。
CGN / CGNAT(Carrier-Grade NAT)
ISP がもう一段 NAT をかける。 加入者は元々プライベート IP(100.64.0.0/10)が振られ、ISP の中で集約してグローバル IP に変換。
- IPv4 アドレスを節約
- 家庭ルータ + ISP CGN で2 重 NAT
- P2P / オンラインゲーム / VoIP で問題
- 逮捕事例で「同じ外部 IP に大量の人」がいて誤認逮捕の話題に
NAT の問題点
- End-to-End 通信が壊れる — インターネットの理念に反する
- P2P / IPSec / FTP(パッシブモード必要)/ SIP との相性が悪い
- ALG(Application Layer Gateway)が必要なプロトコルがある
- ログが「外部 IP + Port + 時刻」で内部を逆引きする必要
- セッション数の上限
- UDP の保持タイマーが切れて接続が消える(VoIP / WebRTC で keepalive 必須)
NAT はセキュリティ機能ではない
- 「NAT のおかげで安全」は誤解
- 確かに外から内へ直接到達できない副作用はあるが、FW を別途用意すべき
- IPv6 で NAT が無くなっても、ステートフル FW で同等のフィルタは可能
IPv6 と NAT
- IPv6 は本来 NAT 不要(アドレスが余っている)
- ただしNAT66 / NPTv6 という方式もある(プレフィックス変換のみ)
- マルチホーム環境などで使われる
- NAT64 は IPv6 ↔ IPv4 の橋渡し(→ IPv6)
Linux で NAT を実装する
iptables(古典)
# MASQUERADE(家庭ルータ的な NAPT)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# DNAT(ポートフォワード)
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \
-j DNAT --to-destination 192.168.1.10:8080
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 8080 -j ACCEPT
nftables(現代)
nft add table nat
nft add chain nat post '{ type nat hook postrouting priority 100; }'
nft add rule nat post oifname "eth0" masquerade
nft add chain nat pre '{ type nat hook prerouting priority -100; }'
nft add rule nat pre iifname "eth0" tcp dport 80 dnat to 192.168.1.10:8080
conntrack を見る
# 現在のコネクション一覧
sudo conntrack -L
# 統計
sudo conntrack -S
# 特定セッションを削除
sudo conntrack -D --orig-src 192.168.1.10
ヘアピン NAT の設定例(nftables)
# 内部からも外部 IP で公開ポートに繋がるように
nft add rule nat pre iifname "br-lan" ip daddr 203.0.113.10 \
tcp dport 80 dnat to 192.168.1.10:8080
# SNAT が必要(戻りパケットを通すため)
nft add rule nat post ip saddr 192.168.1.0/24 ip daddr 192.168.1.10 \
tcp dport 8080 snat to 192.168.1.1
Docker / Kubernetes での NAT
- Docker は内部でiptables の DNAT / MASQUERADEを使う
- コンテナ → 外向きは MASQUERADE
- 外 → コンテナは DNAT (-p 80:8080)
- Kubernetes の Service ClusterIP / NodePort も内部的に NAT
「Open NAT」「Type 2/3」と呼ばれるもの
ゲーム機(PS / Xbox / Switch)が表示する NAT 種別:
- Type 1 / Open: 直接インターネット(NAT なし)
- Type 2 / Moderate: Cone NAT(多くの場合大丈夫)
- Type 3 / Strict: Symmetric NAT(マッチングしにくい)
UPnP を有効化、ポート開放、DMZ などで対処する。
確認コマンド
# 自分のグローバル IP(外側から見た)
curl ifconfig.me
curl ipinfo.io/ip
dig +short myip.opendns.com @resolver1.opendns.com
# Linux: NAT テーブル
sudo iptables -t nat -L -n -v
sudo nft list ruleset
# conntrack
sudo conntrack -L
# STUN テスト
stunclient stun.l.google.com 19302
よくあるトラブル
| 症状 | 原因 |
|---|---|
| 外からは繋がるが家から繋がらない | ヘアピン NAT 非対応 |
| 長時間接続が突然切れる | NAT の UDP タイマー切れ。keepalive を増やす |
| VoIP の音が途切れる | NAT / FW が SIP/RTP を理解しない。ALG / SBC で対処 |
| IPSec が通らない | NAT-T (UDP 4500) が必要 |
| P2P ゲームでマッチングできない | Symmetric NAT。UPnP 有効化 / ポート開放 |
| conntrack table full | セッション数上限。nf_conntrack_max を増やす |
IPv4 を延命するために発明されたが、本来あるべきEnd-to-End 通信を壊している。 IPv6 への移行が完了すれば NAT は基本不要。それまでは付き合うしかない。