Странное поведение iptable с nat И переадресацией портов

У меня есть несколько выделенных серверов, размещенных в нескольких центрах обработки данных, и я хочу перенести почту ( pop3 , imap , smtp ] и их варианты TLS / SSL) с одного сервера на другой.

Для этой цели я намерен временно установить маршрутизацию NAT на новом сервере на старый для обработки времени DNS

Итак, я определил следующие правила IPTABLES :

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 25  -j DNAT --to-destination <my_remote_ip>:8025
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 110 -j DNAT --to-destination <my_remote_ip>
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 143 -j DNAT --to-destination <my_remote_ip>
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 465 -j DNAT --to-destination <my_remote_ip>:8465
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 587 -j DNAT --to-destination <my_remote_ip>:8587
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 993 -j DNAT --to-destination <my_remote_ip>
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 995 -j DNAT --to-destination <my_remote_ip>
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 110  -j SNAT --to-source <my_local_ip>
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 143  -j SNAT --to-source <my_local_ip>
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 993  -j SNAT --to-source <my_local_ip>
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 995  -j SNAT --to-source <my_local_ip>
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 8025 -j SNAT --to-source <my_local_ip>:25
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 8465 -j SNAT --to-source <my_local_ip>:465
iptables -t nat -A POSTROUTING -d <my_remote_ip> -p tcp -m tcp --dport 8587 -j SNAT --to-source <my_local_ip>:587

iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 110  -j ACCEPT
iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 143  -j ACCEPT
iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 993  -j ACCEPT
iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 995  -j ACCEPT
iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 8025 -j ACCEPT
iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 8465 -j ACCEPT
iptables -A FORWARD -d <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --dport 8587 -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 110  -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 143  -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 993  -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 995  -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 8025 -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 8465 -j ACCEPT
iptables -A FORWARD -s <my_remote_ip> -i eth0 -o eth0 -p tcp -m tcp --sport 8587 -j ACCEPT

(на самом деле упрощено, на самом деле это дублируется для IPv4 и IPV6, а на некоторых серверах интерфейс может отличаться от интерфейса eth0… и Конечно, я изменил фактические IP-адреса)

Вы можете заметить, что почтовые службы обрабатываются только NAT, но службы, связанные с SMTP, также имеют преобразование портов , связанное либо с обратным преобразованием, либо с конкретным прослушиванием этих портов на сервере назначения.

Для этого есть веская причина: мой хостинг-провайдер использует для мониторинга o исходящие SMTP-соединения для обнаружения и блокировки спама, размещенного на всех размещенных ими серверах. Но если я перенаправляю входящие соединения на порт SMTP на другой из моих серверов, входящий спам становится исходящим спамом (с точки зрения центра обработки данных) , прежде чем у него появятся шансы для фильтрации (на целевом сервере) , и в результате мой хостинг-провайдер немедленно блокирует NAT-сервер.

Поэтому мне нужно также преобразовать номер порта, чтобы пересылать эти соединения.

Входящие пакеты и исходящие (NAT'ed) пакеты используют один и тот же интерфейс (потому что эти серверы имеют только один сетевой интерфейс) .

На самом деле это работает более или менее, за исключением того, что порт перенаправляет соединения ( и только эти , без проблем на портах 110, 143 и т. д.) имеют странное поведение: они работают при первом использовании, но если я немедленно отключаюсь и снова подключаюсь, переадресация больше не работает, и мне нужно ждать около 1 до 3 минут, прежде чем я смогу подключиться снова.

Похоже, это связано с IP-адресом, а не с номером порта: даже если предыдущее соединение было через порт 110 (pop3, а не перенаправленный порт), мне нужно подождать такая же задержка перед подключением к порту 25.

Я проверил, что на нескольких серверах все l из них Linux Debian Wheezy , Jessie или Stretch , а также на обоих IPv4 и IPv6 (кроме на Wheezy, который не может использовать NAT IPv6) . ……… Да, я знаю, что Wheezy устарел, поэтому я перехожу.

Все IP-адреса полностью статичны.

И да, я установил / proc / sys / net / ipv4 / ip_forward (и его эквивалент IPv6) на 1 .

Я использую telnet для тестирования соединений и проверяю пересылку с помощью tcpdump . С помощью последнего я могу проверить, что пересылка действительно не выполняется, и что это не сервер назначения, который блокирует входящие соединения.

Пожалуйста, помогите мне найти причину этого 1- 3-минутная задержка блокировки и как ее исправить?

Gingko

1
задан 31 May 2019 в 16:57
1 ответ

Ваша проблема связана с особенностями подключения Linux tr acker.

Быстрый ответ: вы не можете избежать этой задержки в вашей конфигурации. Единственный способ избежать этой проблемы - использовать -j SNAT без указания номера порта в опции - to-source .

Есть также небольшая хитрость, которая может Небольшая помощь вам - используйте в j SNAT диапазон портов вместо одного номера порта. Это позволит вам установить несколько подключений. Количество одновременных подключений - это количество портов в диапазоне. Правило будет выглядеть так:

iptables -t nat -A POSTROUTING -d -p tcp -m tcp --dport 8025 -j SNAT --to-source : 10025-10125

Если вам нужны чертовы подробности, я могу расширить ответ.

Обновление

Чтобы понять подробности, у вас должна быть некоторая предыстория.Прочтите «Сеть ядра Linux: реализация и теория» Рами Розена. В основном вам понадобится «Глава 9. Netfilter. Отслеживание подключений» из этой книги.

Когда пакеты проходят через ваш хост linux, трекер подключений linux ( conntrack ) анализирует их и сохраняет информацию о пакете. перетекает в таблицу ( conntrack table ). Каждый поток пакетов представлен как запись conntrack. Conntrack использует кортежи для идентифицированных потоков пакетов. Кортежи состоят из L3 (IP-адреса обоих концов и номер протокола L4) и L4 (для TCP это информация о номерах портов на обоих концах) информации о потоках.

conntrack имеет несколько модулей для каждого протокола L4, чтобы отслеживать специфические для транспортного протокола состояния соединений. Часть TCP conntrack реализует конечный автомат TCP.

В лабораторной работе (ядро 4.14) наблюдается странное поведение этой части TCP conntrack. Давайте продемонстрируем это в простой среде.

Клиент ( 192.0.2.2 ) подключается к хосту linux ( 192.0.2.1:22 ), который перенаправляет это соединение на другой хост. ( 192.0.2.6:22 ). Хост linux также использует правило SNAT, как и в вашей настройке.

Вывод tcpdump:

14:47:32.036809 IP 192.0.2.2.40079 > 192.0.2.1.22: Flags [S], seq 2159011818, win 29200, length 0
14:47:32.037346 IP 192.0.2.1.22 > 192.0.2.2.40079: Flags [S.], seq 960236935, ack 2159011819, win 28960, options [mss 1460,sackOK,TS val 1415987649 ecr 3003498128,nop,wscale 5], length 0
14:47:32.037683 IP 192.0.2.2.40079 > 192.0.2.1.22: Flags [.], ack 1, win 913, options [nop,nop,TS val 3003498129 ecr 1415987649], length 0
14:47:32.041407 IP 192.0.2.1.22 > 192.0.2.2.40079: Flags [P.], seq 1:22, ack 1, win 905, options [nop,nop,TS val 1415987653 ecr 3003498129], length 21
14:47:32.041806 IP 192.0.2.2.40079 > 192.0.2.1.22: Flags [.], ack 22, win 913, options [nop,nop,TS val 3003498133 ecr 1415987653], length 0
14:47:35.826919 IP 192.0.2.2.40079 > 192.0.2.1.22: Flags [F.], seq 1, ack 22, win 913, options [nop,nop,TS val 3003501918 ecr 1415987653], length 0
14:47:35.827996 IP 192.0.2.1.22 > 192.0.2.2.40079: Flags [F.], seq 22, ack 2, win 905, options [nop,nop,TS val 1415991440 ecr 3003501918], length 0
14:47:35.828386 IP 192.0.2.2.40079 > 192.0.2.1.22: Flags [.], ack 23, win 913, options [nop,nop,TS val 3003501919 ecr 1415991440], length 0

В conntrack на хосте linux я вижу следующее:

ipv4     2 tcp      6 431999 ESTABLISHED src=192.0.2.2 dst=192.0.2.1 sport=40079 dport=22 src=192.0.2.6 dst=192.0.2.5 sport=22 dport=22 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431998 ESTABLISHED src=192.0.2.2 dst=192.0.2.1 sport=40079 dport=22 src=192.0.2.6 dst=192.0.2.5 sport=22 dport=22 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431997 ESTABLISHED src=192.0.2.2 dst=192.0.2.1 sport=40079 dport=22 src=192.0.2.6 dst=192.0.2.5 sport=22 dport=22 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431996 ESTABLISHED src=192.0.2.2 dst=192.0.2.1 sport=40079 dport=22 src=192.0.2.6 dst=192.0.2.5 sport=22 dport=22 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 119 TIME_WAIT src=192.0.2.2 dst=192.0.2.1 sport=40079 dport=22 src=192.0.2.6 dst=192.0.2.5 sport=22 dport=22 [ASSURED] mark=0 zone=0 use=2
...
ipv4     2 tcp      6 0 TIME_WAIT src=192.0.2.2 dst=192.0.2.1 sport=40079 dport=22 src=192.0.2.6 dst=192.0.2.5 sport=22 dport=22 [ASSURED] mark=0 zone=0 use=2

Как видите, несмотря на то, что соединение было закрыто правильно , соответствующая запись conntrack все еще представлена ​​в таблице conntrack с состоянием TIME_WAIT . И поскольку у нас есть только один возможный порт для SNAT, который уже занят, новые попытки подключения терпят неудачу. Почему мы не используем этот порт еще раз? Поскольку система не может отличить ответные пакеты от 192.0.2.6 между текущим потоком в состоянии TIME_WAIT и новым потоком.

Почему conntrack установил соединение в TIME_WAIT вместо уничтожьте его, о чем я не узнал.

3
ответ дан 3 December 2019 в 18:24

Теги

Похожие вопросы