Ви встановили Fail2ban. Ви увімкнули SSH jail. Ви навіть бачили, як хтось безупинно б’є по порту 22. І все одно: ніхто не баниться. Немає записів у брандмауері. Немає задовольняючих лічильників «banned». Лише тиша.
У продакшні тиша рідко означає, що все добре. Зазвичай це пропущена телеметрія, неправильний бекенд, невідповідна родина брандмауера або jail, який ніколи не зіставив жодного рядка. Виправлення — це не «перевстановити Fail2ban» (це забере вам півдня). Виправлення — це верифікація: доведіть шлях даних, доведіть збіг, доведіть бан і доведіть, що бан застосовується.
Швидка діагностика: план дій
Якщо ви на виклику, почніть тут. Це послідовність «знайти вузьке місце за п’ять хвилин». Вона субʼєктивна, бо альтернатива — блукати по конфігураціях, поки атаки тривають.
По-перше: чи живий Fail2ban і чи спостерігає він за тим jail, який ви очікуєте?
- Перевірте стан сервісу та останні помилки в journalctl.
- Перелічіть увімкнені jails і перевірте, що ваш цільовий jail присутній.
По-друге: чи бачить він події (логи) і чи збігає їх (фільтри)?
- Підтвердіть бекенд (systemd journal vs файлові логи).
- Підтвердіть, що джерело логів містить очікувані рядки про помилки аутентифікації.
- Запустіть тест regex проти відомих рядків логів.
По-третє: чи намагається він забанити і чи застосовуються бани?
- Примусово забануйте тестовий IP і перевірте, чи зʼявляються правила брандмауера.
- Підтвердьте, що ви використовуєте nftables або iptables і що Fail2ban налаштований відповідно.
- Підтвердьте дію, вибрану в jail, і що «family» брандмауера відповідає реальності системи.
Найпоширеніший режим відмови на сучасному Ubuntu — це не сам Fail2ban. Це невідповідність між тим, де живуть логи (systemd-journald vs файли), і тим, який шар брандмауера фактично активний (nftables vs iptables-legacy). Fail2ban не може заборонити те, чого не бачить, і не може блокувати те, що не може запрограмувати.
Ментальна модель: події → збіги → бани → застосування
Fail2ban простий так само, як детектор диму: він слухає, розпізнає шаблон і виконує дію. Якщо ви поставите його в неправильну кімнату або батарейки сіли, він «працює» з вражаючим спокоєм.
Думайте у чотирьох шарах:
- Події: зʼявляються спроби аутентифікації, деінде (файл типу
/var/log/auth.logабо systemd journal). - Збіги: фільтр jail’а через regex знаходить ці рядки й рахує невдалі спроби на IP за вікном часу.
- Бани: коли пороги перевищені (findtime/maxretry), Fail2ban вирішує забанити IP.
- Застосування: дія вставляє правила в брандмауер (nftables або iptables) або повідомляє сервіс (наприклад, ACL аплікації) заблокувати доступ.
Коли Fail2ban «нічого не банить», не вгадуйте шар, який провалився. Доведіть це. На практиці:
- Немає подій: неправильне джерело логів, права, або сервіс логуватись в іншому місці (логи контейнера, syslog вимкнено тощо).
- Є події, але немає збігів: неправильний фільтр, невірний jail, інший формат логів або сервіс не генерує рядки, які очікує фільтр.
- Є збіги, але немає банів: пороги занадто високі, ignoreip покриває все, часові налаштування неправильні або jail не увімкнено.
- Є бани, але немає застосування: неправильна дія, неправильний бекенд брандмауера, конфлікт менеджера брандмауера або порядок правил робить ваш «блок» неефективним.
Парафразована ідея (Gene Kim): «Надійність приходить від швидкого зворотного звʼязку і малих, зворотних змін». Саме це і є цей робочий процес: короткі петлі зворотного звʼязку, які дозволяють припинити гадання.
Цікавинки й контекст (швидко, корисно, іноді nerdy)
- Fail2ban передує епосі хмар. Він почався на початку 2000-х, коли SSH brute force і FTP password spraying були фоновим шумом Інтернету.
- Він не «виявляє атакуючих». Він виявляє шаблони в логах. Якщо атакуючий уникає генерації очікуваних логів (або атакує ендпоінт, який ви не моніторите), Fail2ban залишиться ввічливо неінформованим.
- Першочерговою ціллю був iptables. Екосистема поступово перейшла на nftables; сьогодні Linux-брандмауери часто працюють через nftables навіть коли ви вводите «iptables».
- systemd-journald змінив гру з логами. В деяких налаштуваннях
/var/log/auth.logприсутній; в інших журнал є канонічним джерелом. Fail2ban може читати обидва, але ви маєте вибрати правильно. - «iptables» може означати кілька речей. Є iptables-legacy і iptables-nft. Імʼя команди однакове, бекенд різний, і правила можуть опинятися там, де ви не дивитесь.
- Uncomplicated Firewall (UFW) — це шар політик. Раніше він під капотом використовував iptables; на новіших системах може інтегруватися з nftables. Fail2ban може співіснувати з UFW, але важливим є порядок правил.
- IPv6 — тихий тригер проблем. Якщо ваш сервіс доступний через IPv6, а ви бланкуєте лише IPv4, ваш «бан» буде лише перешкодою, а не блоком.
- DNS та зворотні запити можуть затримувати бани. Якщо увімкнути функції, що викликають повільні DNS-операції в бандінговому пайплайні, ви можете отримати дивну поведінку «бан через години».
Жарт #1: Fail2ban не «не працює». Він працює точно так, як налаштовано — що в 03:00 звучить не дуже заспокійливо.
Робочий процес верифікації: практичні завдання з командами, значенням, рішеннями
Це серцевина статті: реальні перевірки в логічному порядку з «що це означає» і «що робити далі». Запускайте їх на хості, де встановлено Fail2ban.
Завдання 1 — Підтвердити, що Fail2ban справді запущений (і не флапає)
cr0x@server:~$ systemctl status fail2ban --no-pager
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Sun 2025-12-28 09:12:19 UTC; 1h 7min ago
Docs: man:fail2ban(1)
Main PID: 1247 (fail2ban-server)
Tasks: 5 (limit: 19020)
Memory: 39.8M
CPU: 1.421s
CGroup: /system.slice/fail2ban.service
└─1247 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
Що це означає: «active (running)» — базова вимога. Якщо стан «failed» або сервіс перезапускається, бани не закріпляться й jails можуть ніколи не завантажитись.
Рішення: Якщо сервіс нестабільний, одразу перейдіть до Завдання 2 (помилки в journal) перед тим, як торкатись конфігів.
Завдання 2 — Прочитати останні помилки/попередження від Fail2ban
cr0x@server:~$ journalctl -u fail2ban -n 200 --no-pager
Dec 28 09:12:19 server fail2ban-server[1247]: Server ready
Dec 28 10:01:07 server fail2ban-server[1247]: WARNING Found no accessible config files for 'filter.d/sshd'. Skipping...
Dec 28 10:01:07 server fail2ban-server[1247]: ERROR Unable to read the filter 'sshd'
Що це означає: Fail2ban прямо каже, що не може завантажити фільтр, відкрити лог, поговорити з брандмауером або прив’язати свій сокет. Повірте йому.
Рішення: Виправте точну помилку з файлом/правами спочатку. Не «тюньте bantime», поки jail не завантажується.
Завдання 3 — Перелічити запущені jails (ті, що Fail2ban фактично завантажив)
cr0x@server:~$ sudo fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: sshd, nginx-http-auth
Що це означає: Якщо очікуваного jail немає в списку, він не запущений. Крапка.
Рішення: Якщо jail відсутній, перевірте конфіг у Завданні 4 і перевірте увімкнення в файлі jail. Якщо немає jail — немає бану.
Завдання 4 — Перевірити парсинг конфігурації без гадань
cr0x@server:~$ sudo fail2ban-client -d
...snip...
Jail sshd: backend = systemd
Jail sshd: enabled = true
Jail sshd: maxretry = 5
Jail sshd: findtime = 600
Jail sshd: bantime = 3600
Jail sshd: action = nftables[type=multiport]
...snip...
Що це означає: -d виводить обчислену конфігурацію після include’ів. Саме тут ви знаходите «я відредагував jail.conf, але jail.local його перекриває» та інші класичні проблеми.
Рішення: Якщо бекенд/дія/шляхи не такі, як очікуєте, зупиніться і виправте перекриття. Не відлагоджуйте хибну реальність.
Завдання 5 — Інспектувати статус конкретного jail (це ваш табло)
cr0x@server:~$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 1
| |- Total failed: 44
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
Що це означає: «Total failed» що зростає — означає, що читаються логи й є збіги. «Total banned», що стоїть на нулі — означає, що або пороги не досягнуті, або ignore правила зловили все, або дія терпить поразку.
Рішення: Якщо «File list» вказує на файл, якого немає або який ви не використовуєте (часто на системах із journal), переходьте до Завдань 6–8.
Завдання 6 — Підтвердити, де логуються помилки аутентифікації на Ubuntu 24.04
cr0x@server:~$ ls -l /var/log/auth.log
-rw-r----- 1 syslog adm 148322 Dec 28 10:18 /var/log/auth.log
Що це означає: Якщо /var/log/auth.log існує і оновлюється, файловий бекенд може працювати. Якщо файл відсутній або застарілий, ймовірно, вам потрібен systemd бекенд.
Рішення: Якщо відсутній/застарілий, використайте Завдання 7, щоб підтвердити, що журнал має події, і тоді налаштуйте backend = systemd для jail.
Завдання 7 — Доведіть, що помилки є в journal
cr0x@server:~$ sudo journalctl -u ssh --since "30 min ago" --no-pager | tail -n 20
Dec 28 10:09:41 server sshd[3188]: Failed password for invalid user admin from 203.0.113.90 port 49152 ssh2
Dec 28 10:09:44 server sshd[3188]: Failed password for root from 203.0.113.90 port 49153 ssh2
Що це означає: Система має докази, потрібні Fail2ban. Тепер треба переконатися, що jail читає те ж джерело.
Рішення: Якщо журнал має записи, але «File list» у статусі jail показує /var/log/auth.log, перемкніть на backend = systemd (і приберіть оманливі логшляхи).
Завдання 8 — Перевірити ефективний бекенд і logpath jail’а
cr0x@server:~$ sudo fail2ban-client get sshd backend
systemd
cr0x@server:~$ sudo fail2ban-client get sshd logpath
/var/log/auth.log
Що це означає: Ви можете опинитися з systemd бекендом і застарілим logpath, який все ще налаштований (особливо якщо копіювали старі фрагменти). Це плутає.
Рішення: Якщо використовується systemd бекенд, приберіть logpath з цього jail, якщо немає важливої причини його зберігати. Тримайте конфіг простим.
Завдання 9 — Перевірити, чи Fail2ban може читати джерело логів (права і групи)
cr0x@server:~$ ps -o user,group,comm -p $(pgrep -xo fail2ban-server)
USER GROUP COMMAND
root root fail2ban-server
cr0x@server:~$ sudo -u root test -r /var/log/auth.log && echo "readable"
readable
Що це означає: На Ubuntu Fail2ban зазвичай працює від root, тому права файлів рідко блокують. Але якщо ви ужорсточили запуск від неповноважного користувача, доступ до логів стає реальною перешкодою.
Рішення: Якщо запускаєте Fail2ban не від root, переконайтесь, що він може читати логи і маніпулювати брандмауером. Якщо не може — він не працюватиме.
Завдання 10 — Запустити тест regex фільтра проти реальних даних (припиніть сподіватись)
cr0x@server:~$ sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched
Running tests
=============
Use failregex filter file : sshd, basedir: /etc/fail2ban
Use log file : /var/log/auth.log
Results
=======
Failregex: 12 total
|- #) [# of hits] regular expression
| 1) [12] Failed password for .* from <HOST>
Ignoreregex: 0 total
Summary
=======
Lines: 1828 lines, 0 ignored, 12 matched, 1816 missed
Що це означає: Якщо звіт показує «0 matched», Fail2ban ніяк не зможе банити на основі цього поєднання фільтр/лог. Можливо, ваші логи в журналі або повідомлення SSHD інші (PAM, локалізація тощо).
Рішення: Виправте можливість збігу перед тим, як торкатись порогів. Якщо не збігається, значення maxretry не має значення.
Завдання 11 — Підтвердити, що логіка вікна часу не заважає банам
cr0x@server:~$ sudo fail2ban-client get sshd findtime
600
cr0x@server:~$ sudo fail2ban-client get sshd maxretry
5
cr0x@server:~$ sudo fail2ban-client get sshd bantime
3600
Що це означає: Ви баните, коли IP робить maxretry збігів всередині findtime. Якщо атакуючі розподіляють спроби в часі або по різних іменах користувачів з різними рядками логів, ви можете не досягти порогу.
Рішення: Якщо «Total failed» росте, але банів немає, тимчасово зменшіть maxretry до 2 і тримайте findtime розумним (наприклад, 10 хв). Перевірте, що бани відбуваються, потім налаштуйте назад.
Завдання 12 — Перевірити ignore правила (тихий плащ невразливості)
cr0x@server:~$ sudo fail2ban-client get sshd ignoreip
127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16
Що це означає: Якщо ваш трафік походить з VPN або NAT-діапазону, який є в ignoreip, Fail2ban спокійно нічого не робитиме. Це функція, але й генератор простою.
Рішення: Тримайте ignore списки вузькими. Додавайте лише IP-сі адмінів, а не весь корпоративний простір, якщо вам не подобається ідея про те, що скомпрометовані ноутбуки можуть вільно брутфорсити.
Завдання 13 — Примусово забанити (контрольний тест), щоб перевірити шар дій
cr0x@server:~$ sudo fail2ban-client set sshd banip 203.0.113.90
1
cr0x@server:~$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 44
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 203.0.113.90
Що це означає: Це доводить, що контрольна площина Fail2ban може виконувати бани. Це не доводить, що брандмауер їх застосовує. Це наступний крок.
Рішення: Якщо бан відображається тут, переходьте до валідації брандмауера. Якщо не відображається — дія або jail внутрішньо зламані, або ви вказали неправильну назву jail.
Завдання 14 — Визначити, чи система використовує nftables чи iptables для застосування
cr0x@server:~$ sudo update-alternatives --display iptables
iptables - auto mode
link best version is /usr/sbin/iptables-nft
link currently points to /usr/sbin/iptables-nft
link iptables is /usr/sbin/iptables
/usr/sbin/iptables-nft - priority 20
/usr/sbin/iptables-legacy - priority 10
Що це означає: Якщо iptables вказує на iptables-nft, то «iptables правила» можуть фактично бути структурами nftables під капотом. Якщо ви використовуєте nftables дію Fail2ban, слід інспектувати nftables напряму.
Рішення: Виберіть один шлях застосування і спостерігайте його з правильними інструментами. Не змішуйте iptables-legacy з nftables, якщо ви не навмисно не запускаєте паралельні світи.
Завдання 15 — Перевірити, чи nftables має таблицю/ланцюг Fail2ban (якщо використовуєте nftables дії)
cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority filter; policy accept;
ct state established,related accept
iif "lo" accept
tcp dport 22 accept
}
}
table inet f2b-table {
set f2b-sshd {
type ipv4_addr
elements = { 203.0.113.90 }
}
chain f2b-sshd {
ip saddr @f2b-sshd drop
return
}
}
Що це означає: Ви маєте бачити таблицю/ланцюг або сет f2b з вашим забаненим IP. Якщо він існує, Fail2ban запрограмував nftables.
Рішення: Якщо сет/ланцюг існує, але трафік все одно проходить, ймовірно проблема в порядку правил (ланцюг Fail2ban не підключений рано достатньо), або сервіс доступний по IPv6, а ви забанили лише IPv4.
Завдання 16 — Перевірити iptables на наявність Fail2ban-ланцюгів (якщо використовуєте iptables дії)
cr0x@server:~$ sudo iptables -S | sed -n '1,80p'
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N f2b-sshd
-A INPUT -p tcp -m tcp --dport 22 -j f2b-sshd
-A f2b-sshd -s 203.0.113.90/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -j RETURN
Що це означає: Наявність ланцюга f2b-sshd і переходу з INPUT до нього — доказ конфігурації застосування.
Рішення: Якщо ланцюг є, але немає переходу в нього, дія лише створила ланцюг, але не прикріпила його. Це проблема конфігурації дії.
Завдання 17 — Перевірити, чи бан дійсно блокує пакети (не довіряйте лише конфігу)
cr0x@server:~$ sudo timeout 5 tcpdump -ni any 'host 203.0.113.90 and tcp port 22'
tcpdump: data link type LINUX_SLL2
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
10:21:02.112345 IP 203.0.113.90.49160 > 198.51.100.10.22: Flags [S], seq 123456789, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 7], length 0
Що це означає: Ви бачите SYN, що надходять. Тепер перевірте, чи сервер відповідає (SYN-ACK) або відкидає/відмовляє. Якщо ваш бан — «drop», ви маєте бачити вхідні SYN без відповідей.
Рішення: Якщо ви все ще бачите вихідні SYN-ACK, ваше правило брандмауера не спрацьовує (неправильний ланцюг/порядок/родина інтерфейсу), або сервіс зв’язаний інакше, ніж ви припускаєте.
Завдання 18 — Розбанити тестовий IP і прибрати сліди
cr0x@server:~$ sudo fail2ban-client set sshd unbanip 203.0.113.90
1
Що це означає: Ви не намагаєтесь постійно банити документаційні IP або Wi‑Fi колеги. Ви верифікуєте пайплайн.
Рішення: Якщо unban не видаляє стан брандмауера, ваша очистка дії зламана, або ви дивитесь не в той бекенд брандмауера.
Реальність брандмауера в Ubuntu 24.04: nftables, iptables і що насправді торкається Fail2ban
Ubuntu 24.04 належить до ери, коли nftables — це основна правда, навіть якщо ви звичкою ще друкуєте iptables. Fail2ban може використовувати будь-який з них, але ви маєте узгодити:
- nftables дії створюють таблиці/ланцюги/сети nft напряму. Ви перевіряєте їх командою
nft list ruleset. - iptables дії вставляють iptables правила. На системах з iptables-nft ці правила можуть бути транслювані в структури nftables, але ви все одно керуєте ними через iptables інструменти.
Виберіть один інтерфейс застосування і спостерігайте його правильно
Якщо ви налаштували Fail2ban використовувати nftables дії, не перевіряйте бани через iptables -S і не оголошуйте, що все зламано. Це як перевіряти рівень олії, дивлячись на шини. Технічно все частина машини, але ви вимірюєте не те.
UFW ускладнює, але не забороняє Fail2ban
UFW — це менеджер політик, а не двигун брандмауера. Класична iptables дія Fail2ban часто співіснує з UFW, бо UFW залишає місце для додаткових ланцюгів. Але UFW також може встановлювати суворі політики і розташовувати свої ланцюги перед чи після ланцюгів Fail2ban залежно від інтеграції.
Операційне правило: якщо ви використовуєте UFW, переконайтесь, що блокування Fail2ban оцінюється рано на шляху обробки вхідного трафіку для цільових портів. Якщо не знаєте — тестуйте Завдання 17 і припиніть теоретизувати.
IPv6: причина «бан є, але підключаються»
Якщо сервіс слухає на :: (IPv6 wildcard) і клієнт має IPv6 зʼєднання, IPv4 бан не зачепить це зʼєднання. Це може виглядати як «Fail2ban не банить», коли насправді бан є, але для іншої протоколної сім’ї.
Практичний підхід: підтвердьте, яку сімʼю адрес використовують клієнти, і налаштуйте дії Fail2ban, що покривають і IPv4, і IPv6 там, де це доречно.
Фільтри та regex: коли Fail2ban «працює», але ніколи не збігається
Фільтри — це місце, де ваші припущення вмирають. Fail2ban не розуміє «атаку». Він розуміє «рядок логу, що відповідає цьому regex». Це і сила, і пастка.
Знайте формат ваших логів: OpenSSH — не єдиний голос в auth
Між PAM, різними налаштуваннями SSHD і іноді кастомними патчами, рядки помилок можуть відрізнятися. Деякі середовища викидають «Invalid user», інші — «Failed password», ще інші мають інші поля для publickey-помилок. Ваш фільтр повинен відповідати реальності.
Використовуйте fail2ban-regex як ворота, а не як відкладений дебаг
Якщо ви зробите одну дисципліновану річ: запустіть fail2ban-regex проти точного джерела логів, яке налаштовано. Якщо воно не збігається — у вас проблема з шаблоном, а не з бана��ем.
Journald бекенди змінюють спосіб фокусування
Коли використовується backend = systemd, Fail2ban робить запити до журналу замість того, щоб «хвостити» файл. Зазвичай це краще на сучасних системах, але це означає, що стара мудрість про logpath може вводити в оману. У світі журналу запитання: чи правильна назва юніту (наприклад, ssh vs sshd) і чи достатні ваші права на журнал?
Жарт #2: Regex — мова, яку пишуть, але рідко читають — до тих пір, поки звіт інциденту не вимагатиме витягти її назад.
Дії: коли є збіг, але нічого не блокується
Після того, як ви довели збіги, наступний клас проблем — «Fail2ban вирішив банити, але застосування нічого не зробило». Це зазвичай потрапляє в одну з цих категорій:
- Неправильна родина брандмауера: ви використали iptables дію на системі, де ви дивитесь лише nftables, або навпаки.
- Порядок правил: правило бану існує, але ніколи не досягається, бо ранні правила приймають трафік (поширено з широкими ACCEPT-правилами або хук-ланцюгами, що обходять).
- Невідповідність інтерфейсу: ваш сервіс на іншому порту/протоколі, ніж припускає дія, або ви баните порт 22, тоді як SSH працює на 2222.
- Невідповідність IPv6: ви забанили IPv4, але клієнт підключається через IPv6.
- Права/можливості: Fail2ban не може запрограмувати брандмауер через ужорсточення або політику системи.
Ручний бан/розбан — ваш найкращий «юнит-тест»
У реальних системах ви можете витратити години, чекаючи, поки поріг спрацює. Не робіть цього. Використайте Завдання 13, щоб змусити бан і потім інспектувати стан брандмауера. Якщо ручний бан не створює записи в брандмауері — проблема виконання дії. Якщо створює, але автоматичні бани не відбуваються — проблема в подіях/фільтрах/порогах.
Перевіряйте прикріплення ланцюга, а не лише його існування
Можливо, у вас є красиво заповнений Fail2ban ланцюг, до якого ніхто ніколи не переходить. Це еквівалент побудувати охоронну будку й ніколи її не заступити.
Для iptables ви маєте бачити перехід з INPUT (або релевантного ланцюга) у f2b-*. Для nftables потрібен посилання на f2b ланцюг у правильному hook‑шляху або використання сету в правилі, яке реально виконується для вхідного трафіку.
Три корпоративні міні-історії з полів без банів
1) Інцидент через неправильне припущення
Команда мала невелику флотилію Ubuntu серверів, оновлених до новішого релізу. У списку робіт було «встановити Fail2ban» і «увімкнути sshd jail», і хтось поставив галочку. Через кілька днів їхні логи аутентифікації показали постійний brute-force: тисячі невдалих спроб, як метроном.
Усі припустили, що система банів покриває це, бо завжди покривала. Інженер на виклику подивився fail2ban-client status і побачив, що sshd jail «running». Комфортно. Вони повернулись до іншої роботи.
Наступного ранку хтось помітив піки CPU, що корелювали з хвилею аутентифікацій. Піки не були катастрофою, але достатні, щоб погіршити затримку чутливого сервісу, який ділив ту ж VM. Коли вони нарешті подивились деталі jail, «Total failed» тикало вгору, а «Total banned» стояв на нулі.
Неправильне припущення: «Якщо jail працює, він мусить банити». Насправді jail читав /var/log/auth.log, який існував, але був застарілий, бо події аутентифікації тепер були в journald. Живого входу логів не було. Немає бану.
Виправлення було нудним і швидким: переключити jail на backend = systemd, прибрати logpath-override, який прищепив його до застарілого файлу, потім примусово забанити тестовий IP, щоб перевірити правила nftables. Як тільки ланцюг став видимим і співпав, шум brute-force одразу впав. Постмортем був короткий і трохи принизливий — що й добре.
2) Оптимізація, що зіграла злий жарт
Інженер із безпеки хотів зменшити запис на диск і обʼєм логів. Він посилив конфіг rsyslog і більше покладався на journald. Це само по собі не погано. Але він також налаштував ротацію й збереження так, що деякі файлові логи фактично зникли. Ніхто не помітив, бо сервіси працювали й журнал мав дані.
Fail2ban, однак, все ще був налаштований на файлові бекенди і вказував на шляхи, які колись існували. Оскільки Fail2ban не впав, припущення стало «все гаразд». Він стартував, працював, навіть показував jails. Але фактично він «хвостив порожнє повітря».
Потім стало цікавіше: вони також значно збільшили findtime і bantime, щоб «бути суворішими». Намір був добрий — банити довше. Ефект був гіршим: коли вони згодом знову ввімкнули логування, Fail2ban отримав ширше вікно оцінки, але regex-фільтр почав збігатись з додатковими нешкідливими рядками через кастомний формат PAM. Він почав банити внутрішні NAT вихідні IP під час вікна обслуговування.
Операції сприйняли це як мережеву нестабільність. Розробники — як «SSH не працює». Безпека — як «ми під атакою». Правда: оптимізація логування плюс агресивне тюніння банів підкреслили невідповідність фільтра.
Шлях відновлення був дисциплінований: повернутися до мінімального набору перевірених фільтрів, переключити бекенди на journald явно, зменшити пороги до розумних значень і звузити ignoreip до реальних адмін-діапазонів. Вони зберегли journald як основне джерело, але перестали прикидатися, що невидимі логи можна парсити інструментами, які очікують файли.
3) Байденно правильна практика, яка врятувала ситуацію
Інша організація виконувала стандартизовану перевірку «Security controls verification» після кожного циклу патчів ОС. Це не було складно; це була кілька команд у ранобуці з очікуваними виводами. Одна з перевірок примусово била тимчасовий бан на безпечному тестовому IP і підтверджувала, що правило брандмауера зʼявилось у правильній підсистемі.
Під час рутинного релізу новий базовий образ змінив альтернативу iptables з legacy на nft. Ніщо інше в стеку програми не зламалось. Деплой пройшов гладко. Але перевірка провалилась: тестовий бан був у статусі Fail2ban, але очікуваного iptables-ланцюга не було. Немає відповідних правил.
Оскільки тест був рутинним, це помітили одразу. Команда не стала чекати, поки атакуючі доведуть прогалину. Вони просто оновили дію Fail2ban на nftables і налаштували валідацію дивитись nft list ruleset замість grep по iptables. Через десять хвилин пайплайн пройшов. Вони запушили новий бейзлайн і рухались далі.
Краще за все: нікому не довелося сперечатися, чи «бан працює, мабуть». Було доказово. Нудна, правильна практика. Вона не отримує нагород, але зберігає ваші ночі спокійними.
Типові помилки: симптом → корінь проблеми → виправлення
1) Cимптом: Jail у списку, але «Total failed» стоїть на 0
Корінь проблеми: Неправильне джерело логів. Ви хвостите файл, у який нічого не пишуть, або юніт у journal ви запитуєте неправильно.
Виправлення: Доведіть, що помилки існують (Завдання 7) і вирівняйте бекенд/logpath (Завдання 6–8). Не гадіть. Нехай jail читає те, що пише ваша система.
2) Cимптом: «Total failed» зростає, але «Total banned» назавжди 0
Корінь проблеми: Пороги занадто високі, ignoreip включає джерело атаки, або невдалі спроби розподілені по часу поза findtime.
Виправлення: Перевірте пороги і ignoreip (Завдання 11–12). Тимчасово зменшіть maxretry, щоб верифікувати пайплайн, потім тонко налаштуйте.
3) Cимптом: «Currently banned» показує IPи, але атакуючі все одно підключаються
Корінь проблеми: Невідповідність застосування: неправильна дія (iptables vs nftables), порядок правил або обхід IPv6.
Виправлення: Примусово забаньте тестовий IP (Завдання 13), потім перевірте у відповідній підсистемі брандмауера (Завдання 14–16) і валідуйте поведінку пакетів (Завдання 17). Додайте покриття IPv6 при потребі.
4) Cимптом: У логах Fail2ban «No such file or directory» для logpath
Корінь проблеми: Старі фрагменти jail, що вказують на /var/log/auth.log або логи аплікацій, які більше не існують, бо логування перейшло в journald або вивід контейнера.
Виправлення: Перейдіть на backend = systemd там, де це доцільно, або забезпечте, щоб сервіс логував у файл, який ви можете читати і безпечно ротаційно обробляти.
5) Cимптом: Ручний бан працює, автоматичні бани ніколи не відбуваються
Корінь проблеми: Невідповідність фільтра: ваш regex не збігається з реальними рядками логів. Або jail спостерігає неправильний порт/назву сервісу.
Виправлення: Запустіть fail2ban-regex (Завдання 10) проти реального джерела і поправте фільтр або параметри jail, поки не отримаєте збіги.
6) Cимптом: Після увімкнення UFW бани перестали працювати
Корінь проблеми: Змінився порядок ланцюгів; UFW приймає трафік раніше, ніж Fail2ban встигає його відкинути.
Виправлення: Переконайтесь, що правила Fail2ban оцінюються рано для релевантного трафіку. Перевіряйте поведінку (Завдання 17), а не лише наявність правил.
7) Cимптом: Fail2ban банить ваших колег під час деплою
Корінь проблеми: NAT: багато людей виходять під одним публічним egress IP, і невдалі спроби з кількох хостів накопичуються під тією адресою.
Виправлення: Додавайте відповідні корпоративні NAT адреси до ignoreip (акуратно), або збільшуйте maxretry/findtime, щоб не карати загальний egress. Також подумайте про перенесення доступу адмінів за VPN з ідентифікацією користувачів.
8) Cимптом: Fail2ban сервіс стартує, але jails не завантажуються після правки
Корінь проблеми: Синтаксична помилка в файлі jail або проблема з порядком include. Fail2ban суворий, і одна погана секція може відключити те, що ви думали увімкненим.
Виправлення: Використайте fail2ban-client -d (Завдання 4) і journal помилки (Завдання 2), щоб знайти проблемний файл. Виправте, перезапустіть і перевірте список jails.
Чеклісти / покроковий план
Чекліст A — «Потрібно, щоб бани працювали сьогодні» (30–60 хв, дисципліновано)
- Підтвердьте здоровʼя Fail2ban:
systemctl status fail2ban(Завдання 1). - Прочитайте помилки Fail2ban:
journalctl -u fail2ban(Завдання 2). - Переконайтесь, що ваш jail запущений:
fail2ban-client status(Завдання 3). - Інспектуйте деталі jail:
fail2ban-client status sshd(Завдання 5). - Доведіть, що помилки є в обраному джерелі логів (Завдання 6–7).
- Доведіть, що фільтр збігається:
fail2ban-regex(Завдання 10). - Примусово забаньте тестовий IP:
fail2ban-client set sshd banip ...(Завдання 13). - Перевірте стан брандмауера з відповідним інструментом (Завдання 14–16).
- Валідуйте поведінку з tcpdump (Завдання 17), потім розбаньте (Завдання 18).
Чекліст B — Жорстка конфігурація без втрат роботи банів (бо «безпечніше» не означає «нефункціонально»)
- Визначте бекенд застосування: nftables або iptables-nft. Документуйте вибір.
- Стандартизируйте jails у
/etc/fail2ban/jail.d/*.localзамість редагуванняjail.conf. - Віддавайте перевагу
backend = systemdна хостах, де journald авторитетний. - Тримайте
ignoreipмінімальним; ставтесь до нього як до allowlist брандмауера (перегляд, обґрунтування, обмеження). - Покривайте IPv6, якщо ваші сервіси доступні через IPv6.
- Додайте просту перевірку бану в постдеплой: примусовий бан, перевірка брандмауера, розбан.
Чекліст C — Коли підозрюєте проблеми з порядком правил
- Примусово забаньте тестовий IP (Завдання 13).
- Знайдіть наявність правила і ланцюга (Завдання 15–16).
- Підтвердьте, що ланцюг бану справді викликається з шляху input (iptables: перехід з INPUT; nft: hook ланцюг або посилання на сет).
- Тестуйте поведінку з tcpdump (Завдання 17).
- Налаштуйте конфіг дії або порядок політик брандмауера, поки пакети не перестануть прийматись.
FAQ
1) Чому Fail2ban показує «Total failed» що зростає, але все одно не банить?
Бо бан відбувається за порогами. Перевірте maxretry, findtime і ignoreip. Тимчасово зменшіть maxretry, щоб довести, що пайплайн працює, потім налаштуйте назад.
2) Чи треба використовувати backend = systemd на Ubuntu 24.04?
Якщо ваші помилки аутентифікації живуть у journald (часто так), так. Використовуйте журнал як джерело істини. Хвостинг файлів підходить, коли файл справжній, актуальний і має стабільний формат.
3) Як дізнатись, чи я використовую nftables чи iptables?
Перевірте update-alternatives --display iptables і перегляньте активні правила відповідним інструментом. Якщо Fail2ban використовує nftables дії — вивчайте через nft list ruleset.
4) Я бачу бани в статусі Fail2ban. Чи означає це, що трафік гарантовано блокується?
Ні. Це тільки внутрішній стан Fail2ban. Завжди перевіряйте застосування, дивлячись правила брандмауера і поведінку пакетів (tcpdump або контрольована спроба підключення).
5) Чому ручний бан працює, а автоматичний — ні?
Ручний бан обходить фільтри. Автоматичні бани залежать від відповідності рядків логів. Використайте fail2ban-regex проти точного джерела логів, щоб довести, що фільтр відповідає реальності.
6) Чи може UFW заважати Fail2ban?
Так, переважно через порядок правил або конфлікт політик. Виправлення не полягає у «вимкнути UFW». Потрібно гарантувати, що блокування Fail2ban оцінюється на релевантному шляху трафіку і перевіряти поведінку.
7) Чому іноді я сам себе баню?
NAT і спільний egress. Багато людей виходять під одним публічним IP і накопичення невдалих спроб карає всіх. Додавайте адмін-адреси в ignoreip акуратно або покращуйте схему доступу (VPN, bastion, ключі).
8) Чи потрібно піклуватись про IPv6 з Fail2ban?
Якщо сервіс доступний по IPv6 — так. Інакше ви отримаєте «бан працює для половини Інтернету», що не дуже втішне.
9) Чи достатньо Fail2ban для захисту SSH?
Fail2ban корисний як фільтр шуму і обмежувач швидкості. Але фундаментальні речі важливіші: автентифікація за ключами, відсутність парольної автентифікації де можливо, MFA на bastion, і найменший можливий доступ на мережевому краю.
10) Яка найкраща перевірка, коли хтось каже «Fail2ban не працює»?
Примусово забаньте тестовий IP, перевірте стан брандмауера, потім перевірте поведінку пакетів. Це ізолює застосування від виявлення за кілька хвилин.
Висновок: наступні кроки, які можна зробити сьогодні
Якщо Fail2ban не банить на Ubuntu 24.04, ставтесь до цього як до будь-якого іншого продакшн-пайплайну: input, processing, output, enforcement. Верифікуйте кожен шар з доказами. Не крутьте ручки у темряві.
Зробіть ці три речі наступними:
- Доведіть видимість логів: підтвердіть, що ваші помилки існують там, де jail їх читає (journal vs файл), і запустіть
fail2ban-regexпроти реальних даних. - Доведіть застосування: примусово забаньте тестовий IP і підтвердіть, що правила зʼявляються в правильній підсистемі брандмауера (nft vs iptables), потім перевірте поведінку пакетів.
- Зробіть це повторюваним: додайте просту перевірку після змін (ban, спостереження, unban), щоб оновлення не відʼєднували ваші захисти непомітно.
Fail2ban не магія. І це добра новина. Це означає, що ви можете налагоджувати його як дорослий: за допомогою робочого процесу, а не надії.