因为一些特殊原因,我需要用到端口转发功能,这个功能是这样的,我有2台服务器:A和B,分别是2个不同IP。2台服务器各自的特点是:A网络好,性能差;B网络差,但性能强。(此处“网络”只针对大陆IP访问的网络性能) 所以我的网站放在B上,但是要通过A服务器的IP去访问B服务器上的网站。(注意,这里只是拿放网站做例子,如果只放网站的话,使用nginx做反向代理即可。如果是其他的服务,就需要使用本文章说的端口转发。) 例如: A服务器IP:1.1.1.1 B服务器IP:2.2.2.2 通过网上找到的资料,找到设置方法如下:
首先开启机器的转发功能,有2个方法,有的系统方法1重启后会失效,有的openvz的小鸡方法二无法试用。所以可以2个方法都试试,哪个能用就用哪个。
方法一:echo 1 >/proc/sys/net/ipv4/ip_forward
方法二:编辑文件/etc/sysctl.conf,修改net.ipv4.ip_forward = 0为net.ipv4.ip_forward = 1,如果这行最前面有注释,就去掉注释。如果没有这行,就在文件末尾增加这行内容。保存后执行sysctl -p生效。
然后执行:
设置转发规则
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 2.2.2.2
iptables -t nat -A POSTROUTING -p tcp -d 2.2.2.2 --dport 80 -j SNAT --to-source 1.1.1.1
iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
注意:第三行的venet0一般是openvz结构的VPS的网卡接口名,如果是KVM结构的VPS或者独服,一般是eth0,有些用到虚拟桥接网卡的,可能是vmbr0,需要自己先查看网卡接口名具体是什么。
然后保存并重启iptables,使新规则生效:
使新加的规则生效
iptables-save
1 | iptables-save |
---|
但是这样设置之后,却始终无法打开网站。
经过无数次反复尝试摸索,发现注销掉防火墙中的一行代码后就可以访问了, 这行代码是:-A FORWARD -j REJECT --reject-with icmp-host-prohibited 查询相关资料后,才知道这行意思是拒绝不在此行只上允许列表内的所有连接。原来是这个规则阻止了80端口的转发。但是我不想注释掉这条规则,因为会降低服务器安全性。还是找办法给80端口的转发放行比较靠谱。 其他网上添加允许端口的例子都是类似这样的:iptables -I INPUT -p tcp --dport 80 -j ACCEPT,但是我这样添加后,没有效果。于是尝试照葫芦画瓢,把INPUT改成FORWARD,然后就成功了。 所以正确的放行方法是:
放行要转发的端口
iptables -I FORWARD -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -p tcp --sport 80 -j ACCEPT
总结:完整设置好一个端口转发的完整步骤需要4个命令(只转发TCP连接的情况下)。
添加端口转发的完整步骤
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 2.2.2.2
iptables -t nat -A POSTROUTING -p tcp -d 2.2.2.2 --dport 80 -j SNAT --to-source 1.1.1.1
iptables -I FORWARD -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -p tcp --sport 80 -j ACCEPT
最后别忘记保存并重启iptables服务。
更新:可以使用一句iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE或iptables -t nat -A POSTROUTING -p tcp -m tcp --dport 80 -o venet0 -j MASQUERADE代替所有单独端口的POSTROUTING设置(注意:有的机器网卡信息是eth0,而不是venet0),这样可以精简一行代码,再增加端口转发规则时,可以是:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 2.2.2.2
iptables -I FORWARD -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -p tcp --sport 80 -j ACCEPT