У меня есть веб-сервер (Ubuntu с Apache), работающий за Cloudflare. Я хочу заблокировать пользователя с помощью iptables. Здесь я хочу применить расширение iptables для поиска строк и отбрасывать соединение при совпадении x-forwarded-for. Я добавляю правило с помощью следующей команды:
iptables -I INPUT -m string --string "x-forwarded-for: 216.244.66.205" --algo bm --to 65535 -j DROP
После добавления этого правила клиент все еще может подключиться к серверу.
Я знаю о специфическом заголовке Cloudflare для IP клиента, а именно cf-connecting-ip. Если я добавляю правило с помощью следующей команды, оно работает, как ожидалось. Вот правило, которое работает нормально:
iptables -I INPUT -m string --string "cf-connecting-ip: 216.244.66.205" --algo bm --to 65535 -j DROP
Почему я хочу использовать XFF вместо cf-connecting-ip:
У меня есть отдельный балансировщик нагрузки (haproxy), и некоторые домены работают через него, а не через Cloudflare. Вот почему я хочу использовать XFF, потому что cf-connecting-ip специфичен для Cloudflare, а XFF поддерживается обоими.
Трафик с Cloudflare на веб-сервер - HTTP (порт 80), поэтому данные http видны iptables.
Я вижу, что Cloudflare правильно присоединяет заголовки cf-connecting-ip и XFF. Вот вывод tcpdump среди нескольких запросов:
tcpdump -A -s 65535 'tcp port 80' | grep 216.244.66.205
x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205 x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205 x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205 x-forwarded-for: 216.244.66.205 cf-connecting-ip: 216.244.66.205
Каким-то образом iptables может обнаружить cf-connecting-ip, но не x-forwarded-for.
Что я делаю не так?
Совпадение строк работает с полезной нагрузкой одного IP-пакета.
Таким образом, одной из возможных причин является то, что расположение заголовка x-forwarded-for:
находится на границе двух сегментов TCP. Следовательно, первый IP-пакет может содержать x-forw
, а второй IP-пакет — arded-for:
. Тогда модуль соответствия string
не соответствует ни одному пакету.
Чтобы проверить, является ли это причиной, просмотрите различные полезные нагрузки IP-пакетов, принадлежащие соединению, и посмотрите, как сегмент TCP разбивается на IP-пакеты.
Подобные блочные функции лучше всего реализовывать на уровне HTTP.