Для тех кого ддосят (Nginx+Fail2ban+NFT)

Станислав
На сайте с 27.12.2009
Offline
253
368

Читал тут как то тему где жаловались на какой то не понятный ддос, тупо грузят сервер http запросами с разных IP.

Меня так же эта хрень коснулась примерно года 2 назад.

По первости было плевать, потому как сервера выдерживали и все было отлично, к слову говоря сайтик у меня работает на 3х серверах.

1. Дохленькое облако под сам сайт + api для него

2. База данных

3. Файловый сервер

Из всего этого добра самое слабое место это база данных, при кучи запросов идет огромное потребление памяти и в итоге либо база грохается, либо сервер с базой зависает, ну и как следствие недоступность сайта от 2-10 минут.

Все что ниже напишу, это лишь мой личный опыт, при чем я далеко не профи в этом деле и тупо собирал информацию по крупицам и эксперементировал.


С одной стороны можно накинуть оперетивнки и процессор помощьнее взять, но это просто жесть как дорого, а с учетом того какие сегодня доходы приносит тот же РСЯ, так и в убыток придется работать.

История развивалась плавно и постепенно...

Началось все с того что моя база MongoDB начала грохаться, были мысли о том что идет какая то утечка памяти, на форумах из всех утюгов орали что у меня с софтом проблемы, угу.... Все оказалось намного проще, какой то китаеза начал заваливать сайт запросами, долбил он с передышками, 3-4 раза за сутки и так продолжалось очень долго.

Так как у меня сервер API работает под нодой, а именно логирование ведет pm2, было очень просто увидеть эти всплески спамного трафика и их IP.

Когда я впервые блокнул IP с которого шли запросы, спустя пару дней начали досить с разных IP, но с одной и той же подсетью. Блокнув подсеть, начали ддосить с других подсетей, при чем все с Китая, ну а когда забанил Китай, начали долбить с Сингапура, блок Сингапура как вы думаете к чему привел?

Правильно, начали долбить со вмего мира...

Моя аудитория на сайте это чисто русские, но так же и из за бугра в сутки порядка 1к заходит, нормальные ребята и поведенческие у них добротные, глупо банить их всех.

Решил настроить лимитку в nginx, чтобы переизбыток трафика бросать в ожидание, но есть проблемы, во время ддоса это конечно будет работать, только вот в лимитку будут попадать все без исключения, включая и ботов Яндекса и Гугла, поэтому самое простое решение что мне пришло в голову:

1. Настроить limit_req_zone в nginx

2. В nginx чекать "правильных/нужных" ботов

3. В nginx смотреть какой язык стоит в браузере пользователя, и сделать так чтобы limit_req_zone срабатывал только для указанных языков

4. Банить c помощью fail2ban весь этот шлак который подпадает под лимитку

К слову говоря на постояннку заносить все спамные IP я не стал, так как только за 1 сутки в последние дни fail2ban напушил в nftables более миллиона айпишников. Все конечно работало хорошо, но тупо память поджирала и постепенно расход памяти рос.

Данные по /etc/sysctl.conf

vm.vfs_cache_pressure=50
kernel.printk = 4 4 1 7
kernel.panic = 10
kernel.sysrq = 0
kernel.shmmax = 4294967296
kernel.shmall = 4194304
kernel.core_uses_pid = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
vm.swappiness = 20
vm.dirty_ratio = 80
vm.dirty_background_ratio = 5
fs.file-max = 2097152
net.core.netdev_max_backlog = 262144
net.core.rmem_default = 31457280
net.core.rmem_max = 67108864
net.core.wmem_default = 31457280
net.core.wmem_max = 67108864
net.core.somaxconn = 65535
net.core.optmem_max = 25165824
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
net.ipv4.neigh.default.gc_interval = 5
net.ipv4.neigh.default.gc_stale_time = 120
net.netfilter.nf_conntrack_max = 10000000
net.netfilter.nf_conntrack_tcp_loose = 0
net.netfilter.nf_conntrack_tcp_timeout_established = 1800
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 20
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 20
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 20
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.ip_no_pmtu_disc = 1
net.ipv4.route.flush = 1
net.ipv4.route.max_size = 8048576
net.ipv4.icmp_echo_ignore_all=1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.udp_rmem_min = 16384
net.ipv4.tcp_wmem = 4096 87380 33554432
net.ipv4.udp_wmem_min = 16384
net.ipv4.tcp_max_tw_buckets = 1440000
#net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 400000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 20
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.rp_filter = 1

По fail2ban, создаем /etc/fail2ban/jail.local

[nginx-limit-req]
port     = http,https
enabled  = true
logpath  = /var/log/nginx/*.errors.log
findtime = 30
bantime  = 30s
maxretry = 1
ignoreip  = 127.0.0.1/8
# configure nftables
banaction = nftables-multiport
banaction_allports = nftables-allports
chain     = input

Fail2ban будет смотреть в файлы логив nginx на предмет срабатывания лимита и банить на 30 секунд

Почему 

maxretry = 1

 Потому как при первом же сигнале нужно банить ip, ну и потому что дальше мы уже в nginx будет лимитку настраивать должным образом. Получает так что забугорный пользователь во время ддоса заходит на сайте, сайт делает 1 запрос в API, банится, а последующие 3-4 запроса попросту отваливаются, тем самым сервер базы данных задышал.

В /etc/nginx/nginx.conf в секцию http добавляем map который будет проверять правильный ли бот заходит на сайт

map $http_user_agent $is_search_bot {
        default                                                                                                                 "0";
        ~*(YandexBot|YandexMobileBot|Googlebot|GoogleOther|YandexMetrika|YandexAccessibilityBot|YandexRenderResourcesBot)       "1";
    }

Переменная $is_search_bot будет содержать 1 если это поисковой бот и его ограничивать не нужно, это нам понадобится в следующем мапе

map $is_search_bot:$http_accept_language $locale_bad_country {
        default         "";
        "~^0:zh"        "1";
        "~^0:en"        "1";
    }

$locale_bad_country - по умолчанию пропускает всех, но если это не бот и если язык в браузере zh или en, явно не русский и его будем банить в случае когда срабатывает $limit_req_zone, т.е. в то время когда нас ддосят.

Создаем файл /etc/nginx/conf.d/limit.conf

limit_req_zone $locale_bad_country zone=external:10m rate=500r/m;

О limit_req_zone понравилась статья _https://blog.rnds.pro/052-nginx-rate-limiting

Почитайте обязательно, не все так просто как кажется и нужно будет поиграться с цифрами в случае чего.

В самой секции location добавляем следующее

limit_req zone=external burst=500 delay=250;
limit_req_log_level warn;
limit_req_status 429;

Собственно таким вот методом избавился от этого ддоса, как только на той стороне поняли что весь трафик идет в труху и банится, тут же перестали.

Да, в то время когда идет ддос на сервер пользователи из за бугра так же будет банится на 30 секунд, все будут подпаать под раздачу, а вот основная ЦА будет пользоваться сайтом без каких либо задержек и банов.

Мы там, где рады нас видеть.
Delysid
На сайте с 27.05.2019
Offline
248
#1
Станислав :
Fail2ban будет смотреть в файлы логив nginx на предмет срабатывания лимита и банить на 30 секунд

 30 секунд 🤣

Тебе надо делать если 30 запросов в секунду то тогда включать и банился IP на более высокое время чем 30 сек. 😃

У меня сделано похожее, только сайт если много запросов в секунду идёт - защиту cloudflare включает автоматически.

А способ в статье, только от парсеров спасёт и от мамкиных хакеров. Дудосер грамотный по итогу всё равно канал заполнит и забьёт или отказами положит. 

Но как индикатор надвигающейся проблемы думаю можно использовать. 😁

serval
На сайте с 29.06.2011
Offline
205
#2
Станислав :
сервера выдерживали и все было отлично, к слову говоря сайтик у меня работает на 3х серверах.
Нам так не жить. Сервер обычного вебмастера обычно дохнет уже на 5 - 10 тысячах запросов в секунду.
L
На сайте с 25.12.2013
Offline
406
#3
Из бесплатных cloudflare позволяет очень эффективно фильтровать ботов. Это из личного опыта. Кроме этого там можно фильтровать, как сетки ботов, которые просто парсят сайт, создавая дикие нагрузки, так и фильтровать нежелательный трафф, фильтруя его по странам или кидая нежелательный трафф на капчу. Если посетители из нежелательных стран лезут тучами, то пускай ждут проверки от cloudflare и решают капу. То есть проблему по снижению нагрузки на сайт нужно решать комплексно, фильтруя весь нежелательный трафф и жестко блокируя ботов всяких сервисов.
Недорогой, надежный и отзывчивый VPS хостинг ( https://bit.ly/3eXUnNN ) Проверенная пуш партнерка с ежедневными выплатами ( https://vk.cc/9wLSrL)
Станислав
На сайте с 27.12.2009
Offline
253
#4
Delysid #:

 30 секунд 🤣

Тебе надо делать если 30 запросов в секунду то тогда включать и банился IP на более высокое время чем 30 сек. 😃

У меня сделано похожее, только сайт если много запросов в секунду идёт - защиту cloudflare включает автоматически.

А способ в статье, только от парсеров спасёт и от мамкиных хакеров. Дудосер грамотный по итогу всё равно канал заполнит и забьёт или отказами положит. 

Но как индикатор надвигающейся проблемы думаю можно использовать. 😁

Да 30 секунд, это чисто часный случай, и 30 секукнд мне по факту даже много. Как писал ранее одно обращение на страницу сайта = 4-5 запросов в базу, мне по факту можно даже и на 5 сек блокнуть и будет все работать. К тому же каждое новое обращение было с нового IP,  за двое суток ниразу IP не повторялся, смысл хранить шлак на сервере...

Грамотный дудосер херней не занимается, если платят то ддосит, платить за топку конкурента в не комменрции такое себе удовольствие, поддосит день другой и угомонится =)

L
На сайте с 25.12.2013
Offline
406
#5
Станислав #:
Грамотный дудосер херней не занимается, если платят то ддосит, платить за топку конкурента в не комменрции такое себе удовольствие, поддосит день другой и угомонится =)

Дидоссеры кладут целые дата-центры по заказу, твои мелкие сайты им точно не интересны.

Станислав
На сайте с 27.12.2009
Offline
253
#6
Lastwarrior #:

Дидоссеры кладут целые дата-центры по заказу, твои мелкие сайты им точно не интересны.

Ну может кто то ходит на утку с гранатаметом =)

Vladimir
На сайте с 07.06.2004
Offline
587
#7
Станислав #:

Ну может кто то ходит на утку с гранатаметом =)

гранатомет позволяет расщепить утку на мелкие части и встроить нужный код и тд.
Именно в этом больше интерес ( с миллиона сайтов получить траф или другой эффект), а не положить дата центр на заказ. Т.е желающих получить халяву миллионы, и только один идиот на дата центр
Аэройога ( https://vk.com/aeroyogadom ) Йога в гамаках ( https://vk.com/aero_yoga ) Аэройога обучение ( https://aeroyoga.ru ) и просто фото ( https://weandworld.com )
L
На сайте с 25.12.2013
Offline
406
#8
Vladimir #:
Именно в этом больше интерес ( с миллиона сайтов получить траф или другой эффект), а не положить дата центр на заказ.

Для этого не обязательно бомбить серверы обычных пользователей миллионами запросов в минуту. Достаточно долбить миллионы серверов по всему миру в спокойном режиме, не привлекая внимания санитаров. Когда заходишь через root, то сразу же видно, сколько раз пытались зайти на твой сервер методом подбора пароля. 

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий