我希望将 ppp0 端口 8001 上的传入连接路由到 eth0 端口 8080 上的 192.168.1.200。
我有这两条规则
-A PREROUTING -p tcp -m tcp --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT
但它不起作用。我遗漏了什么?
答案1
首先 - 您应该检查是否允许转发:
cat /proc/sys/net/ipv4/conf/ppp0/forwarding
cat /proc/sys/net/ipv4/conf/eth0/forwarding
如果两者都返回,1
则没问题。如果没有,请执行以下操作:
echo '1' | sudo tee /proc/sys/net/ipv4/conf/ppp0/forwarding
echo '1' | sudo tee /proc/sys/net/ipv4/conf/eth0/forwarding
第二件事 -DNAT
只能应用于nat
表格。因此,您的规则也应该通过添加表格规范来扩展(-t nat
):
iptables -t nat -A PREROUTING -p tcp -i ppp0 --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
这两条规则都仅适用于 TCP 流量(如果您也想改变 UDP,则需要提供类似的规则但设置-p udp
选项)。
最后,但并非最不重要的是路由配置。输入:
ip route
并检查是否192.168.1.0/24
在返回的路由条目之中。
答案2
您忘记了对源地址进行 SNAT 后路由:
sysctl net.ipv4.ip_forward=1
yours_wan_ip=101.23.3.1
-A PREROUTING -p tcp -m tcp -d $yours_wan_ip --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT
-A POSTROUTING -t nat -p tcp -m tcp -s 192.168.1.200 --sport 8080 -j SNAT --to-source $yours_wan_ip
并且不要忘记在计算机上将 Linux 防火墙设置为默认网关,地址为 192.168.1.200。
答案3
当目标主机和网关位于相同的子网(就像您的情况一样,两者都在eth0
192.168.1.0/24 上)。
以下是网关、源和目标都处于开启状态时的通用解决方案不同的子网。
1)启用 IP 转发:
sysctl net.ipv4.conf.eth0.forwarding=1
sysctl net.ipv6.conf.eth0.forwarding=1
//注意:如果转发到/从localhost
,也设置sysctl net.ipv4.conf.eth0.route_localnet=1
2)添加 2 个 iptables 规则来转发特定的 TCP 端口:
重写目的地数据包的 IP(以及回复数据包中的 IP):
iptables -A PREROUTING -t nat -p tcp -i ppp0 --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
重写来源数据包的 IP 到网关的 IP(并返回回复数据包):
iptables -A POSTROUTING -t nat -p tcp -d 192.168.1.200 --dport 8080 -j MASQUERADE
3)如果您没有默认ACCEPT
防火墙规则,请允许流量到达目的地:
iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
4)测试新设置。如果成功,请确保更改在重启后仍然有效:
cat <<EOF > /etc/sysctl.d/99-forwarding.conf
sysctl net.ipv4.conf.eth0.forwarding=1
sysctl net.ipv6.conf.eth0.forwarding=1
EOF
iptables-save > /etc/network/iptables.up.rules
echo '#!/bin/sh' > /etc/network/if-pre-up.d/iptables
echo "`which iptables-restore` < /etc/network/iptables.up.rules" >> /etc/network/if-pre-up.d/iptables
chmod +x /etc/network/if-pre-up.d/iptables
答案4
我创建了以下 bash 脚本来在我的 Linux 路由器上执行此操作。它会自动推断 WAN IP 并在继续操作之前确认您的选择。
#!/bin/bash
# decide which action to use
action="add"
if [[ "-r" == "$1" ]]; then
action="remove"
shift
fi
# break out components
dest_addr_lan="$1"
dest_port_wan="$2"
dest_port_lan="$3"
# figure out our WAN ip
wan_addr=`curl -4 -s icanhazip.com`
# auto fill our dest lan port if we need to
if [ -z $dest_port_lan ]; then
dest_port_lan="$dest_port_wan"
fi
# print info for review
echo "Destination LAN Address: $dest_addr_lan"
echo "Destination Port WAN: $dest_port_wan"
echo "Destination Port LAN: $dest_port_lan"
echo "WAN Address: $wan_addr"
# confirm with user
read -p "Does everything look correct? " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [[ "remove" == "$action" ]]; then
iptables -t nat -D PREROUTING -p tcp -m tcp -d $wan_addr --dport $dest_port_wan -j DNAT --to-destination $dest_addr_lan:$dest_port_lan
iptables -D FORWARD -m state -p tcp -d $dest_addr_lan --dport $dest_port_lan --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -D POSTROUTING -p tcp -m tcp -s $dest_addr_lan --sport $dest_port_lan -j SNAT --to-source $wan_addr
echo "Forwarding rule removed"
else
iptables -t nat -A PREROUTING -p tcp -m tcp -d $wan_addr --dport $dest_port_wan -j DNAT --to-destination $dest_addr_lan:$dest_port_lan
iptables -A FORWARD -m state -p tcp -d $dest_addr_lan --dport $dest_port_lan --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -p tcp -m tcp -s $dest_addr_lan --sport $dest_port_lan -j SNAT --to-source $wan_addr
echo "Forwarding rule added"
fi
else
echo "Info not confirmed, exiting..."
fi
脚本的使用很简单,只需将其复制并粘贴到文件中即可。
# chmod +x port_forward.sh
# ./port_forward.sh 192.168.1.100 3000
... confirm details ... press y
# Forwarding rule added
删除同一规则
# ./port_forward.sh -r 192.168.1.100 3000
... confirm details ... press y
# Forwarding rule removed
我认为这可能会节省一些人在各自路由器上的时间。