使用内部 SNAT 进行 iptables 端口转发

使用内部 SNAT 进行 iptables 端口转发

我想将外部端口转发到私有网络上的机器上的另一个端口。但是,我需要对流量进行 SNAT,使其看起来像是来自网关的内部 IP,因为目标机器具有完全不同的出站路由。我在这里合并了两个问题,但我不确定是否可以合并分别询问它们的结果。

网关 = 1.2.3.4/192.168.2.5,内部服务器 = 192.168.2.10

  1. 转发到不同的端口

我已经习惯这样做了,而且这似乎是谷歌为我找到的唯一答案:

iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 12345 -j DNAT --to-destination 192.168.2.10:12345
iptables -A FORWARD -p tcp -d 192.168.2.10 --dport 12345 -j ACCEPT
iptables -A POSTROUTING -t nat -d 192.168.2.10 -s 192.168.2.0/24 -p tcp --dport 12345 -j SNAT --to 1.2.3.4

这会将端口 12345 从我的外部 IP 1.2.3.4 转发到 192.168.2.10:12345。如果我想转发到端口 54321 怎么办?我对哪个端口引用与哪台机器匹配感到困惑;我过去曾通过反复试验解决了这个问题,但后来发现它并没有真正起作用。

  1. 从 LAN 地址转发

我不确定这部分是否可行。我希望传入 192.168.2.10:54321 的流量来自网关机器的 LAN 地址,而不是来自互联网。(我正在尝试将端口 443 转发到 ssh 服务器,但该服务器已在不同的 IP 地址上在外部可见,因此回复流量将采用不同的路由。)

我修改了上面的标准规则:

iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 12345 -j DNAT --to-destination 192.168.2.10:12345
iptables -A POSTROUTING -t nat -p tcp -d 192.168.2.10 --dport 12345 -j SNAT --to-source 192.168.2.5
iptables -A FORWARD -p tcp -d 192.168.2.10 --dport 12345 -j ACCEPT
iptables -A POSTROUTING -t nat -d 192.168.2.10 -s 192.168.2.0/24 -p tcp --dport 12345 -j SNAT --to 1.2.3.4

tcpdump 显示,流量现在来自网关的 LAN 地址 192.168.2.5,服务器正在回复,但并没有转发到外部地址。我怀疑这根本不可能,回复流量需要以客户端的地址作为目的地,但如果 iptables正确地重定向回复,我将非常感激有关如何操作的线索。

另外,如果可能的话,包括更改目标端口的正确语法,如第 1 部分所述。

答案1

经过一些实验,我想我已经回答了我的问题,所以我应该把它发布在这里,以防其他人觉得它有用。是的,这是可能的,而且相当简单,只需获得正确的地址和端口组合即可。

注意:以下示例要求使用以下方式启用内核 IP 转发

echo 1 > /proc/sys/net/ipv4/ip_forward

在任何这些片段之前。

我的脚本的评论:

# summary:
# allow forwarding *to* destination ip:port
# allow forwarding *from* destination ip:port
# nat packets identified by arrival at external IP / port to have
#  *destination* internal ip:port
# nat packets identified by arrival at internal IP / port to have
#  *source* internal network IP of gateway machine

对于问题中的例子:

# allow inbound and outbound forwarding
iptables -A FORWARD -p tcp -d 192.168.2.10 --dport 54321 -j ACCEPT
iptables -A FORWARD -p tcp -s 192.168.2.10 --sport 54321 -j ACCEPT

# route packets arriving at external IP/port to LAN machine
iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 12345 -j DNAT --to-destination 192.168.2.10:54321
# rewrite packets going to LAN machine (identified by address/port)
# to originate from gateway's internal address
iptables -A POSTROUTING -t nat -p tcp -d 192.168.2.10 --dport 54321 -j SNAT --to-source 192.168.2.5

实际的脚本,因为这应该更容易直接应用:

# EXTIP = external IP of gateway (1.2.3.4)
# EPORT = external port (12345)
# DIP   = destination IP in local network (192.168.2.10)
# DPORT = destination port (54321)
# INTIP = internal IP of gateway (192.168.2.5)

iptables -A FORWARD -p tcp -d $DIP --dport $DPORT -j ACCEPT
iptables -A FORWARD -p tcp -s $DIP --sport $DPORT -j ACCEPT

iptables -A PREROUTING -t nat -p tcp -d $EXTIP --dport $EPORT -j DNAT --to-destination $DIP:$DPORT
iptables -A POSTROUTING -t nat -p tcp -d $DIP --dport $DPORT -j SNAT --to-source $INTIP

我希望这个答案对其他人有用,并且我不会用已经处理过多次的东西来弄乱网站。

相关内容