fail2ban
SSH hardening maqolasida fail2ban kengroq SSH checklist’ining bir qismi sifatida qisqacha tilga olingan edi: u log'larni kuzatadi va vaqt oralig'i ichida juda ko'p muvaffaqiyatsiz urinish qilgan IP manzilni ban qiladi. Bu maqolada u to'liq ko'rib chiqiladi. fail2ban umuman faqat SSH’ga xos emas. U log fayli va tanib olinadigan muvaffaqiyatsizlik shabloni bor har qanday servisni — pochta serveridan tortib web ilovaning login formasigacha — himoya qila oladigan umumiy log kuzatish framework’i.
Nimalarni o'rganasiz
Bu maqola oxirida siz quyidagilarni qila olasiz:
- fail2ban log shablonini firewall ban’iga qanday aylantirishini tushuntirish;
- tayyor standart sozlamalarni bevosita tahrirlamasdan
jail.localda jail sozlash; - filtrning regex’ini production’da unga ishonishdan oldin haqiqiy log qatorlariga qarshi sinab ko'rish;
- manzillarni qo'lda tekshirish, ban’dan chiqarish va oq ro'yxatga (whitelist) kiritish;
- SSH’dan tashqari ikkinchi servisni o'z jail’i bilan himoya qilish.
fail2ban aslida qanday ishlaydi
fail2ban’da birgalikda bitta jail ni tashkil qiladigan uchta harakatlanuvchi qism bor:
- kuzatiladigan log fayl (
/var/log/auth.log, ilovaning o'z log'i va hokazo); - filter — o'sha log'dagi muvaffaqiyatsiz urinish qatorini tanib oladigan regular expression’lar to'plami;
- action — filter vaqt oralig'i ichida bitta manzildan juda ko'p marta mos kelgandan keyin nima qilish kerakligi. Bu deyarli har doim uni bloklash uchun firewall qoidasini qo'shish.
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled)
Active: active (running)
fail2ban’ning o'zi firewall o'rnini bosmaydi — u firewall’ni boshqaradi. U ban qoidalarini nftables/iptables to'plami (set) sifatida dinamik qo'shadi va olib tashlaydi (qarang: iptables va nftables), ularni esa ostida baribir UFW yoki xom nftables ruleset’i majburlaydi.
Tayyor standart sozlamalarni hech qachon bevosita tahrirlamang
fail2ban /etc/fail2ban/jail.conf dagi standart konfiguratsiya bilan keladi. Lekin bu fayl keyingi paket yangilanishida qayta yozilishi kutiladi. Har qanday mahalliy sozlash /etc/fail2ban/jail.local ga yozilishi kerak. fail2ban uni jail.conf dan keyin o'qiydi va undagi har qanday sozlama ustun keladi:
Boshlang'ich nuqta sifatida butun faylni nusxalash an’anaviy yondashuv. Lekin faqat haqiqatan sozlanayotgan bo'limlarni qoldirish kifoya — o'rnatilmagan har qanday narsa avtomatik ravishda jail.conf ning standart qiymatiga qaytadi.
Jail sozlash
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 203.0.113.5
[sshd]
enabled = true
port = 22
logpath = %(sshd_log)s
maxretry = 3
bantime— ishga tushgan ban qancha davom etishi (1hyoki doimiy uchun-1);findtime— ban’ni ishga tushirish uchunmaxretryta muvaffaqiyatsizlik sodir bo'lishi kerak bo'lgan siljuvchi vaqt oynasi;maxretry—findtimeichida nechta mos keluvchi muvaffaqiyatsizlik ban’ni ishga tushirishi;ignoreip— qanday mos kelishidan qat’i nazar hech qachon ban qilinmaydigan manzillar (va CIDR oraliqlari). Bu yerga har doim boshqaruv ish stansiyasining o'z manzilini qo'shing, chunki o'z IP’ingizga qo'yilgan ban hujumchinikiga qo'yilgani kabi sizni qulflab qo'yishda xuddi shunday samarali;[sshd]aynan shu jail uchunmaxretryni qayta belgilaydi va aniq qayta yozilmagan hamma narsa uchun[DEFAULT]bo'limidagi qiymatlar ustiga qo'shiladi.
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 14
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 3
`- Banned IP list: 198.51.100.7
Filtrga ishonishdan oldin uni sinab ko'rish
Haqiqiy log qatorlariga mos kelmaydigan filter muammoni bildiradigan hech qanday xatosiz, jimgina hech narsani himoya qilmaydi. Shuning uchun filtrga tayanishdan oldin uning regex’i haqiqatan mos kelishini tekshirishga arziydi:
Results
=======
Success, the total number of match is 14
Overall
=======
Lines: 20348 lines, 0 ignored, 14 matched, 20334 missed
fail2ban-regex filtrni hech kimni ban qilmasdan haqiqiy log fayliga qarshi ishga tushiradi. Bu maxsus filtr (yoki distributiv log formatini o'zgartirgandan keyin o'zgartirilgan filtr) production’da unga tayanishdan oldin hali ham mos kelishini tasdiqlashning xavfsiz usuli.
Tekshirish, ban’dan chiqarish va oq ro'yxatga kiritish
Noto'g'ri ishlash (false positive) holatida — masalan, parolini juda ko'p marta noto'g'ri kiritgan qonuniy foydalanuvchi uchun — to'g'ri javob ban’dan chiqarish. Butun fail2ban servisini qayta ishga tushirish esa xatoga aloqasi bo'lmagan boshqa barcha faol ban’larni ham tozalab yuboradi.
Hech qachon ban’ni ishga tushirmasligi kerak bo'lgan manzillarni doimiy oq ro'yxatga kiritish qayta-qayta qo'lda ban’dan chiqarish bilan emas, ignoreip da qilinadi:
Ikkinchi servisni himoya qilish
fail2ban’ning tuzilishi SSH’dan tashqariga ham umumlashadi — log fayli va tanib olinadigan muvaffaqiyatsizlik qatori bor har qanday servis o'z jail’iga ega bo'lishi mumkin. Keng tarqalgan misol: nginx saytiga qarshi takroriy muvaffaqiyatsiz HTTP basic-auth urinishlarini ban qilish.
fail2ban aynan shu log shabloni uchun mos filtr bilan allaqachon keladi (/etc/fail2ban/filter.d/nginx-http-auth.conf). Filtrning o'zi standart distributivning bir qismi bo'lgani uchun jail ta’rifi faqat uni yoqishi va to'g'ri log yo'liga ishora qilishi kerak.
Status for the jail: nginx-http-auth
|- Filter
| |- Currently failed: 0
| |- Total failed: 6
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 0
|- Total banned: 1
`- Banned IP list:
Bu pam_faillock va UFW’ning limit i bilan qanday bog'liq
Bu kursdagi uchta mexanizm bir-biriga o'xshash eshitiladigan muammoni hal qiladi va ularni aniq farqlay olish uchun bevosita tayyorlanishga arziydi:
| Mexanizm | Nimaga javob beradi | Bloklash doirasi |
|---|---|---|
ufw limit (qarang: Firewall va UFW) |
Muvaffaqiyat/muvaffaqiyatsizlikni bilmagan holda xom ulanish tezligiga | Har bir manba IP bo'yicha, firewall’da, autentifikatsiyaga urinishdan oldin |
pam_faillock (qarang: Root va sudo) |
Bitta akkaunt uchun ketma-ket autentifikatsiya muvaffaqiyatsizliklariga | Manba IP’dan qat’i nazar, har bir akkaunt bo'yicha |
| fail2ban | Servisdan qat’i nazar, log fayldagi muvaffaqiyatsizlik shablonlariga | Haqiqatan muvaffaqiyatsiz bo'lgan urinishlar asosida, har bir manba IP bo'yicha, firewall’da |
Intervyuda: nega bittasini emas, uchalasini joriy qilish kerak
Har bir akkaunt uchun bir nechta urinishni minglab manba IP’lar bo'ylab tarqatadigan taqsimlangan brute-force hujum fail2ban’ning har bir IP bo'yicha ban qilishini yengadi (birorta ham IP chegaradan o'tmaydi), lekin pam_faillock ning har bir akkaunt bo'yicha bloklashini yengmaydi. Bitta IP’dan ko'plab foydalanuvchi nomlarini navbatma-navbat sinab ko'radigan sekin, sabrli hujumchi pam_faillock ning har bir akkaunt bo'yicha sanashini yengadi, lekin fail2ban’ning har bir IP bo'yicha ban qilishini yengmaydi. ufw limit ikkala shablonni ham aniq ushlamaydi, lekin aniq ko'rinib turgan yuqori tezlikdagi skanerlashni autentifikatsiya qatlamiga yetib bormasdan bloklaydigan qo'pol, arzon birinchi himoya chizig'ini qo'shadi. Uchalasidan hech biri yolg'iz o'zi har bir hujum shaklini qamrab olmaydi — bu qisqartirilishi kerak bo'lgan ortiqchalik emas, uchalasini birga joriy qilishning amaliy dalili.
Amaliy vaziyat: hech kimni ban qilmayotgan jail’ni diagnostika qilish
Muammo. SSH aniq faol hujum ostida (auth.log da o'nlab muvaffaqiyatsiz loginlar ko'rinadi), lekin fail2ban-client status sshd nol ban ko'rsatadi.
1-qadam — jail umuman yoqilgani va to'g'ri log'ni kuzatayotganini tasdiqlash:
Jail umuman mavjud emas — jail.local da [sshd] hech qachon enabled = true ga o'rnatilmagan. Shuning uchun amalda jail.conf ning o'z standart qiymati (bu distributivda o'chiq) ishlayapti.
2-qadam — uni yoqish va log yo'li haqiqatga mos kelishini tasdiqlash:
3-qadam — filtr ishlatilayotgan log formatiga haqiqatan mos kelayotganini tekshirish:
Xulosa. Jail shunchaki hech qachon yoqilmagan edi — bu filtr yoki firewall muammosi emas, konfiguratsiyadagi bo'shliq. U yoqilib, haqiqiy log qatorlariga mos kelishi tasdiqlangach, keyingi muvaffaqiyatsiz urinishlar maxretry tomon to'g'ri to'plana boshlaydi.
Keng tarqalgan xatolar
jail.confni bevosita tahrirlash. Keyingi paket yangilanishi uni qayta yozadi va sozlashni jimgina yo'q qiladi. Barcha mahalliy o'zgarishlarjail.localga tegishli.- Boshqaruv ish stansiyasining o'z IP’sini
ignoreipga qo'shishni unutish. Umumiy ofis IP’sidan bitta noto'g'ri kiritilgan parol faqat xato qilgan kishini emas, butun jamoani qulflab qo'yishi mumkin. - Konfiguratsiya faylida ko'rsatilgani uchungina jail yoqilgan deb o'ylash. Yuqoridagi vaziyatda ko'rsatilganidek, jail bo'limi
enabled = truesiz ham mavjud bo'lishi mumkin va bu holda u hech narsa qilmaydi. - Filtrni haqiqiy log qatorlariga qarshi sinamasdan unga ishonish. Distributiv yangilangandan keyingi log formati o'zgarishi oldin ishlagan filtrni jimgina buzishi mumkin.
fail2ban-regexunga tayanishdan oldin u hali ham mos kelishini tasdiqlash usuli. - fail2ban’ni brute-force login urinishlariga qarshi yagona himoya sifatida ishlatish. Yuqorida ko'rib chiqilganidek, u
pam_faillockvaufw limitdan boshqa hujum shaklini qamrab oladi. Faqat unga tayanish ma’lum hujum shablonlarini himoyasiz qoldiradi.
Mashqlar
- Lab VM’da
sshdjail’ini pastmaxretry(2) va qisqabantime(60) bilan yoqing, keyin ban ishga tushishi uchun boshqa mashina yoki terminaldan ataylab yetarli marta SSH login’da muvaffaqiyatsizlikka uchrang.fail2ban-client status sshdbilan tasdiqlang va keyin o'zingizni ban’dan chiqaring. - O'z boshqaruv IP’ingizni
ignoreipga qo'shing va bu qator jail’ning o'zi xavfsizlik uchun qanchalik muhim bo'lsa, mavjudlik (availability) uchun ham shunchalik muhimligini bir jumlada tushuntiring. - Servisning log fayli va unga mos filtrga qarshi
fail2ban-regexni ishga tushiring va chiqishdagi "matched" va "missed" sonlarini talqin qiling. - Password-spraying hujumi ostidagi faraziy pochta serveri uchun (ko'plab akkauntlar, har biriga kam urinish, bitta IP’dan) fail2ban,
pam_faillockvaufw limitdan qaysi biri uni birinchi bo'lib ushlashini va nega ekanini tushuntiring.
Xulosa
fail2ban log faylni tanib olinadigan muvaffaqiyatsizlik shabloni bo'yicha kuzatadi va vaqt oynasi ichida chegaradan o'tilgach, aybdor manzilni firewall’da ban qiladi. Bu SSH’ga xos emas, umumiy mexanizm bo'lib, qayta yozilishi mumkin bo'lgan jail.conf orqali emas, jail.local orqali sozlanadi. U pam_faillock ning har bir akkaunt bo'yicha bloklashini va UFW’ning xom rate limiting'ini almashtirmaydi, balki to'ldiradi, chunki uchalasining har biri boshqa hujum shaklini ushlaydi. Keyingi maqola, auditd, xavfsizlikka oid kernel hodisalarini bevosita yozib borishni ko'rib chiqadi. Bu xuddi shu "kuzat, keyin harakat qil" g'oyasining nozikroq, umumiyroq shakli.