Почему некоторые правила DNAT iptables не работают до перезагрузки?
Мои DNAT-правила iptables не работают до перезагрузки. Если я перезагружаю свой сервер, все правила работают.
Описание архитектуры:
Десятки хостов (отправителей) отправляют некоторые пакеты UDP (в одну сторону на определенный порт 9999) на мой маршрутизатор Linux. Этот маршрутизатор Linux использует iptables для пересылки этих пакетов нескольким хостам (получателям).
senderX 10.0.0.X ====> Linux роутер с iptables ====> receiveY 10.0.1.Y
У маршрутизатора linux есть две сетевые карты: eth1 10.0.0.1/24 (сторона отправителя) и eth0 10.0.1.1/24 (сторона получателя).
Настройка Iptables:
- ip_forwarding активирован
- все политики по умолчанию установлены на ПРИНЯТЬ
- для каждого отправителя существуют правила iptables, вот пример:
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT - к месту назначения 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, правила, которые не работали, все равно не работают.
- Если я перезагружаю свой сервер, все правила работают нормально.
Анализ сделан:
Я добавил правило для регистрации конкретного отправителя, который не работает:
iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j LOG --log-prefix='PREROUTING LOG :'
Но это правило ничего не регистрирует. Пакеты идут, потому что я вижу их в tcpdump, но они не зарегистрированы. Также с -v
опция в iptables, я не вижу увеличения счетчиков для этого правила.
Если я применяю то же правило, прежде чем оно перестает работать, у меня есть несколько журналов.
Вопрос:
- Есть ли ограничения на пересылку UDP в iptables?
- Как я могу решить эту проблему?
1 ответ
Описанные вами симптомы совпадают с симптомами, наблюдаемыми в случае конфликта между правилом NAT и записью отслеживания соединения.
Например, когда пакет соответствует
-A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123
новая запись отслеживания соединения должна быть создана. Это сопоставит кортеж IP-адреса источника и назначения и порта на входящей стороне с аналогичным кортежом на исходящей стороне.
Не может быть существующей записи отслеживания соединения, соответствующей входящей стороне, потому что, если бы она существовала, она использовалась бы вместо правила. Однако, как только IP-адрес назначения кортежа был заменен для создания кортежа для исходящей стороны, кортеж может конфликтовать с существующей записью отслеживания соединения.
Если вы установите conntrack
утилита, вы можете ввести conntrack -L
чтобы увидеть список существующих записей отслеживания подключений. Эта утилита также имеет функции для отображения только записей отслеживания соединений, соответствующих определенным критериям, а также удаления выбранных записей.
Если это действительно проблема, с которой вы столкнулись, то удаление ошибочной записи отслеживания соединения устранит проблему. Постоянное исправление обычно включает в себя настройку соответствующих правил NAT для пакетов в обоих направлениях, так что вы всегда получаете желаемую запись отслеживания соединения, даже если первый пакет отправляется в противоположном направлении, чем обычно.