使用 TC 的 1:1 无状态 NAT 内核版本 3.16 或更高版本

Bra*_*des 5 linux nat

我正在尝试 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 过滤器?

pow*_*pow 2

我认为你互换了srcdst匹配。我现在有:

#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尽管我不是专家)!