更改规则后,iptables 未按预期工作

更改规则后,iptables 未按预期工作

背景信息:

有一台机器,我们称之为“机器 A”,(运行 Xubuntu 18.04),我在防火墙后面托管 Minecraft,从现在开始我将其称为“防火墙”,(运行 Ubuntu Server 16.04)。

以前,Minecraft 服务器在我的文件服务器上运行,称之为“机器 B”,一切运行正常,只是 Java 一直出现分段错误,因此我决定转移到机器 A。

当我使用机器 B 时,我在防火墙上对 iptables 使用了以下规则,将到防火墙 25565 端口的所有连接转发到机器 B 的 25565 端口:

iptables -t nat -A PREROUTING -p tcp -d 128.xxx.xxx.xxx --destination-port 25565 -j DNAT --to 192.xxx.xxx.xxx:25565
iptables -A FORWARD -p tcp -i 'enp2s0' -o 'enp4s0' -d 192.xxx.xxx.xxx --destination-port 25565 -m state --state NEW -j ACCEPT

当时这工作得很好,没有任何问题。但现在我已移至机器 A 并相应地修改了上述规则,转发仍然只发生在机器 B 上,而不发生在机器 A 上。

下面是我用来设置防火墙上的所有规则的 iptables 脚本(省略了不相关的条目):

#!/bin/bash

IPT=/sbin/iptables

INET_IFACE='enp4s0'
INET_SUB=128.xxx.xxx.xxx/28

LOCAL_IFACE='enp2s0'
LOCAL_SUB=192.xxx.xxx.xxx/24

# Flush the tables
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD

# Define default policy to DROP packets
$IPT -P INPUT   DROP
$IPT -P OUTPUT  ACCEPT
$IPT -P FORWARD ACCEPT

$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT

$IPT -A INPUT -i $INET_IFACE -m state --state INVALID -j DROP

$IPT -A INPUT -s $LOCAL_SUB -i $LOCAL_IFACE -j ACCEPT

$IPT -A FORWARD -o 'enp4s0' -i 'enp2s0' -s 192.xxx.xxx.xxx/24 -m conntrack --ctstate NEW -j ACCEPT
$IPT -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

$IPT -A INPUT -m state -p tcp --dport 1024:65535 --state ESTABLISHED,RELATED -s 0/0 -j ACCEPT

$IPT -t nat -A PREROUTING -p tcp -d 128.xxx.xxx.xxx --destination-port 25565 -j DNAT --to 192.xxx.xxx.xxx:25565
$IPT -A FORWARD -p tcp -i 'enp2s0' -o 'enp4s0' -d 192.xxx.xxx.xxx --destination-port 25565 -m state --state NEW -j ACCEPT

检查iptables -Liptables -S显示转发规则存在于计算机 A 中,但如果我尝试从网络外部访问 Minecraft 服务器,它将无法连接,除非服务器正在运行计算机 B,这使我相信更新的转发规则在某个地方没有生效。输出如下:

user@firewall:~# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     icmp --  anywhere             anywhere             icmp echo-reply
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
LOG        all  --  anywhere             anywhere             limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: "
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere             state INVALID
ACCEPT     udp  --  anywhere             anywhere             udp spt:domain
ACCEPT     all  --  192.xxx.xxx.0/24     anywhere
ACCEPT     udp  --  anywhere             anywhere             udp dpts:bootps:tftp
ACCEPT     tcp  --  anywhere             anywhere             state RELATED,ESTABLISHED tcp dpts:1024:65535

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  192.xxx.xxx.0/24     anywhere             ctstate NEW
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             192.xxx.xxx.xxx      tcp dpt:25565 state NEW
ACCEPT     tcp  --  anywhere             192.xxx.xxx.xxx      tcp dpt:http state NEW

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     icmp --  anywhere             anywhere             icmp echo-reply
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:http
ACCEPT     all  --  anywhere             anywhere
user@firewall:~# iptables -S
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i enp4s0 -m state --state INVALID -j DROP
-A INPUT -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -s 192.xxx.xxx.0/24 -i enp2s0 -j ACCEPT
-A INPUT -p udp -m udp --dport 67:69 -j ACCEPT
-A INPUT -p tcp -m state --state RELATED,ESTABLISHED -m tcp --dport 1024:65535 -j ACCEPT
-A FORWARD -s 192.xxx.xxx.0/24 -i enp2s0 -o enp4s0 -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -d 192.xxx.xxx.xxx/32 -i enp2s0 -o enp4s0 -p tcp -m tcp --dport 25565 -m state --state NEW -j ACCEPT
-A FORWARD -d 192.xxx.xxx.xxx/32 -i enp2s0 -o enp4s0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 80 -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

您可能注意到,我还将端口 8080 从防火墙转发到了机器 A 上的端口 80。这只是一个健全性检查,以确保端口转发对该机器有效,并且确实有效。

我的问题正是:什么原因导致 25565 的转发规则仍然对机器 B 起作用,而它应该对机器 A 起作用?

编辑-添加的输出iptables -t nat -S

user@firewall:~# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A PREROUTING -i enp4s0 -p tcp -m tcp --dport 25565 -j DNAT --to-destination 192.xxx.xxx.xxx:25565 # (Machine B)
-A PREROUTING -i enp4s0 -p tcp -m tcp --dport 25565 -j DNAT --to-destination 192.xxx.xxx.xxx # (Machine B)
-A PREROUTING -d 128.xxx.xxx.xxx/32 -p tcp -m tcp --dport 25565 -j DNAT --to-destination 192.xxx.xxx.xxx:25565 # (Machine B - Shows up 14 more times) 
-A PREROUTING -d 128.xxx.xxx.xxx/32 -p tcp -m tcp --dport 25565 -j DNAT --to-destination 192.xxx.xxx.xxx:25565 # (Machine A - Shows up 2 more times)
-A PREROUTING -d 128.xxx.xxx.xxx/32 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.xxx.xxx.xxx:80 # (Machine A)
-A POSTROUTING -j MASQUERADE # (Shows up 35 more times)

答案1

明白了。我包含的脚本在运行时不会清除 nat 表,这导致我的旧规则仍然存在,从而导致我遇到的问题。以下文章帮助我解决了这个问题:清除所有 iptables 规则的最佳方法(在 Server Fault 上清除所有 iptables 规则的最佳方法)。我iptables -t nat -F在脚本顶部添加了以下内容并重新运行了该脚本,这样就解决了所有问题。在 @Tomek 要求我提供输出后,iptables -t nat -S我开始怀疑我是否也必须刷新 nat 表。再次感谢!

相关内容