![iptables 规则到 AWS 实例上的 snat 端口和 ip](https://linux22.com/image/115276/iptables%20%E8%A7%84%E5%88%99%E5%88%B0%20AWS%20%E5%AE%9E%E4%BE%8B%E4%B8%8A%E7%9A%84%20snat%20%E7%AB%AF%E5%8F%A3%E5%92%8C%20ip.png)
希望有人可以帮助我,或者至少让我指明正确的方向。我在 AWS 上有一个 NAT 实例,它为主机提供到互联网的出站流量。这很好用。我需要做的是从主机和 NAT 机器上获取任意端口(让我们使用端口 26 作为示例),将其转换为来自端口 25 上的 NAT 机器。这条规则就是我正在尝试的做工作:
iptables -A POSTROUTING -t nat -o eth0 -p tcp --dport 26 -j SNAT --to 172.17.2.125:25
目前,该规则将愉快地更改 IP 地址,但保持传出端口不变。
重定向会很高兴地更改端口,但不会更改源 IP(因此它不会将框保留在正确的公共 IP 上)。
我考虑过使用 pfSense 或其他一些防火墙产品,我认为它们可能能够做到这一点,但对于看起来“简单”的东西来说似乎有点矫枉过正。我已经尝试过疯狂地谷歌搜索,但我一定是搜索了错误的术语...我尝试过“透明代理”,但这似乎也不起作用。
稍微更新一下这个
HOST = 172.17.1.125,通过端口 26 的出站 SMTP 连接 NAT = 172.17.2.126 DESTINATION = 216.1.2.3 端口 25(标准 SMTP 端口)
需要的是拥有
主机(内部)-> NAT -> 目的地
为了正确实现这一点,NAT 服务器必须将端口 26 流量转换到 172.17.2.126 端口 25。
答案1
测试设置:两个网络命名空间ns0
(您的外部邮件服务器)ns1
(您的主机)。主网络命名空间(您的 NAT)执行转发和 nat。连接命名空间的两个 veth 对:
ns0 ---> <------ main ns -----> <--- ns1
veth0b --- veth0a veth1a --- veth1b
10.0.0.1 10.0.0.254 10.0.1.254 10.0.1.1
tcpdump
在 veth0a 和 veth1a 上。作为“邮件服务器”nc -k -l -p 9999
监听端口 9999 。ns0
客户端nc
通过ns1
.正常连接,无 nat,默认随机源端口:
$ echo foo | nc 10.0.0.1 9999 -q0
veth*a: IP 10.0.1.1.60560 > 10.0.0.1.9999
veth*a: IP 10.0.0.1.9999 > 10.0.1.1.60560
在源端口上匹配(我添加-s
到所有匹配项以避免意外,但它也可以在没有 的情况下工作-s
):
# iptables -t nat -A POSTROUTING -o veth0a -s 10.0.1.1/32 -p tcp --sport 8001 -j SNAT --to 10.0.1.81:9900
$ echo foo | nc 10.0.0.1 -p 8001 9999 -q0
veth1a: IP 10.0.1.1.8001 > 10.0.0.1.9999
veth0a: IP 10.0.1.81.9900 > 10.0.0.1.9999
veth0a: IP 10.0.0.1.9999 > 10.0.1.81.9900
veth1a: IP 10.0.0.1.9999 > 10.0.1.1.8001
匹配目标端口(未到达“服务器”,因为规则无法重写目标端口):
# iptables -t nat -A POSTROUTING -o veth0a -s 10.0.1.1/32 -p tcp --dport 7002 -j SNAT --to 10.0.1.82:9900
$ echo bar | nc 10.0.0.1 7002 -q0
veth1a: IP 10.0.1.1.38614 > 10.0.0.1.7002
veth0a: IP 10.0.1.82.9900 > 10.0.0.1.7002
veth0a: IP 10.0.0.1.7002 > 10.0.1.82.9900
veth1a: IP 10.0.0.1.7002 > 10.0.1.1.38614
正如您所看到的,源地址和源端口都得到了很好的转换。在SNAT(源nat),只能翻译来源地址和端口,这就是 S 的意思,也是您链接的文档所说的。相反,在 DNAT 中,您可以翻译目的地地址和端口。 SNAT 发生在 POSTROUTING 中(必须veth0a
在此设置中打开),DNAT 发生在 PREROUTING 中(必须veth1a
在此设置中打开)。因此,您不能将两者结合在一条规则中,并且不能在 SNAT 之后执行 DNAT,因为 PREROUTING 发生在 POSTROUTING 之前。
我的印象是您真正想做的是访问各种邮件服务器,但控制来源通过将规范的 25 端口替换为其他端口,他们可以看到您的地址目的地端口。例如,mail.xxx.com:26
应该联系mail.xxx.com:25
来自一个地址,mail.xxx.com:27
应该联系mail.xxx.com:25
来自另一地址。 (我真的希望这不会与发送垃圾邮件有关...)所以源端口并不重要,给定的目标端口决定源地址,并且目标端口应该改回25。这是正确的吗?如果是的话,由于 nat 的工作方式,这在 Linux 上不容易完成。
如果您能说服您不需要它来处理垃圾邮件,我可以想到两个更好的选择(取决于您的 MTA 软件的功能)。
答案2
我设法找到了可以帮助我解决这个问题的人。以下是我们用于将端口映射到 AWS 中的传出 IP 地址的规则:
首先,您必须让它通过 NAT 实例运行才能正常工作。有很多关于如何配置它的资源。
iptables -t mangle -A PREROUTING -p tcp --dport 27 -j MARK --set-mark 27
iptables -t nat -A PREROUTING -p tcp --dport 27 -j DNAT --to :25
iptables -t nat -A POSTROUTING -m mark --mark 27 -j SNAT --to-source 10.0.0.11