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

Отбрасывание входящих запросов для определенного файла с помощью iptables

Сервер представляет собой стандартный стек LAMP, настроенный через cpanel в CentOS 5.9.

У нас есть один файл, назовите его bad.php, на одном из наших доменов, к которому поставщик услуг по ошибке обращается примерно 10 раз в секунду. Файл больше не существует, и мы хотим заблокировать эти запросы наиболее эффективным способом. В настоящее время мы возвращаем 410 простых ответов, но это все еще связано с связыванием потоков apache, отправкой заголовков и т. Д.

В идеале я хочу просто отбросить запросы, не отправляя никакого ответа. Блокировка по IP не является вариантом, потому что нам нужно разрешить этим IP-адресам законный доступ к другим файлам. (И нет, мы не можем просто попросить их остановиться.) У нас также нет внешнего брандмауэра для работы (арендованный сервер, настраиваемый внешний брандмауэр оплачивается дополнительно).

Я считаю, что лучшим вариантом было бы такое правило iptables:

iptables -I INPUT -p tcp --dport 80 --destination [ip address] -m string \
    --algo kmp --string "bad\.php" -j DROP

Два вопроса:

Сначала я попробовал это правило (с IP-адресом домена вместо IP-адреса), но это не дало результата. Это было самое первое правило, показанное с помощью iptables -L, поэтому его не следует отменять более ранним правилом:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  anywhere             [ip address]       tcp dpt:http STRING match "bad\.php" ALGO name kmp TO 65535

Я где-то напортачил? Я в большой степени новичок в iptables.

Второй вопрос: есть ли предостережения по этому поводу? Возникнут ли значительные накладные расходы, если строка iptables будет соответствовать каждому запросу (по сравнению с apache RewriteRule с R = 410, как мы сейчас используем)? Мне лучше просто жить с этим? Или есть вариант получше? (Возможно, mod_security?) Сервер нигде не напрягается, так что это не необходимость, а просто оптимизация.

Редактировать в ответ на Саураба Барджатию:

Вот все, что я вижу из tcpdump, когда делаю запрос на файл bad.php:

20:21:09.740217 IP [clientIP].62790 > [serverIP].http: S 3454863895:3454863895(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
20:21:09.740243 IP [serverIP].http > [clientIP].62790: S 4112555138:4112555138(0) ack 3454863896 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
20:21:09.838595 IP [clientIP].62790 > [serverIP].http: . ack 1 win 16425
20:21:09.838606 IP [clientIP].62790 > [serverIP].http: . 1:1461(1460) ack 1 win 16425
20:21:09.838622 IP [serverIP].http > [clientIP].62790: . ack 1461 win 69
20:21:09.838632 IP [clientIP].62790 > [serverIP].http: P 1461:1476(15) ack 1 win 16425
20:21:09.838638 IP [serverIP].http > [clientIP].62790: . ack 1476 win 69

Очевидно, фактической строки URL-адреса здесь нет. Насколько я понимаю, iptables жестяная банка фильтр для строк URL-адресов, поэтому, по-видимому, я проверяю не то.

Предполагается, что правило iptables будет использовать больше ЦП, чем конфигурация apache. Но, тем не менее, использование iptables для блокировки входящих запросов интересно. Поскольку запросы не заархивированы и обычно находятся в одном пакете, я не вижу никаких возражений против вашей логики.

Чтобы понять, почему текущее правило не работает, у меня есть два предложения:

  1. Удалите -d на время и посмотрите, работает ли правило. Вы могли совершить глупую ошибку при интерпретации IP-адреса назначения
  2. Захватывайте пакеты с помощью tcpdump или wirehark и анализируйте их, чтобы увидеть строки, которые вы можете сопоставить в запросах для bad.php. Это также поможет проверить, что все запросы bad.php действительно содержат bad.php, как и ожидалось. Иногда локальные правила перезаписи могут приводить к тому, что запросы переходят на bad.php, в то время как исходный запрос в пакете предназначен для good.php, что приводит к сбою правила iptables.