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)
- SNAT: 送信元を変換 (
-
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
- Linux
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
# 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+ Browsermitigation 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 インフラ縮退
- Phase 1: 内部を
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
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