Как защитить веб-приложение от ботов IPv6?
Я заинтересован в этом в контексте защиты веб-приложения от ботов, но я думаю, что это применимо ко всем видам атак, которые могут быть выполнены с помощью ботов по IPv6.
В веб-приложении у вас есть несколько страниц, которые вы хотите защитить от ботов.
Это может быть страница входа в систему: вы хотите избежать миллионов запросов, пытающихся использовать комбинацию имени пользователя и пароля.
Это может быть страница регистрации. Вам не нужны тысячи аккаунтов ботов, созданных на вашем сайте.
Или, может быть, вы не хотите, чтобы весь контент вашей базы данных загружался сразу. Вы думаете, что для анонимного пользователя нормально делать 100 или 200 запросов в день к вашей базе данных, чтобы получить некоторую информацию, но вы не в порядке с ботами, загружающими весь контент, который вы предлагаете, выполняя 1000 запросов в минуту.
Или просто для статистических целей. Вы регистрируете активность посетителей на своем сайте, и вы не хотите, чтобы боты полностью смещали ваши данные, скажем, искусственно нажимая на ссылку тысячи раз, чтобы статья, на которую она ссылается, стала "самой популярной статьей" на вашем новостном сайте.,
Я часто обрабатывал это с помощью регулирования / ограничения скорости на основе IP-адресов, используя возможности ограничения скорости Nginx:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/m;
server {
location /sensitiveUrl {
limit_req zone=mylimit;
proxy_pass http://my_upstream;
}
}
Но с IPv6 я не уверен, насколько это эффективно. Я имею в виду, что с IPv4 это относительно эффективно, потому что злоумышленникам дорого создавать и использовать тысячи IP-адресов, но кажется, что с IPv6 любой может создать миллионы IP-адресов. Как справиться с этим? Должен ли я применять ограничения к сетям IPv6 вместо адресов? Насколько это будет эффективно на практике, если я это сделаю?
2 ответа
Гибкость IPv6 с адресацией великолепна, но она действительно усложняет такие вещи. Алгоритм, который я бы порекомендовал:
- Начните с блокировки отдельных адресов IPv6 (
/128
). Это может быть один пользователь в сети с несколькими пользователями, и вы хотите избежать блокировки невинных пользователей (что происходит с IPv4 все время из-за NAT, давайте не будем повторять это) - Если у вас есть больше, чем
x
блоки внутри того же/64
, предположим, что весь/64
испорчен и блокирует все это. Теперь вы можете удалить человека/128
записи из вашего черного списка, потому что они теперь охватываются/64
, Это предотвращает переполнение вашей системы черного списка памяти / хранилища. - Возможно, у злоумышленника больше одного
/64
, Размер по умолчанию/48
, но/56
и даже/60
(что слишком мало для IPv6, но некоторые интернет-провайдеры никогда не учатся). Я бы увеличил на 4 бита: если несколько/64
с того же/60
заблокированы, масштабировать, чтобы заблокировать все/60
, То же самое с несколькими/60
в/56
и т.п. - Я также рекомендовал бы использовать разные таймауты черного списка для разных длин префикса. Для одного пользователя проще случайно заблокировать
/64
чем для кого-то "случайно" получить целое/48
заблокирован. Большие блоки заслуживают более длительного времени в черном списке ИМХО. - Этот алгоритм может быть использован злоумышленником, распространяющим свою атаку на целое
/48
с самого начала, таким образом, не быстро запускать алгоритм масштабирования. Поэтому вам может потребоваться несколько параллельных условий для быстрого масштабирования.
Примером такого механизма масштабирования может быть:
+---------------+----------------------------------------+-----------+
| | Block when containing >= of these: | Blacklist |
| Prefix length | /128 | /64 | /60 | /56 | /52 | time |
+---------------+--------+-------+-------+-------+-------+-----------+
| /128 | N/A | N/A | N/A | N/A | N/A | 5 min |
| /64 | 5 | N/A | N/A | N/A | N/A | 15 min |
| /60 | 15 | 2 | N/A | N/A | N/A | 30 min |
| /56 | 50 | 4 | 2 | N/A | N/A | 60 min |
| /52 | 75 | 8 | 4 | 2 | N/A | 120 min |
| /48 | 100 | 16 | 8 | 4 | 2 | 240 min |
+---------------+--------+-------+-------+-------+-------+-----------+
Вы можете сделать действительно примитивное разбиение IP-подсетей с помощью регулярного выражения . Здесь я передаю адреса IPv4 без изменений, но захватываю первую половину адресов IPv6, которая соответствует префиксу /64 адреса. В результате nginx будет отслеживать ограничения скорости сразу по всему каталогу /64.
map $binary_remote_addr $masked_ip_addr {
# Extract the first half (the /64 prefix) of an ipv6 address
"~^(?P<a>........)........$" "$a";
# Extract the entire ipv4 address
"~^(?P<a>....)$" "$a";
}
limit_req_zone $masked_ip_addr zone=myzone:10m rate=1r/s;
server {
limit_req zone=myzone;
}