如何使用 iptables 进行端口转发?

如何使用 iptables 进行端口转发?

我希望将 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

当目标主机和网关位于相同的子网(就像您的情况一样,两者都在eth0192.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

我认为这可能会节省一些人在各自路由器上的时间。

相关内容