Мои правила DNAT для iptables не работают до перезагрузки. Если я перезагружаю свой сервер, все правила работают.
Десятки хостов (отправителей) отправляют некоторые UDP-пакеты (в одну сторону на определенный порт 9999) на мой маршрутизатор Linux. Этот маршрутизатор Linux использует iptables для пересылки этих пакетов на несколько хостов (получателей).
senderX 10.0.0.X ====> Linux-роутер с iptables ====> ReceiverY 10.0.1.Y
Маршрутизатор linux имеет две сетевые карты: eth1 10.0.0.1/24 (сторона отправителя) и eth0 10.0.1.1/24 (сторона получателя).
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
ip addr show
:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 54:9f:35:0a:16:38 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.1/24 brd 10.0.1.255 scope global eth0
inet6 fe80::569f:35ff:fe0a:1638/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 54:9f:35:0a:16:3a brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 brd 10.0.0.255 scope global eth1
inet6 fe80::569f:35ff:fe0a:163a/64 scope link
valid_lft forever preferred_lft forever
После добавления набора правил некоторые из них не работают. И с помощью tcpdump я вижу, что UDP-пакеты больше не маршрутизируются, а пакеты отклоняются.
tcpdump -n -i eth1 host 10.0.0.2
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
16:12:58.241225 IP 10.0.0.2.56859 > 10.0.0.1.9999: UDP, length 1464
16:12:58.241285 IP 10.0.0.1 > 10.0.0.2: ICMP 10.0.0.1 udp port 9999 unreachable, length 556
Я добавил правило для регистрации определенного отправителя, который не работает:
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j LOG --log-prefix='PREROUTING LOG :'
Но это правило ничего не регистрирует. Пакеты приходят, потому что я вижу их в tcpdump, но они не регистрируются. Также с -v
в iptables, я не вижу увеличения счетчиков для этого правила.
Если я применю то же правило до того, как оно перестанет работать, у меня появятся журналы.
Описанные вами симптомы соответствуют тем, которые наблюдаются при конфликте между правилом NAT и записью отслеживания соединения.
Например, когда пакет соответствует
-A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
необходимо создать новую запись отслеживания подключения. Это сопоставит кортеж IP-адреса источника и назначения и порта на входящей стороне с аналогичным кортежем на исходящей стороне.
Не может быть существующей записи отслеживания соединения, соответствующей входящей стороне, потому что, если бы она была, она использовалась бы вместо правила. Однако после того, как IP-адрес назначения кортежа был заменен для создания кортежа для исходящей стороны, кортеж может конфликтовать с существующей записью отслеживания соединения.
Если вы установите conntrack
утилита, вы можете ввести conntrack -L
чтобы увидеть список существующих записей отслеживания подключений. Эта утилита также имеет функции для перечисления только записей отслеживания соединений, соответствующих определенным критериям, а также для удаления выбранных записей.
Если это действительно проблема, с которой вы столкнулись, то удаление записи отслеживания соединения, которая нарушает правила, решит проблему. Постоянное исправление обычно включает настройку соответствующих правил NAT для пакетов в обоих направлениях, так что вы всегда получаете желаемую запись отслеживания соединения, даже если первый пакет отправляется в противоположном направлении, чем обычно.