使用 iptables 进行双向 NAT

使用 iptables 进行双向 NAT

简而言之,我手头有一个集群系统,我必须通过其主节点路由流量。将流量从节点路由到外部世界是可行的,但将流量从我们部门的子网路由到节点却失败了。不幸的是,将节点添加到我们的子网是不可能的。

设置

集群设置,为了简单起见,没有哑交换机

集群由一个主服务器和多个节点以及一些外围设备组成。这些节点位于内部网络上,对我们的内联网或互联网隐藏。主服务器上已经有一个 NAT,因此节点可以访问内部和外部服务器。这部分工作正常。

主机的外部接口与我们的工作站电脑位于同一子网,它们共享我们无法控制的网关。

编辑:集群运行 CentOS 7,个人电脑运行基于 Ubuntu xenial 的发行版。

任务

我们的一些软件包需要直接访问节点。为此,我们想使用 iptables 在主节点上设置第二个 NAT,并在 pc 上添加一个 ip 路由,以通过主节点将流量发送到 10.10.1.0/24。

配置

主:ip 路由

default via 123.45.67.254 dev eth0 proto static metric 100
10.10.0.0/16 dev eth1 proto kernel scope link src 10.10.0.1
123.45.67.0/23 dev eth0 proto kernel scope link src 123.45.67.204 metric 100

主服务器:iptables -vnL -t nat

Chain PREROUTING (policy ACCEPT 7356 packets, 880K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 4884 packets, 687K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 3445 packets, 225K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 3445 packets, 225K bytes)
 pkts bytes target     prot opt in     out     source               destination
  439 33324 MASQUERADE  all  --  *     eth0    10.10.1.0/24         0.0.0.0/0
61828 3710K MASQUERADE  all  --  *     eth1    123.45.67.0/23       10.10.1.0/24

使用 SNAT 而不是 MASQUERADE 没有什么区别。

节点:ip 路由

default via 10.10.0.1 dev eth1
10.10.0.0/16 dev eth1 proto kernel scope link src 10.10.1.1

pc:ip路由

default via 123.45.67.254 dev eth0  proto static  metric 100
10.10.0.0/16 via 123.45.67.204 dev eth0
123.45.67.0/23 dev eth0  proto kernel  scope link  src 123.45.67.191  metric 100

目前的诊断

  • 从 node01 到 internet/intranet/pcs 的 NAT 运行顺畅。
  • TCP 握手期间从 pc1 到 node01 的 NAT 失败:
    • SYN 通过 master 传递到 node01,在 tcpdump 中标记为 SYN_RECV
    • SYN+ACK 从 node01 发送到 master
    • SYN+ACK 出现在主机的 tcpdump 中,并被传递给过滤器
    • tcpdump 显示 SYN+ACK 已通过过滤器
    • iptables 显示通过过滤器 FORWARD、mangle FORWARD + POSTROUTING 的 SYN+ACK 包
    • SYN+ACK 包永远无法通过 nat POSTROUTING(它们应该吗?)
    • SYN+ACK 数据包从未到达 pc1
  • 当然,握手失败
    • pc1 卡在 SYN_SENT
    • node01 卡在 SYN_RECV 状态
    • 最终,连接超时
  • 我没有办法在网关监控包裹

我最好的猜测是,由于其源地址在主服务器上被重写,因此途中的状态路由器会丢弃 SYN + ACK 包,因此它与原始 SYN 包的关系会丢失。

我们怎样才能让它发挥作用?

如果需要额外的配置/日志,请告诉我。

相关内容