不幸的是,我们有一个客户,他已将设备硬编码为指向特定 IP 和端口。我们希望将流量从他们的 IP 重定向到我们的负载均衡器,该负载均衡器会将 HTTP POST 发送到能够处理该请求的服务器池。我希望来自所有其他 IP 的现有流量不受影响。
我相信 iptables 是实现此目的的最佳方法,并且我认为这个命令应该有效:
/sbin/iptables -t nat -A PREROUTING -s $CUSTIP -j DNAT -p tcp --dport 8080 -d $CURR_SERVER_IP --to-destination $NEW_SERVER_IP:8080
不幸的是,它没有按预期工作。我不确定是否需要添加另一条规则,可能在链中POSTROUTING
?
下面我用真实的 IP 替换了上面的变量,并尝试在我的测试环境中逐步复制布局。
$CURR_SERVER_IP = 192.168.2.11
$NEW_SERVER_IP = 192.168.2.12
$CUST_IP = 192.168.0.50
同一 IP 上的端口转发
/sbin/iptables -t nat -A PREROUTING -p tcp -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.11:8080
完全按照预期工作。
IP 和端口转发到不同的机器
/sbin/iptables -t nat -A PREROUTING -p tcp -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.12:8080
连接似乎超时了。
限制 IP 和端口转发仅适用于来自特定 IP 的请求
/sbin/iptables -t nat -A PREROUTING -p tcp -s 192.168.0.50 -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.12:8080
我已ACCEPT
按照@Massimo 建议添加了规则,但仍然没有成功。
我从头开始并运行了以下命令:
# /sbin/iptables -t nat -A PREROUTING -p tcp -d 192.168.2.11 --dport 16000 -j DNAT --to-destination 192.168.2.12:8080
# iptables -A FORWARD -j ACCEPT
现在规则如下:
# iptables -L -v --line-numbers (see FORWARD rule 7)
Chain INPUT (policy ACCEPT 1115M packets, 889G bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT udp -- virbr0 any anywhere anywhere udp dpt:domain
2 0 0 ACCEPT tcp -- virbr0 any anywhere anywhere tcp dpt:domain
3 0 0 ACCEPT udp -- virbr0 any anywhere anywhere udp dpt:bootps
4 0 0 ACCEPT tcp -- virbr0 any anywhere anywhere tcp dpt:bootps
Chain FORWARD (policy ACCEPT 112 packets, 5936 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT all -- any virbr0 anywhere 192.168.122.0/24 state RELATED,ESTABLISHED
2 0 0 ACCEPT all -- virbr0 any 192.168.122.0/24 anywhere
3 0 0 ACCEPT all -- virbr0 virbr0 anywhere anywhere
4 0 0 REJECT all -- any virbr0 anywhere anywhere reject-with icmp-port-unreachable
5 0 0 REJECT all -- virbr0 any anywhere anywhere reject-with icmp-port-unreachable
6 0 0 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
7 6 336 ACCEPT all -- any any anywhere anywhere
Chain OUTPUT (policy ACCEPT 813M packets, 428G bytes)
num pkts bytes target prot opt in out source destination
和
# iptables -L -t nat -v --line-numbers
Chain PREROUTING (policy ACCEPT 3108K packets, 242M bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DNAT tcp -- any any anywhere 192.168.2.11 tcp dpt:16000 to:192.168.2.12:8080
Chain POSTROUTING (policy ACCEPT 13M packets, 790M bytes)
num pkts bytes target prot opt in out source destination
1 8644 1979K MASQUERADE all -- any any 192.168.122.0/24 anywhere
Chain OUTPUT (policy ACCEPT 13M packets, 792M bytes)
num pkts bytes target prot opt in out source destination
有没有人看到明显的问题,会导致浏览器超时,当我去http://192.168.2.11:16000?
答案1
您的 NAT 规则似乎没问题,但是您是否还为此流量添加了 ACCEPT 规则?
否则,NAT 将成功启动,但生成的数据包将被悄悄丢弃...
更新:
您需要在 FORWARD 链(处理通过防火墙但与防火墙不直接相关的数据包的地方)中添加此规则。
应用 FORWARD 规则后PREROUTING 规则(如 NAT),因此当应用此规则时,数据包看起来就像来自原始 IP,但被定向到修改后的新目标 IP。因此,规则应该类似于以下内容:
/sbin/iptables -A FORWARD -s $CUSTIP -d $NEW_SERVER_IP -j ACCEPT
答案2
我假设您正在使用 Linux 机器作为路由器,并且该 Linux 机器可以看到新的 IP。
我相信仅当 /proc/sys/net/ipv4/ip_forward 设置为 1 时,NAT 表才会启动。为了使其持久,请在 /etc/sysctl.conf 中输入以下行:
net.ipv4.ip_forward = 1
答案3
有一个 sysctl 设置阻止 dnat 环回。将下面的 eth0 替换为你的外部接口流量进入的接口。
允许它
sysctl -w net.ipv4.conf.eth0.route_localnet=1
或者
echo 1 > /proc/sys/net/ipv4/conf/eth0/route_localnet
并检查设置。
cat /proc/sys/net/ipv4/conf/eth0/route_localnet
现在你可以 dnat 到 127.0.0.1
答案4
我发过类似的问题,自己找到了答案。链接如下:-