主题
到底该选哪个
三章的实测结果汇总成一张决策表,外加几个 EI 侧还没提过的选项, 以及一个会让 VPP 崩溃的坑。
先看硬约束
有些需求只有一个插件能满足。碰到这些,没得选:
text
只能用 nat44-ei 只能用 nat44-ed
──────────────────────────────── ──────────────────────────────
· 切换时已建立连接不能断 · twice-NAT(源和目的一起改)
→ 只有 EI 有会话高可用
(配合 VRRP 实测可做到 0 丢失) → 非对称路由场景必需
· 必须支持 P2P 打洞 · 负载均衡静态映射
→ VoIP、视频会议、游戏联机 → 一个公网端口分流多后端
· 要限制单个用户的会话数 · VRF 多租户表
→ 只有 EI 有 user-sessions → 地址重叠的多租户
· 要限定外部端口范围 · 需要更强的入向安全性
→ 只有 EI 有 port-range 算法 → 外部主机换端口进不来这两列各自都是对方完全没有的能力,不是"做得好一点"的差别。
没有硬约束时的权衡
text
┌────────────────┬──────────────────────┬──────────────────────┐
│ │ nat44-ed │ nat44-ei │
├────────────────┼──────────────────────┼──────────────────────┤
│ 端口利用率 │ 高 │ 低 │
│ │ 同一端口可对多个目的复用 │ 一端口占用即对所有目的占用│
├────────────────┼──────────────────────┼──────────────────────┤
│ 入向安全性 │ 强 │ 弱 │
│ │ 五元组全对上才放行 │ 地址对上就放行 │
├────────────────┼──────────────────────┼──────────────────────┤
│ P2P 体验 │ 差,需走中继 │ 好,可打洞 │
├────────────────┼──────────────────────┼──────────────────────┤
│ 可观测性 │ 弱 │ 强 │
│ │ 看不到每地址端口占用 │ 有 busy ports 统计 │
├────────────────┼──────────────────────┼──────────────────────┤
│ 功能丰富度 │ 高 │ 低 │
├────────────────┼──────────────────────┼──────────────────────┤
│ 会话表结构 │ 平铺,含完整改写规则 │ 按用户聚合 │
└────────────────┴──────────────────────┴──────────────────────┘一句话概括这个权衡:ED 更省资源更安全,EI 对用户体验更友好、更可控。
按场景选
几个典型场景的答案:
| 场景 | 选择 | 理由 |
|---|---|---|
| 家用 / 小型办公网关 | EI | 用户会用视频通话和游戏,P2P 体验优先 |
| 企业出口,有服务对外发布 | ED | 要端口转发、可能要 twice-NAT,安全性优先 |
| 运营商 CGN | ED 或 DET44 | 端口利用率是第一位的;可追溯性见第 4 章 |
| 多租户托管 | ED | 需要 VRF 隔离重叠地址 |
| 需要双机热备的关键出口 | EI | 会话 HA 是硬约束 |
| 不确定 | ED | VPP 的默认主力实现,功能最全,社区用得最多 |
EI 侧还没提过的几个选项
mss-clamping
TCP 建连时双方协商 MSS。如果路径上有隧道(VPN、GRE、PPPoE)导致实际 MTU 变小, 而两端协商出的 MSS 又太大,就会出现"小包能通、大包不通"的经典故障。 mss-clamping 让 NAT 设备在转发 SYN 时把 MSS 改小。
bash
vppctl nat44 ei mss-clamping 1400
vppctl show nat44 ei mss-clampingtext
mss-clamping 1400ED 侧和 EI 侧是两个独立的设置
VPP 有两条 mss-clamping 命令,作用于不同的插件:
bash
vppctl nat mss-clamping 1400 # 作用于 nat44-ed
vppctl nat44 ei mss-clamping 1400 # 作用于 nat44-ei它们互不影响,而且各自都有 show:
bash
vppctl show nat mss-clamping # ED 侧
vppctl show nat44 ei mss-clamping # EI 侧配 ED 侧却去查 EI 侧的状态,会看到 disabled 而误以为没生效。
还有一个和 NAT 无关的接口级 MSS clamping
bash
vppctl set interface tcp-mss-clamp <接口> ip4 rx ip4-mss 1400 ip6 disable ip6-mss 0
vppctl show interface tcp-mss-clamp这个不依赖任何 NAT 插件,直接挂在接口上,必须指定方向(rx / tx)。 它在隧道场景里是标准做法 —— 第 10 章有完整实测, 能在 trace 里看到 SYN 的 MSS 从 1460 被改成 1400。
forwarding
和 ED 的 nat44 forwarding 语义一样:让匹配不到转换规则的流量不经翻译直接转发。
bash
vppctl nat44 ei forwarding enable用法和注意事项见第 2 章那一节 —— 最重要的一条是:外网侧必须真的有回内网的路由,否则打开了也没用。
static-mapping-only:别用,会让 VPP 崩溃
VPP 26.06 上这个选项会导致 SIGSEGV
nat44 ei plugin enable 有个 static-mapping-only 选项, 意思是"只做静态映射,不建动态会话"。
实测在 VPP 26.06 上,它会让 VPP 段错误崩溃,而且稳定复现:
bash
vppctl nat44 ei plugin enable static-mapping-only
vppctl set interface nat44 ei in host-eth1 out host-eth2
# 此时任何一个从外网侧进来的包都会打崩 VPP容器日志里的崩溃栈:
text
received signal SIGSEGV, PC 0x..., faulting address 0x...
#0 clib_bihash_search_8_8 + 0x3f
from /lib/x86_64-linux-gnu/libvnet.so.26.06
#1 nat44_ei_out2in_node_fn_x86_64_v4 + 0x4a9f8
from /usr/lib/x86_64-linux-gnu/vpp_plugins/nat44_ei_plugin.so
#2 vlib_main + 0x22b9
/usr/local/bin/netlab-start.sh: line 100: 69 Aborted (core dumped) /usr/bin/vpp ...崩在 EI 的 out2in 处理节点里查哈希表的地方 —— 看起来是 static-mapping-only 模式下某张表没有被初始化,out2in 路径却照样去查它。
结论:在 26.06 上不要用这个选项。 想达到"只允许静态映射"的效果, 更安全的做法是正常启用插件,只是不配任何动态地址池 —— 没有池,动态会话自然建不起来(会记 out of ports), 而且不会崩。
顺带一提:帮助文本里有个拼写错误
text
nat44 ei plugin <enable ... [static-mappig-only [connection-tracking]|out2in-dpo] ...>
^^^^^^^^^^^^^^^^^^ 少了一个 n实际接受的是正确拼写 static-mapping-only,按帮助里的拼法输入会被拒绝。 不过既然它会崩,这个拼写问题也就无所谓了。
崩了怎么恢复
如果不小心触发了崩溃:
bash
./labctl down base && ./labctl up base容器会以 Exited (134) 状态停下(134 = 128 + 6,SIGABRT)。 restart-policy: no 意味着它不会自动重启,需要重建。
这也是一堂实战课
生产环境里 VPP 崩溃时,第一件事是保住现场:
bash
docker logs <容器名> 2>&1 | tail -50 # 崩溃栈在这里崩溃栈里最有价值的是 #1 那一帧 —— 它指出是哪个插件的哪个 graph node 出的问题。像上面这样能直接锁定到 nat44_ei_out2in_node_fn, 排查方向就非常明确了。
两个插件能不能同时用
不能。它们会抢同一批接口,配置命令也互不通用。
本教程所有实验步骤开头都调用一个 nat44_clean 函数,把三个 NAT 插件全部关掉, 再启用需要的那个:
bash
nat44_clean() {
vcq nat44 plugin disable >/dev/null
vcq nat44 ei plugin disable >/dev/null
vcq det44 plugin disable >/dev/null
}切换插件会清空所有配置和会话
plugin disable 连带清掉接口归属、地址池、静态映射和整张会话表。
这意味着 ED 和 EI 之间没有平滑迁移路径 —— 切换就是一次彻底的业务中断。 选型要在上线前想清楚,不要指望以后再换。
小结
text
有硬约束?
│
┌─────────────┴─────────────┐
│ │
会话 HA / P2P / twice-NAT / 负载均衡 /
用户配额 / 端口范围 VRF 多租户 / 强安全
│ │
nat44-ei nat44-ed
│ │
└─────────────┬─────────────┘
│
都没有硬约束
│
默认选 nat44-ed
(功能最全,社区主力)第 3 章到此结束。EI 的全部图景:
text
行为 会话粒度粗、过滤宽松、P2P 友好、端口利用率低
独有 会话 HA · 每用户配额 · 端口范围算法 · 每地址端口占用可见
缺失 twice-NAT · 负载均衡映射 · VRF 多租户
雷区 static-mapping-only 会让 26.06 崩溃其中"会话 HA"这一项,配合 VRRP 才是完整方案 —— 实测切换时 18 次心跳零丢失,而只有 VRRP 没有会话同步时切换即断。
接下来第 4 章进入运营商级 NAT:det44 确定性 NAT。 它走的是完全不同的路子 —— 不查表,用算法直接算出映射, 代价是端口利用率固定,好处是可追溯性和极低的状态开销。