Назад | Перейти на главную страницу

Приведет ли использование iptables DROP target к сокету CLOSE_WAIT, который никогда не завершится?

У меня есть несколько простых правил для блокировки определенных IP-блоков, часто используемых хакерами / спамерами, например:

iptables -A INPUT -s 173.208.250.0/24 -j DROP

Но я заметил, что apache зависает через пару дней, и в выводе netstat отображается множество CLOSE_WAIT, которые никогда не исчезают:

# netstat -atlpn 
Active Internet connections (servers and established) 
Proto Recv-Q Send-Q Local Address Foreign   Address State PID/Program name 
tcp 1 0 ::ffff:10.0.0.107:80 ::ffff:173.208.250.123.50813 CLOSE_WAIT 29125/httpd

Может ли это быть вызвано указанием цели DROP в правиле? Должен ли я использовать вместо этого REJECT?

Может ли это быть вызвано указанием цели DROP в правиле?

Нет.

Следует ли мне использовать REJECT вместо этого?

Нет.


Цель DROP в этом правиле в цепочке INPUT будет означать, что Apache никогда не увидит самый первый пакет SYN или какой-либо пакет с этим адресом источника. Без установления соединения он никогда не перейдет в состояние CLOSE_WAIT. См. Диаграмму состояний из Википедии ниже:

Как видите, CLOSE_WAIT происходит только после установленного сеанса и только на сервере, если клиент инициирует закрытие сеанса. С KeepAlive сеанс остается открытым до тех пор, пока один из клиентов или серверов не достигнет своего тайм-аута и не закроет сеанс.

Обычно сервер достигает этого тайм-аута и закрывает сеанс, что приводит к тому, что сервер заканчивает множеством подключений в состоянии TIME_WAIT. По умолчанию они остаются в этом состоянии в течение двух минут, но это очень редко вызывает проблемы. Соединения TIME_WAIT (в Linux) связывают комбинацию IP / порта, но вы не исчерпаете их, пока у вас не будет около 30 000 соединений в состоянии TIME_WAIT.


Диапазон исходных адресов в вашем правиле не соответствует IP-адресу в состоянии CLOSE_WAIT в вашем примере.

REJECT - это вежливо для вежливых людей, если по какой-то причине вы не можете принять их соединения, потому что это позволяет им немедленно закрыть соединение, но для хакеров / спамеров нет необходимости быть вежливыми. Заставьте их ждать установленного ими тайм-аута.


Ну и что жестяная банка вызывать соединения в состоянии CLOSE_WAIT? Клиент отправляет FIN, сервер отвечает FIN / ACK, а затем ожидает окончательного ACK. Если он так и не получил этот последний ACK, он застрянет там, пока не произойдет что-то еще, например, перезапуск Apache.

Это может быть вызвано плохим отслеживанием состояния соединения в другом коде (например, аппаратным брандмауэром), а также проблемами на стороне клиента. Я не мог понять, в чем причина вашей конкретной проблемы.