我正在尝试 1:1 无状态 NAT 流量。流量通过 GRE 隧道进入并通过 VPN 退出。
我已经做了足够的研究来了解从 GRE 隧道进入 linux box 的流量不会击中 Conntrack,也不会击中 iptables -t nat。iptales SNAT、DNAT 或 NETMAP 都需要在 -t nat 表中。
有一个 iproute2 stateless nat 选项,但它在内核版本 2.6 中被删除了。在删除之前,你可以做一个ip route add nat 192.168.50.2 via 192.168.60.2
当从 iproute2 中删除无状态 nat 时,Xtables-addons 包中有一个 RAWDNAT 和 RAWSNAT 选项。 Xtables 插件。Xtables-addons 文档仍然提供 RAWDNAT 和 RAWSNAT 作为选项,但它们会引发错误和Xtables-addons 删除 RAWSNAT/RAWDNAT
这让我现在进入了交通控制的世界。交通控制文档非常稀少且难以遵循。特别是对于入口处理。
所以我已经把问题分解了,现在我只是想在我的 eth0 上使用 tc 来获得一个 1:1 的简单无状态 nat。我有一个地址为 192.168.234.5 和到 10.40.0.0/16 的路由的盒子。我试图从 192.168.234.112 到 10.40.0.112,在两个方向。
对于来自 10.40.0.112 的入站数据包:
tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol ip prio 10 \
u32 match ip src 10.40.0.112/32 \
action nat ingress 10.40.0.112/32 192.168.234.112
Run Code Online (Sandbox Code Playgroud)
和出站数据包
tc qdisc add dev eth0 root handle 1: htb
tc filter add dev eth1 parent 1: protocol ip prio 10 \
u32 match ip dst 192.168.234.112/32 \
action nat egress 192.168.234.112/32 10.40.0.112
Run Code Online (Sandbox Code Playgroud)
不知何故,我实际上能够使上述命令起作用,但在我的一生中,我无法再使它们起作用。我在 stackoverflow.com 上发现了一篇文章,其中说明了 Ubuntu 中的默认 qdisc (pfifo_fast) 是无类的,因此它不提供数据包过滤,但我无法再关注该帖子。如果您添加到不支持过滤器的 qdisc,您会认为“tc filter add”会提供错误消息,但这似乎成功了。
所以这是我正在运行的命令:
首先添加出口 qdisc,以便入口有一些东西要附加到
tc qdisc add dev eth0 root handle 1: htb
tc qdisc add dev eth0 ingress
Run Code Online (Sandbox Code Playgroud)
此时tc qdisc
报告
qdisc htb 1: dev eth0 root refcnt 2 r2q 10 default 0 direct_packets_stat 9 direct_qlen 1000
qdisc ingress ffff: dev eth0 parent ffff:fff1 ----------------
qdisc pfifo_fast 0: dev eth1 root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
现在添加入口过滤器,如:
tc filter add dev eth0 parent ffff: protocol ip prio 10 \
u32 match ip src 10.40.0.112/32 \
action nat ingress 10.40.0.112/32 192.168.234.112
Run Code Online (Sandbox Code Playgroud)
此时,如果我 ping 10.40.0.112,我希望答案来自 192.168.234.112。但过滤器永远不会被击中。实际上,我从未看到应用于数据包的 nat 操作,但是该过滤器规则的统计数据上升了。
我会添加出口过滤器,如:
tc filter add dev eth0 parent 1: protocol ip prio 10 \
u32 match ip dst 192.168.234.112/32 \
action nat egress 192.168.234.112/32 10.40.0.112
Run Code Online (Sandbox Code Playgroud)
此时 tc 过滤器看起来像:
root@ubusswan1-VirtualBox:/home/ubusswan1# tc filter show dev eth0
filter parent 1: protocol ip pref 10 u32
filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 terminal flowid ???
match c0a8ea70/ffffffff at 16
action order 1: nat egress 192.168.234.112/32 10.40.0.112 pass
root@ubusswan1-VirtualBox:/home/ubusswan1# tc filter show dev eth0 root
filter parent ffff: protocol ip pref 10 u32
filter parent ffff: protocol ip pref 10 u32 fh 800: ht divisor 1
filter parent ffff: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 terminal flowid ???
match 0a280070/ffffffff at 12
action order 1: nat ingress 10.40.0.112/32 192.168.234.112 pass
Run Code Online (Sandbox Code Playgroud)
你能帮助我充分理解 tc 以实现 1:1 nat 吗?还有没有更好的方法来调试不起作用的 tc 过滤器?
我认为你互换了src
和dst
匹配。我现在有:
#tc qdisc del dev eth0 ingress
#tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb
tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol ip prio 1 u32 match ip dst $FROMIP action nat ingress $FROMIP $TOIP
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip src $TOIP action nat egress $TOIP $FROMIP
#tc -s qdisc show dev eth0
#tc -s filter show dev eth0
#tc -s filter show dev eth0 parent ffff:
Run Code Online (Sandbox Code Playgroud)
这似乎有效(tc
尽管我不是专家)!