Върху картата на атаките има плътно петно над една държава и от само себе си се налага правилото „да се забрани изцяло“. То няма да даде почти нищо: смяната на държавата на изход струва на нападателя няколко минути, а под забраната ще попаднат вашите собствени посетители и вие самите по време на пътуване. По-лошото е, че видим обхождащ робот от един облак след блокирането ще се премести на домашни адреси и ще стане неразличим от хората.

По-долу са пет стъпки, които на същия сървър наистина дават резултат: да се отрежат скенерите, да се ограничи темпото, да не се отреже нужното и — ако все пак се налага — да се блокира правилно. Всичко се проверява и настройва за едно сядане.

Стъпка 1. Да се види кой точно създава петното

Първо намерете дневника на заявките. На сървър с няколко сайта access.log нерядко е празен, а записите отиват в дневника на съответния виртуален хост:

sudo ls -lS /var/log/apache2/*access*.log /var/log/apache2/*requests*.log 2>/dev/null

Във всички следващи команди се подставя файлът, който е излязъл най-отгоре в този списък. Първо водещите адреси за денонощието, после какво точно иска онзи, който е най-горе:

sudo awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20
sudo grep '^203\.0\.113\.' /var/log/apache2/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

Втората команда отговаря на главния въпрос. Ако в изхода има десетки различни страници на вашия сайт, това е събирач на съдържание: безвреден е и е достатъчно да не го броите за посетител. Ако там са /wp-login.php, /.env, /phpmyadmin и други неща, които нямате, това е скенер и с него се занимава стъпка 2. При nginx дневниците са в /var/log/nginx/, полетата са същите.

Стъпка 2. Jail срещу заявки към това, което нямате

Пътят на заявката не може да се подправи — именно той е намерението, за разлика от адреса и User-Agent. Филтърът /etc/fail2ban/filter.d/web-probes.local:

[Definition]
failregex = ^<HOST> .* "(GET|POST|HEAD) /(wp-login\.php|wp-admin|xmlrpc\.php|\.env|\.git/|phpmyadmin|administrator/)
ignoreregex =

Jail-ът /etc/fail2ban/jail.d/web-probes.local:

[web-probes]
enabled  = true
port     = http,https
filter   = web-probes
logpath  = /var/log/apache2/*access.log
maxretry = 1
findtime = 1h
bantime  = 1d

Тук maxretry = 1 е оправдано: случайни обръщения към чужд административен панел няма. Прилагане и проверка, че филтърът улавя записи във вашия дневник:

sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/web-probes.local
sudo systemctl reload fail2ban && sudo fail2ban-client status web-probes

Стъпка 3. Да се ограничи темпото

Скенерът и обхождащият робот се издават със скоростта си, независимо от коя държава идват. Тридесет страници в минута от един адрес е праг, който не засяга човек, прелистващ каталог:

[http-flood]
enabled  = true
port     = http,https
filter   = apache-overflows
logpath  = /var/log/apache2/site_access.log
maxretry = 30
findtime = 60
bantime  = 1h

Ключовата подробност е кой дневник е посочен в logpath. Ако под маската попадне дневникът на самия панел за управление или на административната част, ще блокирате себе си: една негова страница води след себе си десетина заявки към стилове и скриптове, а тридесет се събират за два клика. Затова на панела се дава отделен файл за дневник, който не съвпада с маската на jail-а, а на статичните файлове се задава дълъг срок на кеширане, за да не ги заявява браузърът наново при всяко преминаване. Признакът, ако все пак се е случило: HTML пристига, оформлението не, страницата виси. Сваляне на блокирането:

sudo fail2ban-client set http-flood unbanip 203.0.113.10

Стъпка 4. Да се защити това, което не бива да се отрязва

Преди да включите блокиранията, впишете изключенията — иначе първо под тях ще попадне нужното:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24 66.249.64.0/19

Какво задължително трябва да има в този ред и защо:

  • Вашият собствен адрес или подмрежата на офиса. Най-честата причина за загуба на достъп до сървъра е собственото правило, а не атака;
  • Диапазонът 66.249.64.0/19. Търсещият робот на Google се разпознава по User-Agent, но онази негова част, която изпълнява JavaScript, идва с обикновен Chrome/Linux и не се представя. Всяко правило от рода на „да се блокира трафикът от центрове за данни“ засяга именно нея, след което страниците тихо изпадат от индекса. Подозрителен адрес може да се провери с обратна заявка: dig -x 66.249.66.1 +short трябва да върне име в зоната googlebot.com;
  • Адресите на известията за плащания. Webhook-овете на платежните системи идват от сървъри на AWS и Azure. Ако затворите тези облаци изцяло, потвържденията за плащания ще спрат да стигат и ще разберете за това тогава, когато клиент напише, че парите са удържани, а достъп няма. Диапазоните се вземат от документацията на вашия доставчик на плащания.

Стъпка 5. Ако блокирането все пак е нужно — блокирайте подмрежа, а не държава

Устойчиво сгъстяване от една мрежа, което се задържа с дни и е съпроводено от еднотипни заявки, е един изпълнител, който върви по списък. Такъв случай се блокира точково и за определено време:

sudo ufw deny from 198.51.100.0/22 to any
sudo ufw status numbered

С втората команда запомнете номера на правилото: блокирането ще трябва да се свали именно чрез него, sudo ufw delete <номер>. Договорете се със себе си за срок — например месец — и запишете свалянето в календара. Правила, поставени „завинаги“, след година се превръщат в списък, който никой не смее да пипне, защото никой не помни заради какво тези адреси са попаднали там.

Коя подмрежа да блокирате, може да се разбере по адреса от първата стъпка: whois 198.51.100.17 | grep -iE 'route|cidr|netname'.

Какво се променя след тези пет стъпки

Скенерите се отрязват по намерение, а не по произход, и се улавят от първата заявка. Обхождащите роботи се опират в ограничението на темпото. Търсещият робот и известията за плащания продължават да минават. Единственото блокиране, което е останало широко, е точково, с известен срок и разбираема причина.

Картата при това не изчезва, но ролята ѝ се променя: тя е нужна не за да затваря държави, а за да забележи самото сгъстяване и да го сравни с това отпреди седмица. За това е нужна история, а не снимка на текущото денонощие. Как изглежда такава карта заедно с дневника на блокиранията и списъка на отворените портове, показват демонстрационните страници по-долу.