У меня есть интерфейсы eth0 (доступ в интернет) и tap_vpn0 (интерфейс vpn tap с сетью 192.168.110.0/24). Я хочу DNAT для всех входящих подключений через eth0 к 192.168.110.2, но ТОЛЬКО если на самом сервере НЕТ прослушивающей службы (в основном, сам VPN-сервер, но в принципе и любая другая служба, отображаемая в netstat -plunt
, включая SSH).
На данный момент я делаю следующее:
iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 22 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 443 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 5555 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 992 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 1194 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 4500 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 500 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 1194 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 1701 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 54700 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 63486 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 68 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p gre -j ACCEPT iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.110.2
записывая длинный список статических исключений. Но есть ли способ сказать IPTables не DNAT в случае, если порт не закрыт на реальном хосте, если пакет будет успешно обработан локально? Так что если, например, у меня есть случайный порт 9988, открытый позже на сервере, мне не нужно добавлять еще одно исключение, iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 9988 -j ACCEPT
но оно просто не будет DNAT?
решение1
Кажется, iptables -t nat -I PREROUTING 1 -i eth0 -m socket --nowildcard -j ACCEPT
это то, что нужно. -m socket
по описанию это именно то, что нужно - соответствует, если есть какой-либо принимающий сокет для этого пакета. Хитрость была в использовании опции --nowildcard
, которую я ранее опустил - даже на странице руководства говорится: "Соответствие сокета не будет принимать нулевые прослушиватели по умолчанию, поскольку тогда локальные службы могли бы перехватывать трафик, который в противном случае был бы перенаправлен". - что на самом деле именно то, что мне было нужно - чтобы локальные службы перехватывали, если таковые имеются!
В результате получаются следующие правила:
iptables -t nat -I PREROUTING 1 -i eth0 -m socket --nowildcard -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 22 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p gre -j ACCEPT iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.110.2
Я оставил порт 22 (ssh) на всякий случай, если что-то не будет работать так, как ожидалось, но, судя по тестированию, все работает отлично!