Недавно я решил отбрасывать пакеты, которые хотят пройти через порт 80. Похоже, в моей конфигурации есть проблемы, потому что некоторые нежелательные пакеты отбрасываются.
Выдержка из моей конфигурации:
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp -s [PUBLIC IP OF MY SERVER] --sport 80 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
Вопрос 1: разве второе правило не бесполезно, поскольку в первом я уже сказал, что принимаю все пакеты с состоянием "ESTABLISHED"?
Вопрос 2: Почему этих двух правил недостаточно, чтобы принять следующие отброшенные пакеты:
Jul 14 18:47:18 [HOSTNAME] kernel: iptables output: IN= OUT=eth0 SRC=[PUBLIC IP OF MY SERVER] DST=[A WWW CLIENT PUBLIC IP] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=8408 DF PROTO=TCP SPT=80 DPT=50085 WINDOW=123 RES=0x00 ACK FIN URGP=0
Jul 14 18:47:53 [HOSTNAME] kernel: iptables output: IN= OUT=eth0 SRC=[PUBLIC IP OF MY SERVER] DST=[A WWW CLIENT PUBLIC IP] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=8409 DF PROTO=TCP SPT=80 DPT=50085 WINDOW=123 RES=0x00 ACK FIN URGP=0
Jul 14 18:48:08 [HOSTNAME] kernel: iptables output: IN= OUT=eth0 SRC=[PUBLIC IP OF MY SERVER] DST=[A WWW CLIENT PUBLIC IP] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=54091 DF PROTO=TCP SPT=80 DPT=25780 WINDOW=16616 RES=0x00 ACK FIN URGP=0
Примечание:
РЕДАКТИРОВАТЬ я смотрел на эта почта, а также включил протоколирование НЕВЕРНЫХ пакетов ядром:
echo 255 >/proc/sys/net/netfilter/nf_conntrack_log_invalid
Кажется, у меня есть несколько видов ошибок:
Jul 14 22:00:40 [HOSTNAME] kernel: nf_ct_tcp: invalid RST IN= OUT= SRC=[ONE_CLIENT_IP] DST=[SERVER_IP] LEN=40 TOS=0x00 PREC=0x00 TTL=49 ID=47149 PROTO=TCP SPT=993 DPT=51364 SEQ=1043042446 ACK=0 WINDOW=0 RES=0x00 RST URGP=0
Jul 14 21:57:11 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state ESTABLISHED IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=3782 SEQ=474588492 ACK=2243291425 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402)
Jul 14 21:57:25 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state LAST_ACK IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=3782 SEQ=474588492 ACK=2243291425 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402)
Jul 14 21:57:41 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state TIME_WAIT IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=3782 SEQ=474588492 ACK=2243291425 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402)
Jul 14 21:58:52 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state SYN_RECV IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=50488 SEQ=3804975135 ACK=229029122 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402)
(на самом деле я дал этот ответ в другом месте, я думал, что это тот же сайт)
согласно этим:
http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm
http://www.iptables.info/en/connection-state.html (не актуально)
Возможно, клиент (возможно, мобильный) закрылся первым, не дождался окончательного FIN / ACK и никогда не отправил свой последний ACK, или, возможно, сервер ответил слишком поздно, и сам клиент был защищен брандмауэром, или любой другой случай медленного ответа ... Итак, сервер повторяет попытку после таймера (sysctl net.netfilter.nf_conntrack_tcp_timeout_last_ack
), но netfilter сбросил состояние до того, как реальный стек TCP сбросит его.
вы должны взять следы и посмотреть, например, есть ли у вас дублирующиеся пакеты.
Второе правило является подмножеством первого правила, поэтому оно бесполезно. Попробуйте увеличить значения различных tcp_timeout настройки (sysctl -w net.netfilter....
или echo XX > /proc/sys/net/netfilter/...
) и посмотрите, исчезнут ли эти журналы. Я устанавливал это по аналогичным причинам в прошлом, и он «решил» некоторые загадочные журналы netfilter. Это может увеличить использование памяти conntrack.
1) Второй кажется бесполезным, если у вас есть первый.
2) Сейчас. Зачем вообще нужно использовать DROP по умолчанию для OUTPUT? Вы себе не доверяете? Я бы оставил ПРИНЯТЬ по умолчанию. Просто примените свои правила к цепочке INPUT с помощью DROP по умолчанию. При правильных правилах в цепочке INPUT и DROP по умолчанию iptables отлично справится с защитой вашего сервера. Создание таких политик для OUTPUT кажется слишком сложным, если вы не настраиваете особую безопасность.
До завершения трехстороннего установления связи TCP соединение еще не будет «установлено». Рукопожатие требует, чтобы клиент отправил SYN
пакет, вы возвращаете SYN+ACK
пакет, а затем клиент возвращает ACK
пакет. Однако вы собираетесь заблокировать SYN+ACK
исходящий пакет.
Лучше всего разрешить все пакеты в OUTPUT
которые соответствуют -p tcp --sport 80 --dport 1024:65535
. Вы также можете дополнительно ограничить нижнюю границу; IANA рекомендует использовать порты 41952 и выше для произвольных исходных портов, но, как вы можете заметить, многие клиенты не соответствуют требованиям. Подобное правило разрешит любой трафик, который является ответом на соединение с портом 80, когда порт на клиенте не является привилегированным портом (и предотвратит вызов вредоносной программы домой на 80 или 443).
Если вы предпочитаете использовать состояния подключения для своих правил, вы также можете разрешить исходящие пакеты на исходный порт 80 с состояниями ESTABLISHED,RELATED,SYN_RECV
(в вашей конфигурации вы можете просто использовать SYN_RECV
потому что первое правило позаботится об этом). Это позволит исходящим SYN+ACK
для установки исходящего соединения.
Недействительные пакеты, похоже, связаны с тем, что они SYN+ACK
пакетов, но соединение не ожидает установления. Вероятно, это артефакт, не связанный с проблемой, и беспокоиться не о чем.