Я запускаю веб-сайт, который технически действует как прокси для другого веб-сайта (я делаю к нему HTTP-запросы), и мне нужно было убедиться, что было сделано не слишком много одновременных подключений, поэтому я ограничил его до 29 одновременных подключений с iptables:
iptables -A OUTPUT -p tcp --dport 80 -m state --state NEW -m connlimit --connlimit-above 29 -j REJECT
Это единственное правило, которое я использую помимо правила по умолчанию INPUT ACCEPT
/ FORWARD ACCEPT
/ OUTPUT ACCEPT
.
Я протестировал это правило на другом моем сервере и увидел только 29 соединений в iptables на этом другом сервере.
Тем не менее, другой веб-сайт, на котором я проксирую, сообщил мне, что они видели 1499 одновременных подключений на пике. Вот это да. Это сделало их сайт нестабильным, и им пришлось заблокировать IP-адрес моего сервера, что, по их словам, вернуло их веб-сайт к стабильности.
Примечание: этот сайт имеет точку DNS для двух IP-адресов, но 1499 намного больше, чем 29 × 2.
Я использую стабильный Debian, nginx и php, и соединения выполняются через функции PHP cURL. Я не использую соединения повторно, потому что PHP делает это невозможным благодаря своей реализации cURL.
Вопрос: Как это возможно? Это вообще возможно? Любая идея?
Лучшая теория, которая у меня есть (которая кажется мне невозможной, если только они не будут делать какие-то действительно забавные вещи), заключается в том, что каким-то образом запросы закрываются на моем сервере, но не на их.
Я думаю, твоя догадка на правильном пути. Соединение находится в состоянии NEW только до тех пор, пока не получит ACK с другого конца. Вы говорите: «разрешать только 29 SYN без ACK из порта 80 за раз». Таким образом, ваше правило ограничивает количество ОЖИДАЮЩИХСЯ подключений до 29, но после его установления ограничений нет.
Если другая сторона своевременно отправляет обратно ACK, то те соединения, которые их получили, больше не находятся в состоянии «NEW» и, следовательно, не учитываются в лимите.
Возможно, стоит протестировать, отбросив фильтр --state и добавив пункт назначения. Таким образом, вы ограничиваете скорость всех подключений к $ DESTINATION_SERVER: $ DESTINATION_PORT независимо от состояния. Это могло подтвердить вашу догадку.