Почему iptables не блокирует IP-адрес? (Версия LB / прокси)

ВНИМАНИЕ: Долго. Здесь много информации.

3 года назад кто-то спросил Почему iptables не блокирует IP-адрес? , и оказалось, что причина в том, что серверы стояли за CloudFlare, что делало невозможным блокировать IP-адреса напрямую, как они хотели если вы не используете его по-другому. Любой обратный прокси-сервер или балансировщик нагрузки вызовут то же самое.

Точно так же мы настроили fail2ban с правилом для запрета любых ботов, которые пытаются подобрать себе путь к административному входу или спаму xmlrpc. Сайт находится за балансировщиком нагрузки, поэтому очевидно, что мы не можем напрямую запретить IP-адрес, но предполагается, что iptables принимает соединение и шаблон, соответствующий пакетным данным, для запрета определенного трафика.

Это конфигурация fail2ban jail.conf:

[wp-auth] 
enabled = true
filter = wp-auth
action = iptables-proxy[name = lb, port = http, protocol = tcp]
         sendmail-whois[name=LoginDetect, dest=ITemail@ourdomain.com, sender=acceptablebotbot@ourdomain.com, sendername="Fail2Ban"]
logpath = /obfuscated/path/to/site/transfer_log
bantime = 604800
maxretry = 4
findtime = 120

Это простое соответствие шаблону для запросов wp-login:

[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreip = # our ip address

Это наше действие fail2ban iptables, которое, как предполагается, может блокировать этих ботов, но по большей части этого не делает. Это из раздела советов сайта CentOS для fail2ban за прокси . Для краткости я оставил только комментарии заголовка раздела.

# Fail2Ban configuration file
#
# Author: Centos.Tips
#

[INCLUDES]

before = iptables-blocktype.conf

[Definition]

# Option:  actionstart
actionstart = iptables -N fail2ban-<name>
              iptables -A fail2ban-<name> -j RETURN
              iptables -I <chain> -p <protocol> --dport <port> -j fail2ban-<name>

# Option:  actionstop
actionstop = iptables -D <chain> -p <protocol> --dport <port> -j fail2ban-<name>
             iptables -F fail2ban-<name>
             iptables -X fail2ban-<name>

# Option:  actioncheck
actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'

# Option:  actionban
actionban = iptables -I fail2ban-<name> 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP

# Option:  actionunban
actionunban = iptables -D fail2ban-<name> -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP

[Init]
# Default name of the chain
name = default

# Option:  port
port = http

# Option:  protocol
protocol = tcp

# Option:  chain
chain = INPUT    

Итак, как я уже упоминал, сайт находится на паре серверов за эластичным балансировщиком нагрузки и, похоже, работает в тесте. Мы можем добавить любой из наших IP-адресов, и мы не сможем получить доступ к сайту. Несмотря на это, боты, похоже, могут пройти.

[root:~/] iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-SSH
-N fail2ban-lb
-A INPUT -p tcp -m tcp --dport 80 -j fail2ban-lb
-A INPUT -p tcp -m tcp --dport 22 -j fail2ban-SSH
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 5666 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 24007:24020 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A fail2ban-SSH -j RETURN
-A fail2ban-lb -p tcp -m tcp --dport 80 -m string --string "X-Forwarded-For: 91.200.12.33" --algo bm --to 65535 -j DROP
-A fail2ban-lb -p tcp -m tcp --dport 80 -m string --string "X-Forwarded-For: 91.134.50.10" --algo bm --to 65535 -j DROP
-A fail2ban-lb -p tcp -m tcp --dport 80 -m string --string "X-Forwarded-For: 160.202.163.125" --algo bm --to 65535 -j DROP
-A fail2ban-lb -p tcp -m tcp --dport 80 -m string --string "X-Forwarded-For: 162.243.68.232" --algo bm --to 65535 -j DROP
-A fail2ban-lb -j RETURN

Порт 80 - единственный порт, открытый для всех. Все остальные находятся в ACL через группы безопасности AWS. Кажется, что IPtables обрабатываются в правильном порядке и поэтому должны блокировать эти IP-адреса на основе их заголовка X-Forwarded-For. Существует плагин Firefox, который позволяет вам отправлять эти заголовки с начальными запросами, и в результате мы также блокируемся с любым из этих IP-адресов ботов.

Исходный IP-адрес, похоже, не подделывает X-Forwarded-For заголовок, с которым мы играли, поскольку ELB все равно их переписывает. tcpdump не показывает никакой дополнительной информации о пакете на уровне сервера.

22:07:14.309998 IP ip-10-198-178-233.ec2.internal.11054 > ec2-10.4.8.71.http: Flags [P.], seq 2545:3054, ack 19506, win 166, options [nop,nop,TS val     592575835 ecr 2772410449], length 509
E..1..@.@..9
...
f.p+..P.Nz.
20............
#Q.[.?.QPOST /wp-login.php HTTP/1.1
host: www.thiswebsite.com
Accept: */*
Accept-Language: zh-cn
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
Referer: http://www.thiswebsite.com/wp-login.php
User-Agent: Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
X-Forwarded-For: 91.200.12.33
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Content-Length: 21
Connection: keep-alive

Все эти запросы регистрируются в журнале transfer_log. Когда мы делаем то же самое и создаем X-Forwarded-For, мы попадаем в ловушку iptables еще до того, как достигнем Apache. tcpdump также показывает наши дополнительные IP-адреса.

20:10:25.378873 IP ip-10-198-178-233.ec2.internal.11054 > ec2-10.4.8.71.http: Flags [P.], seq 3157:3860, ack 124583, win 267, options [nop,nop,TS     val 526293643 ecr 2507283790], length 703
E...Tf@.@.[.
...
f.p,O.P...GU........m.....
.^...r.QPOST /wp-login.php HTTP/1.1
host: www.thiswebsite.com
Accept: /
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Cache-Control: no-cache
Cookie: __utma=190528439.16251225.1476378792.1478280188.1478289736.3; __utmz=190528439.1476378792.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);     _icl_current_language=en; __utmc=190528439; __utmb=190528439.2.10.1478289736; __utmt=1
Pragma: no-cache
Referer: http://www.thiswebsite.com/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0
X-Forwarded-For: 91.200.12.33, <our ip address>
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Connection: keep-alive

У меня также есть журнал доступа ELB, для которого я ожидаю увидеть запись, но не журналы передачи Apache.

2016-11-07T22:07:14.309917Z mLB 91.200.12.33:60407 10.4.8.71:80 0.000079 1.99244 0.000091 200 200 21 3245 "POST http://www.thiswebsite.com:80/wp-login.php HTTP/1.1" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)" - -

Таким образом, IP-адрес (по крайней мере, согласно ELB) соответствует не похоже, что на уровне X-Forwarded-For. Почему трафик с него не блокируется? IP-адрес также постоянно отображается в журнале fail2ban, как обычно:

fail2ban.actions[11535]: INFO [wp-auth] 91.200.12.33 already banned
4
задан 13 April 2017 в 15:14
2 ответа

Похоже, что fail2ban на самом деле не создает новые правила, как вы думаете. Когда вы видите сообщение «уже забанен», выполняете ли вы команду «iptables -L» и видите желаемое правило? Сообщение «уже заблокировано» означает, что ваше обнаружение работает, а ваш брандмауэр - нет. Если вы видите правило, но оно не работает, это означает, что что-то в правиле не работает, и вам нужно переосмыслить правило.

Ваши failregex и ignoreip говорят мне, что вы просто хотите заблокировать всех, кто не работает. t с ваших IP-адресов. Это звучит намного проще, чем использование fail2ban.

На самом деле, нужен ли вашей консоли администратора балансировщик нагрузки? 99% трафика на этот сайт должны быть злоумышленниками, пытающимися взломать. Если вы знаете, какие адреса разрешить, а ваши failregex и ignoreip указывают на то, что вы это делаете, вы можете просто сделать консоль администратора доступной напрямую, но только для разрешенных IP-адресов.

Ой, это не через SSL? Если это так, iptables не сможет прочитать заголовок X-Forwarded-For.

Мне очень нравится идея HBruijn об использовании API cloudflares. Они должны выполнять блокировку, а не вы.

Наконец, если вы решите выполнить фильтрацию на уровне apache, в mod_rewrite есть карты перезаписи , которые отлично подходят для этого. Функции dbd и prg позволяют изменять сопоставление без перезапуска apache.

Надеюсь, что некоторые из них помогут

-Dylan

0
ответ дан 3 December 2019 в 03:54

Ваши правила для iptables выглядят прекрасно. Невозможно точно сказать, что они передают, однако, без протоколирования принимает. Tcpdump не скажет вам этого, потому что он работает на входе до запуска iptables. Так как вам нужен балансировщик нагрузки, iptables-accept logs для порта 80, скорее всего, создаст очень большие файлы, которыми вам нужно будет аккуратно управлять (для использования диска), и вам понадобятся скрипты или другие инструменты для их анализа. Однако, это то, что вам нужно будет сделать, чтобы выяснить, через что вы проходите.

Однако, что я могу сказать вам из вышесказанного, так это то, что существует неотъемлемая проблема утечки при использовании сетевых пакетов для фильтрации на уровне приложений. Границы пакетов не уважают границы приложений, поэтому в среде с высоким уровнем атак некоторые из этих запросов будут утечканы. Это статистический эффект. При достаточном количестве запросов, направленных к Вашей системе, возрастает вероятность того, что некоторые из них будут разбиты более чем на один пакет. Только это может объяснить утечку. Хакеры могут наклонять шансы в свою пользу, вставляя заголовки, которые увеличивают размер пакета. Но одного только объема достаточно.

Для тщательной фильтрации необходимо фильтровать на уровне приложения. Apache предоставляет несколько механизмов для этого. Вы можете блокировать пользователей, идентифицированных fail2ban с помощью правила .htaccess для X-Forwarded-For. Вы также можете фильтровать в своей директиве Location. Я не вижу ни опции для этого в fail2ban, ни отдельной утилиты, которая делает это, но пользовательский сценарий для синхронизации fail2ban jail-ees с apache фильтром будет одним из способов реализации фильтра на прикладном уровне.

Еще одно соображение: Вы разместили правила для IPv4. Если вы принимаете IPv6 соединения на 80 порту, вы должны убедиться, что эти правила также поддерживаются.

.
2
ответ дан 3 December 2019 в 03:54

Теги

Похожие вопросы