#0175（2025/06/20）NAPT徹底解説

# NAPT徹底解説 ― IPv4枯渇時代を支えるポートアドレス変換の実践ノウハウ

## 1. はじめに

* **対象読者**: ネットワークエンジニア／SRE／クラウド・通信キャリアのインフラ担当
* **前提知識**: L3 ルーティング, TCP/UDP ヘッダ, 状態型ファイアウォール, Linux Netfilter
* **ゴール**: この記事を読み終えると、以下を行えることを目指す

  * CGNAT 規模の NAPT キャパシティ計算とハードウェア選定
  * P2P / VoIP アプリ実装時の NAT トラバーサル設計
  * フロー監視・トラブルシューティングのベストプラクティス把握

---

## 2. NAT / NAPT 基礎整理

* **NAT (Network Address Translation)**

  * IP アドレスのみ書き換える。多段 NAT では衝突を起こしやすい
* **NAPT / PAT (Port Address Translation)**

  * IP + Port を変換し 1 グローバル IP に 6 万超のフローを多重化
  * *NAPT* を実装しない NAT は実務では極少数（VPN, IPv6 NPT など特例）
* **SNAT / DNAT terminologies** (Netfilter)

  * SNAT: 送信元を変換 (`POSTROUTING`)
  * DNAT: 宛先を変換 (`PREROUTING`)
* **CGNAT, LSN (Large‑Scale NAT)**

  * キャリア網で 10^7 フロー規模を捌く NAPT クラスタ

---

## 3. NAPT 内部動作詳細

### 3.1 フローテーブル構造

* **キー**: `(src_ip, src_port, dst_ip, dst_port, proto)`
* **値**: NAT 変換後 5‑tuple + 状態 (`SYN_SENT`, `ESTABLISHED` …) + タイムスタンプ
* **実装例**

  * Linux `conntrack` ハッシュテーブル (Jenkins Hash)
  * ASIC/NPU: TCAM + SRAM の二層構造で LPM / exact match

### 3.2 ポート割当アルゴリズム

* **Sequential**: 単純インクリメント → CPU 負荷小, 予測容易
* **Randomized (RFC 6056)**: セキュリティ重視, CPU コスト増
* **Hash‑based bucket**: `(internal_ip XOR epoc_time) mod port_pool`

### 3.3 タイムアウト & リソース管理

* `tcp_fin_timeout = 120s`, `tcp_established_timeout = 7440s(2h4m)` が Linux 既定
* フローキャッシュの RAM 使用量 = `entry_size × max_flows`

  * 例: `entry_size 256B × 4M flows ≈ 1GB`
* **L4S/LB**: RST/FIN の未到達でゾンビフロー残留 → Idle sweep タスクが必要

---

## 4. アプリケーションとの相互作用

### 4.1 ALG (Application‑Layer Gateway)

* SIP ALG が `Via:` ヘッダを書き換える具体例
* FTP Active Mode (PORT command) 対応で DNAT を自動生成
* **リスク**: ALG 不具合でパケット破壊 → 監視項目に *ALG hit/miss* を追加

### 4.2 NAT トラバーサル技法

* **STUN**: 外部アドレス自己発見
* **TURN**: リレー経由通信 (帯域コスト大)
* **ICE**: STUN + TURN + 優先度算出で最適経路選択
* **DTLS/TLS encapsulation**: UDP/TCP 443 を通しやすい現代的 P2P

---

## 5. キャリアグレード NAPT 設計指針

### 5.1 IP & ポートプール計算

* ユーザ 1 人あたり平均同時 TCP セッション: 50 (動画 + SNS + Ads)
* ピーク係数 3×, 安全率 1.2×

  * `ports_needed = 50 × 3 × 1.2 ≈ 180`
* **1/512 メソッド**: `/24` を 512 ユーザで共有 → 128 ポート/ユーザ

  * モバイル向け大手キャリア実績例

### 5.2 スケールアウトアーキテクチャ

* **ECMP + Anycast VIP** で複数 CGN ノードへフロー分散
* **ステート同期 (stateful HA)**

  * 同期頻度 = 10 ms 未満 推奨
  * グレースフルローリングアップグレードに必須
* **BGP FlowSpec** で DDoS トラフィックを事前遮断しテーブル枯渇を防御

---

## 6. Linux / ネットワーク機器実践設定

### 6.1 Linux nftables

```bash
# SNAT (NAPT) 例
nft add table ip nat
eval $(ip -4 -o addr show eth0 | awk '{print "SNAT_IP=" $4} ')  # 203.0.113.25/32
nft add chain ip nat postrouting { type nat hook postrouting priority 100; }
nft add rule ip nat postrouting oifname "eth0" ip saddr 192.168.0.0/24 snat to $SNAT_IP
```

### 6.2 Cisco IOS (PAT)

```
interface Gig0/0
 ip address 203.0.113.25 255.255.255.248
 ip nat outside
!
interface Gig0/1
 ip address 192.168.0.1 255.255.255.0
 ip nat inside
!
ip nat inside source list 100 interface Gig0/0 overload
access-list 100 permit ip 192.168.0.0 0.0.0.255 any
```

### 6.3 Juniper SRX CGNAT

`set security nat source pool CGN_POOL address 203.0.113.25/32 port 20000 to 65000`

---

## 7. ポート枯渇シミュレーション（Poisson モデル）

* **想定**: 1 ユーザあたり λ=0.8 セッション/秒, 平均セッション長 μ=20 秒
* **ポート使用分布**: `E[ports] = λ × μ = 16`
* **ポートプール 128/ユーザ** → 枯渇確率 `P(X>127) < 10^-9` (Chernoff bound)
* Python シミュレーションスクリプト例を appendix に掲載

---

## 8. 可観測性 & ログスキーマ

* **IPFIX with NAT Events (RFC 4789)**

  * `natEvent 1 create`, `2 delete`, `3 poolExhaustion`
* **最低限残すべき項目**

  * `originalIPv4Address`, `originalPort`, `translatedIPv4Address`, `translatedPort`, `protocolIdentifier`, `flowStartMilliseconds`, `flowEndMilliseconds`
* **GDPR / 通信ログ保持法対応**

  * ローテーション + 暗号化格納

---

## 9. トラブルシューティングパターン集

* **症状: 外部 Web アプリのみ接続不可** → ALG が TLS Inspection と競合
* **症状: VoIP 音声片方向** → Symmetric NAT + 欠落 RTP ポートフォワード
* **症状: セッション切断多発** → CGN ノード間 ECMP でステート非同期
* **調査コマンド**

  * `conntrack -E -p tcp --dport 443` でリアルタイム追跡
  * Cisco `show ip nat translations | include <inside_ip>`

---

## 10. セキュリティ考慮

* **NAT Slipstreaming v2**

  * 防御: `MSS Clamping` + `ALG SIP disabled` + Browser `mitigation flag`
* **Port Randomization** による Blind Spoofing 防御
* **UPnP/WANIPConnection**

  * 家庭用では LAN 側に権限委譲するが、企業環境では必ず disable

---

## 11. IPv6 とのハイブリッド運用

* **IPv6 Native + NAT64 (464XLAT)**: モバイルキャリア主流構成
* **NPTv6 (RFC 6296)**

  * グローバル⇔ULA プレフィクス変換、ステートレスゆえ高スケール
* **移行戦略**

  * Phase 1: 内部を `dual-stack`, 外部は CGN で IPv4
  * Phase 2: コンテンツの 95% が IPv6 到達時に NAT インフラ縮退

---

## 12. ベストプラクティスチェックリスト

* [ ] **キャパシティ設計**: ユーザ毎ポートプール基準値を数学的に算出しレビュー
* [ ] **モニタリング**: conntrack 使用率 70% でアラート, >90% で自動トラフィックシェッド
* [ ] **ステート同期**: versioned 標準 API または Vendor RPC で自動テスト
* [ ] **ALG 管理**: 必要プロトコルのみに限定しバージョン互換を検証
* [ ] **P2P 設計**: ICE fallback を実装し Symmetric NAT でも通信を確保
* [ ] **IPv6 ロードマップ**: 3 年以内に CGN 終端率 50% 以下を目標

---

## 13. まとめ

* **NAPT = IPv4 時代の生命線**。しかしキャリア・クラウドレベルではフロー状態爆発との戦い
* **高性能ハードウェア + ステート同期 + 可観測性** が実運用の三本柱
* **IPv6 ネイティブ化を進めつつ NAPT 依存を段階的に縮小**
* 本稿のチェックリスト・コマンド例を活かして自組織の NAT 基盤をいますぐ棚卸ししてみよう

---

### Appendix: Poisson シミュレーション Python Snippet

```python
import numpy as np
from scipy.stats import poisson
lam = 0.8*20  # E[ports]
threshold = 128
prob_exhaust = 1 - poisson.cdf(threshold-1, lam)
print(f"Port exhaustion probability: {prob_exhaust:.2e}")
```

### Appendix: 参考 RFC・資料

* RFC 4787 (NAT Behavioral Requirements for Unicast UDP)
* RFC 6888 (Analysis of Stateful NAT64)
* RFC 7753 (Port Control Protocol NatTimeOut Option)
* Juniper Networks CGNAT Best Practices
* Cisco ASR1000/CGN Design Guide