Назад | Перейти на главную страницу

iptables не работает должным образом после изменения правила

Немного предыстории:

Есть машина, назовем ее «Машина А» (работает с 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 -L и iptables -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 с брандмауэра на порт 80 на машине A. Это была просто проверка работоспособности, чтобы убедиться, что перенаправление портов работает для этой машины, и это действительно так.

Мой вопрос: что может привести к тому, что правила пересылки для 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)

Понял. Сценарий, который я включил, не сбрасывает таблицу nat при каждом запуске, из-за чего мои старые правила сохранялись, вызывая проблему, с которой я столкнулся. Следующая статья помогла мне решить эту проблему: лучший способ очистить все правила iptables (лучший способ очистить все правила iptables при сбое сервера). я добавил iptables -t nat -F в начало моего сценария и перезапустите сценарий, и это устранило все проблемы. После того, как @Tomek попросил меня предоставить результат iptables -t nat -S это заставило меня задаться вопросом, нужно ли мне также очищать нат-таблицу. Еще раз спасибо!