Немного предыстории:
Есть машина, назовем ее «Машина А» (работает с 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
это заставило меня задаться вопросом, нужно ли мне также очищать нат-таблицу. Еще раз спасибо!