iptables SNAT 不适用于 GRE 数据包

iptables SNAT 不适用于 GRE 数据包

我正在尝试将 SNAT 应用于 PPTP 客户端。TCP/1723 数据包已正确进行 SNAT,但 GRE 数据包未正确进行 SNAT。有人能发现问题所在吗?

我有以下 iptables 配置:

$ sudo iptables -t nat -L POSTROUTING -v -n
Chain POSTROUTING (policy ACCEPT 616 packets, 37030 bytes)
pkts bytes target     prot opt in     out     source               destination         
   0     0 SNAT       47   --  *      *       $internal_ip         0.0.0.0/0            to:$external_ip

当使用 tcpdump 检查出口接口上的传出流量时,我看到以下内容:

<timestamp> IP $internal_ip > $target_ip: GREv1, call 31607, seq 1, length 36: LCP, Conf-Request (0x01), id 1, length 22

... 与预期不同,$external_ip >所以显然SNAT翻译不起作用(从中可以清楚地看出0 pkts 0 bytes)。

我已经加载了以下模块(其中包括):

nf_nat_proto_gre
nf_conntrack_proto_gre   
nf_conntrack_pptp
nf_nat_pptp

以防万一这是相关的,这里有几点说明:

  • 路由使用第三方防火墙在上游进行(因此传出的数据包已经在正确的出口接口上)。
  • 防火墙实际上在虚拟机中运行(上面的iptables列表来自其虚拟机管理程序),并桥接至出口接口。
  • TCP/1723 数据包被防火墙 SNAT 处理(但 GRE 数据包没有);我实际上正在尝试使用 IPTables 作为解决防火墙缺陷的变通方法。想必 IPTables 并不关心数据包是如何到达那里的?
  • 出口接口/网桥具有不同于$external_ip(尽管在同一子网中)的静态 IP

这是运行3.13.0-123-generic

答案1

首先,您的 iptables 命令缺少-t nat部分。但这应该会产生错误,因为默认情况下,过滤表中不存在 POSTROUTING 表。请确保将其添加到正确的表中。这与这个问题非常相似:Linux 路由器上的 NAT GRE(IP 协议 47)

接下来,确保您指定了正确的 $internal_ip,并且该值与您在 tcpdump 上看到的值相匹配。有时一个简单的拼写错误就会被忽略,并使事情看起来很复杂。

另外,检查您的 iptables 规则中没有任何在 SNAT 规则之前触发的前置规则。Netfilter 只会在那种情况下触发第一个匹配。您注意到 TCP/1723 已进行 NAT,这实际上意味着您在那里有其他规则。

如果这没有帮助,请确保使用iptables -t nat -L -v -n和类似的东西检查并发布您的详细配置ip rule ls && ip route ls。使用-v带有 iptables 的交换机,您实际上可以看到每个规则触发了多少数据包。

您正在虚拟机内部运行。请检查主机节点的 iptables 规则!您的规则可能有效,但主机节点防火墙已将来自虚拟机的打包源 IP 覆盖回内部 IP。似乎您正在其他地方检查数据包,即不直接在您的虚拟机上。

相关内容