我的 nat 和数据包路由工作正常,但我想将除 SSH 之外的所有端口转发到静态 ip(192.168.0.3)
执行此操作的正确 iptables 语法是什么?
答案1
自iptables规则按顺序执行(第一个匹配的规则适用,后面的规则甚至不会被测试),您可以按如下方式执行:
iptables -t nat -A PREROUTING -i eth0 -d 192.168.0.2 -j DNAT --to 192.168.0.3
iptables -t nat -A PREROUTING -i eth0 -d 192.168.0.2 -j DNAT --to 192.168.0.3
iptables -A FORWARD -i eth0 -d 192.168.0.2 --dport 22 -j REJECT
iptables -A FORWARD -i eth0 -d 192.168.0.2 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
假设您执行此操作的 PC 的 IP 地址为 192.168.0.2,否则请相应地更改它。最后一条规则是为了确保 IP 地址为 192.168.0.3 的 PC 的连接性。
答案2
先前的答案过于复杂,并且随着nftables以下是我对这个问题的看法,虽然从另一个角度看很复杂,但很完整:
sysctl 设置
启用 IPv4 和 IPv6 转发(也称为网络地址转换 (NAT)):
sudo tee '/etc/sysctl.d/90-ip-forward.conf' << EOF
# Enable IPv4 forwarding (NAT).
net.ipv4.ip_forward=1
# Enable IPv6 forwarding (NAT).
net.ipv6.conf.all.forwarding=1
EOF
应用sysctl
设置:
sudo sysctl --system
环境检测
检测传出网络接口(即面向 Internet 的接口):
default_interface="$(command ip route show 'default' |
command head --lines=1 |
command cut --delimiter=' ' --fields=5)"
检测SSH守护进程监听端口:
sudo --validate &&
sshd_port="$(sudo sshd -T -f '/etc/ssh/sshd_config' |
grep "^port " |
cut --delimiter=" " --fields=2)"
源 NAT - 伪装
伪装是 SNAT 的一个特例,其中源地址“自动”设置为输出接口的地址。
伪装是连接共享背后的机制。
伪装规则不是所提问题的答案的一部分,但对于有效的 NAT 设置而言是必需的。当与正确设置的 DHCP 服务器结合使用或使用防火墙 IP 作为这些主机上的网络网关时,它允许防火墙后面的主机访问 Internet。
在旧版中iptables
,伪装来自默认网络接口的所有传出流量的规则是:
sudo iptables --append 'POSTROUTING' --table 'nat' \
--out-interface "${default_interface}" --jump 'MASQUERADE'
随着新法的实施nftables
,同样的规则分为两部分。
创建
source-nat
表,并将其添加为后路由钩子(相当于iptables --table 'nat'
:sudo nft add table 'source-nat' sudo nft add chain 'source-nat' postrouting '{ type nat hook postrouting priority 100 ; }'
将伪装规则添加到
source-nat
默认传出接口(或oif
)的表中:sudo nft add rule 'source-nat' 'postrouting' oif "${default_interface}" 'masquerade'
转发除 SSH 之外的所有端口
在旧版中iptables
,转发除 SSH 之外的所有端口(针对 IP 地址为 的目标主机)的规则192.168.0.3
是:
添加一条规则,将所有传入的 TCP 流量转发到目标 IP 地址,但针对 SSH 守护程序端口 ( ) 的流量除外
! --dport "${sshd_port}"
:sudo iptables --append 'PREROUTING' --table 'nat' \ --in-interface "${default_interface}" --protocol 'tcp' ! --dport "${sshd_port}" --jump 'DNAT' --to "192.168.0.3"
添加一条规则,将所有传入的 UDP 流量转发到目标 IP 地址:
sudo iptables --append 'PREROUTING' --table 'nat' \ --in-interface "${default_interface}" --protocol 'udp' --jump 'DNAT' --to '192.168.0.3'
随着新法的实施nftables
,同样的规则分为两部分。
创建
destination-nat
表,并将其添加为预路由钩子(相当于iptables --table 'nat'
:sudo nft add table 'destination-nat' sudo nft add chain 'destination-nat' prerouting '{ type nat hook prerouting priority -100; }'
将转发所有传入 TCP 流量(SSH 端口除外)的规则添加到
destination-nat
默认传入接口(或iif
)的表中:sudo nft add rule 'destination-nat' 'prerouting' iif "${default_interface}" \ 'tcp' dport != "${sshd_port}" dnat to '192.168.0.3'
将转发所有传入 UDP 流量(SSH 端口除外)的规则添加到
destination-nat
默认传入接口(或iif
)的表中:sudo nft add rule 'destination-nat' 'prerouting' iif "${default_interface}" \ 'udp' dnat to '192.168.0.3'
我相信使用时可以将两个目标 NAT 规则合二为一
nftables
,但我还没有找到正确的解决方案。
瞧!
有关nftables
NAT 规则的更多信息,请参阅执行网络地址转换(NAT)@nftables。