Linux 端口转发(公网机器端口转发到内网IP和端口)

好风 发表于 2018-05-03T12:46:55.717457Z
引用地址:https://plus.ooclab.com/note/article/1408

如果我们有一台 Linux 服务器有公网IP,如何通过这台有公网IP的服务器,将自定义的外部端口,映射/转发(forward)内部IP和端口呢?

环境

  • 有公网IP的服务器安装操作系统 CentOS 7.4 x86_64
  • kvm + libvirtd 创建了虚拟机 192.168.122.96 , 其中端口 7480 启动了 ceph rgw HTTP Server

目标 :通过访问公网IP + 端口 17480 即可访问内部的 http://192.168.122.96:7480 服务。

首先打开 ip forward 功能:

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

其次创建 iptables 规则:

iptables -A PREROUTING -t nat -i em1 -p tcp --dport 17480 -j DNAT --to 192.168.122.96:7480
iptables -A FORWARD -p tcp -d 192.168.122.96 --dport 7480 -j ACCEPT

方法总结

假设公网IP为 119.119.119.119 ,需要将 tcp 端口 2222 转发到内网 192.168.122.128:22 上。

iptables

sysctl net.ipv4.ip_forward=1
export yours_wan_ip=119.119.119.119
iptables -t nat -A PREROUTING -p tcp -m tcp -d $yours_wan_ip --dport 2222 -j DNAT --to-destination 192.168.122.128:22
iptables -A FORWARD -m state -p tcp -d 192.168.122.128 --dport 22 --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -p tcp -m tcp -s 192.168.122.128 --sport 22 -j SNAT --to-source $yours_wan_ip

firewall / firewalld

firewall-cmd --zone=public --add-masquerade
firewall-cmd --zone=public --add-forward-port=port=2222:proto=tcp:toport=22:toaddr=192.168.122.128

注意 libvirtd + firewalld 服务,默认添加了禁止规则,需要去掉:

-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable

1、保存当前规则 iptables-save > t

2、编辑 vim t ,将上面两行移动到最后的之前,如:

-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT

3、导入规则 iptables-restore < t

socat

socat tcp-listen:2222,reuseaddr,fork tcp:192.168.122.128:22

nc

nc -l -p 8002 -c "nc 192.168.122.128 22"

FAQ

如果测试不成功,请:

1. 清理防火墙

iptables -F
iptables -t nat -F

2. 确保 ip 转发开启

# cat /proc/sys/net/ipv4/ip_forward
1

3. 重试!