NAT(Network Address Translation)

プライベートアドレスとグローバルアドレスを変換する仕組み。IPv4 を延命する救世主であり、 End-to-End 通信を壊す元凶でもある。種類、ホールパンチング、CGN、IPv6 との関係まで。

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
      

動的 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
      

NAT の動作(送信側)

  1. 内部 PC が 192.168.1.10:52341 → 93.184.216.34:443 でパケットを送出
  2. NAT 機器が受け取り、空きポート(例: 60001)を割り当てる
  3. IP ヘッダの送信元を 203.0.113.10:60001 に書き換え
  4. チェックサムを再計算
  5. NAT テーブルに登録
  6. 外側へ送出

NAT の動作(受信側)

  1. 外部からパケット 93.184.216.34:443 → 203.0.113.10:60001 が到着
  2. NAT 機器が NAT テーブルを引き、宛先を 192.168.1.10:52341 に書き換え
  3. 内部へ転送

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 機器に「このポートを開けて」と頼むプロトコル群。

ゲーム機やオンラインアプリが「ポート開放」と言って自動でこれを使う。セキュリティ上は無効化推奨される現場もある。

ポートフォワーディング(DNAT / Port Mapping)

外部からのアクセスを内部の特定ホスト・ポートに振り向ける設定。

外部 203.0.113.10:80   →   内部 192.168.1.10:8080
外部 203.0.113.10:22   →   内部 192.168.1.20:22
      

ヘアピン NAT(NAT Loopback)

内部から外部の自グローバル IP に対してアクセスしたとき、NAT が折り返して内部サーバへ届ける機能。 非対応のルータでは「外からは繋がるが家からは繋がらない」が起きる。

CGN / CGNAT(Carrier-Grade NAT)

ISP がもう一段 NAT をかける。 加入者は元々プライベート IP(100.64.0.0/10)が振られ、ISP の中で集約してグローバル IP に変換。

NAT の問題点

NAT はセキュリティ機能ではない

IPv6 と NAT

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

「Open NAT」「Type 2/3」と呼ばれるもの

ゲーム機(PS / Xbox / Switch)が表示する 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 を増やす
NAT は必要悪

IPv4 を延命するために発明されたが、本来あるべきEnd-to-End 通信を壊している。 IPv6 への移行が完了すれば NAT は基本不要。それまでは付き合うしかない。