南琴浪博客

iptables 中转流量

01/20/2018

本文介绍如何使用 iptables 中转流量。

相同端口的中转

iptables -t nat -A PREROUTING  -p tcp                      --dport ${port} -j DNAT --to-destination ${ip-destination}
iptables -t nat -A PREROUTING  -p udp                      --dport ${port} -j DNAT --to-destination ${ip-destination}
iptables -t nat -A POSTROUTING -p tcp -d ${ip-destination} --dport ${port} -j SNAT --to-source ${ip-source}
iptables -t nat -A POSTROUTING -p udp -d ${ip-destination} --dport ${port} -j SNAT --to-source ${ip-source}

其中,带有 destination 的值表示你要中转的目标,带有 source 的值表示你用来中转的这台机本身。iptables 的所有规则都写在你用来中转的这台机上。

不同端口的中转

iptables -t nat -A PREROUTING  -p tcp -m tcp                      --dport ${port-source}      -j DNAT --to-destination ${ip-destination}:${port-destination}
iptables -t nat -A PREROUTING  -p udp -m udp                      --dport ${port-source}      -j DNAT --to-destination ${ip-destination}:${port-destination}
iptables -t nat -A POSTROUTING -p tcp -m tcp -d ${ip-destination} --dport ${port-destination} -j SNAT --to-source ${ip-source}
iptables -t nat -A POSTROUTING -p udp -m udp -d ${ip-destination} --dport ${port-destination} -j SNAT --to-source ${ip-source}

和上面那种情况的区别在于,因为中转的这台机和被中转的机采用了不同端口,所以规则写法不一样。

我们来举个例子,如果要用 1.1.1.1:80 来中转 2.2.2.2:443,即前者是用来中转的机、后者是被中转的机,那么规则就可以这样写:

iptables -t nat -A PREROUTING  -p tcp -m tcp            --dport 80  -j DNAT --to-destination 2.2.2.2:443
iptables -t nat -A PREROUTING  -p udp -m udp            --dport 80  -j DNAT --to-destination 2.2.2.2:443
iptables -t nat -A POSTROUTING -p tcp -m tcp -d 2.2.2.2 --dport 443 -j SNAT --to-source 1.1.1.1
iptables -t nat -A POSTROUTING -p udp -m udp -d 2.2.2.2 --dport 443 -j SNAT --to-source 1.1.1.1

更简便的写法

这是一种更简便的写法,使用 MASQUERADE 实现自动化 snat(有关这部分,更具体的可以查看这篇文章),不需要具体指定 source 参数(不需要区分相同端口和不同端口两种情况)。

iptables -t nat -A PREROUTING -p tcp -i eth0 --dport ${port-source} -j DNAT --to ${ip-destination}:${port-destination}
iptables -t nat -A PREROUTING -p udp -i eth0 --dport ${port-source} -j DNAT --to ${ip-destination}:${port-destination}
iptables -t nat -A POSTROUTING -j MASQUERADE

其中,eth0 是你的网卡名称,可以使用 ifconfig 指令查看。