Tarkibga o'tish

PAM asoslari

Root va sudo maqolasida PAM sudo va su ning autentifikatsiya qarorlari ortidagi mexanizm sifatida tanishtirilgan va aynan shu holat uchun pam_faillock ko'rib chiqilgan edi. Lekin PAM sudo'dan kattaroq. Bu SSH orqali tizimga kirish, passwd bilan parolni o'zgartirish, konsolda login sessiyasini ochish va "bu shaxsga hozir buni qilishga ruxsat bormi" degan savolga javob berishi kerak bo'lgan o'nlab boshqa servislar ortida turgan o'sha framework. Bu maqola umumiy qo'llanma: arxitektura, modul turlari va allaqachon ko'rib chiqilganidan tashqari bilishga arziydigan modullar.

Nimalarni o'rganasiz

Bu maqola oxirida siz quyidagilarni qila olasiz:

  • PAM nega ilova va haqiqiy autentifikatsiya tekshiruvi o'rtasidagi qatlam sifatida mavjudligini tushuntirish;
  • PAM stack’ini o'qish va har bir qatorning turi, control flag'i va modulini aniqlash;
  • pam_unix, pam_limits va pam_env ning har biri nima qilishini tushuntirish;
  • PAM konfiguratsiyasidagi o'zgarishni o'zingizni tizimdan qulflab qo'ymasdan sinab ko'rish;
  • PAM stack’larini siz uchun qaysi distributiv vositasi (pam-auth-update yoki authselect) boshqarishini va qachon qo'lda tahrirlash o'rniga undan foydalanish kerakligini bilish.

PAM nega mavjud

PAM’dan oldin foydalanuvchini autentifikatsiya qilishi kerak bo'lgan har bir dastur — login, passwd, ftpd — /etc/shadow ni tekshirish uchun o'zining qattiq kodlangan mantiqiga ega edi. LDAP katalogi yoki apparat token kabi yangi autentifikatsiya usulini qo'shish shu dasturlarning har birini alohida patch qilib, qayta kompilyatsiya qilishni anglatardi. Pluggable Authentication Modules (PAM) bu muammoni ilova va haqiqiy tekshiruv o'rtasiga umumiy kutubxona qo'yish orqali hal qiladi: ilova PAM’ga murojaat qiladi, PAM esa — to'liq konfiguratsiya fayllari asosida, qayta kompilyatsiyasiz — savolga javob berish uchun qaysi modullarni ishga tushirishni hal qiladi.

ldd /usr/bin/sudo | grep pam
libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0

Shuning uchun serverning autentifikatsiya backend’ini mahalliy /etc/shadow tekshiruvidan LDAP’ga almashtirish yoki apparat token talabini qo'shish sudo, sshd yoki login ning o'zini o'zgartirish emas, /etc/pam.d/ ostidagi konfiguratsiya o'zgarishi bo'ladi. Bu dasturlar faqat PAM bilan muloqot qiladi.

To'rtta modul turi

Har bir PAM moduli to'rtta maqsaddan biriga xizmat qiladi va bitta servisning PAM stack’i odatda ulardan bir nechtasidan foydalanadi:

Tur U javob beradigan savol Qo'llanish misoli
auth Bu shaxs haqiqatan o'zi da’vo qilgan kishimi? Parol, kalit, barmoq izini tekshirish
account Parol to'g'riligidan qat’i nazar, bu akkauntga hozir buni qilishga ruxsat bormi? Muddati o'tgan akkaunt, kun vaqti bo'yicha cheklov, bloklangan akkaunt
password Credential qanday o'zgartiriladi? passwd yangi parol o'rnatayotganda murakkablik qoidalarini majburlash
session Sessiya boshida va oxirida nima bo'lishi kerak? Resurs cheklovlarini o'rnatish, login yozuvini yozish, home katalogni mount qilish

/etc/pam.d/ ostidagi servis fayli o'ziga kerak bo'lgan har bir turdan bir yoki bir nechta qatorni ustma-ust joylashtiradi. account auth allaqachon bajargan shaxsni tekshirishni ataylab takrorlamaydi. To'g'ri parol akkauntga hozir tizimga kirishga hali ham ruxsat borligini kafolatlamaydi, va PAM’da ikkala tur ham borligining sababi aynan shu ikki savolni ajratish.

Stack’ni o'qish

cat /etc/pam.d/login
auth       requisite  pam_securetty.so
auth       required   pam_env.so
auth       required   pam_unix.so nullok
account    required   pam_unix.so
account    required   pam_nologin.so
password   required   pam_unix.so
session    required   pam_limits.so
session    required   pam_unix.so
session    optional   pam_lastlog.so

Har bir qator type control module [arguments] ko'rinishida. Control flag — bitta modulning muvaffaqiyati yoki muvaffaqiyatsizligi stack’ning umumiy hukmiga qanday ta’sir qilishini hal qiladigan qism. To'rttasining farqini aniq bilish — PAM bo'yicha eng ko'p beriladigan intervyu savoli:

Control flag Muvaffaqiyatda Muvaffaqiyatsizlikda
required Stack’ni tekshirishda davom etadi; umumiy natija faqat shu turdagi har bir required modul o'tgan bo'lsagina muvaffaqiyatli bo'ladi Muvaffaqiyatsizlikni qayd qiladi, lekin stack’ning qolgan qismini tekshirishda davom etadi, keyin oxirida muvaffaqiyatsiz tugaydi
requisite Stack’ni tekshirishda davom etadi Keyingi modullarni ishga tushirmasdan darhol to'xtaydi va muvaffaqiyatsiz tugaydi
sufficient Darhol to'xtaydi va muvaffaqiyatli tugaydi — agar oldingi biror required modul allaqachon muvaffaqiyatsiz bo'lmagan bo'lsa Bu modul natijasini e’tiborsiz qoldiradi va tekshirishda davom etadi
optional Tekshirishda davom etadi; natija faqat bu stack’da o'z turidagi yagona modul bo'lsagina ahamiyatga ega Tekshirishda davom etadi; aks holda muvaffaqiyatsizlik e’tiborsiz qoldiriladi

Intervyuerlar eng ko'p so'raydigan farq — required va requisite. Ikkalasi ham o'tishi shart, lekin required muvaffaqiyatsizlikdan keyin ataylab davom etadi, shunda foydalanuvchi qaysi tekshiruv uni rad etganini (masalan, noto'g'ri parolmi yoki muddati o'tgan akkauntmi) bila olmaydi. requisite esa davom etishdan xavfsizlik uchun foyda bo'lmaganda darhol to'xtaydi. sufficient — "bulardan istalgan bittasi yetarli" flag'i: muvaffaqiyatli bo'lgan birinchi sufficient modul qolganlarini o'tkazib yuboradi. Bitta stack ikkalasini ham talab qilmasdan mahalliy parolni yoki LDAP credential’ini qabul qila olishi shu tufayli.

requisite sifatidagi pam_securetty.so aniq misol bo'ladi. U /etc/securetty da ro'yxatga olinmagan terminaldan root sifatida kirishni rad etadi va requisite deb belgilangan — muvaffaqiyatsizlik butun stack’ni darhol to'xtatadi. Chunki PAM rad etilishi kerakligini allaqachon bilgan loginni tekshirishda davom etishning hech qanday ma’nosi yo'q.

Qavsli shakl: [success=1 default=ignore]

Zamonaviy stack’lar (quyidagi common-auth chiqishi shulardan biri) ko'pincha oddiy kalit so'z o'rniga [success=1 default=ignore] kabi qavsli shakldan foydalanadi. Bu o'sha g'oyaning umumlashtirilgani: to'rtta qat’iy xatti-harakatdan biri o'rniga u modul qaytarishi mumkin bo'lgan har bir qiymat uchun amalni (ok, ignore, die, done, bad yoki raqam — shu turdagi keyingi nechta qatorni o'tkazib yuborish kerakligi) ko'rsatadi. success=1 "muvaffaqiyatda keyingi 1 ta qatorni o'tkazib yubor" degani, default=ignore esa "boshqa har qanday natijada bu modul yo'qdek harakat qil" degani. To'rtta oddiy kalit so'z bu mexanizmning keng tarqalgan tayyor sozlamalari xolos — masalan, sufficient [success=done new_authtok_reqd=done default=ignore] ga teng. Root va sudo maqolasi pam_faillock ni shu flag'larni qo'llaydigan auth stack misoli sifatida batafsil ko'rib chiqadi. U tushuntirish faqat sudo ning emas, istalgan servisning stack’iga tegishli.

pam_unix: an’anaviy tekshiruv

pam_unix.so — /etc/passwd va /etc/shadow ni haqiqatan o'qiydigan modul. Bu deyarli har bir stack biror joyida o'z ichiga oladigan standart mahalliy akkaunt autentifikatsiyasi:

auth    required   pam_unix.so nullok

nullok argumenti mavjud bo'lsa, /etc/shadow dagi parol maydoni bo'sh bo'lgan akkauntga umuman parolsiz autentifikatsiyadan o'tishga ruxsat beradi. Production serverda bu kamdan-kam kerak bo'ladi va uning mavjudligini alohida tekshirishga arziydi:

grep pam_unix /etc/pam.d/common-auth
auth  [success=1 default=ignore]  pam_unix.so nullok_secure

nullok_secure — ikkalasining xavfsizroq varianti. U bo'sh parolga baribir ruxsat beradi, lekin faqat /etc/securetty da ro'yxatga olingan terminaldan, ya’ni tarmoq orqali kirishdan emas, mahalliy konsoldan. nullok/nullok_secure ni butunlay olib tashlash (shunda bo'sh shadow parol maydoni har doim muvaffaqiyatsiz bo'ladi) tarmoqqa ochiq har qanday server uchun xavfsizroq standart.

pam_limits: har bir sessiya uchun resurs cheklovlari

session bosqichidagi pam_limits.so /etc/security/limits.conf da belgilangan resurs cheklovlarini qo'llaydi. Bu ulimit ning PAM darajasidagi ekvivalenti bo'lib, har bir shell uni qo'lda o'rnatishini talab qilmasdan, tizimga kirishda avtomatik qo'llaniladi:

sudo nano /etc/security/limits.conf
@developers   soft   nofile   4096
@developers   hard   nofile   8192
postgres      soft   nproc    2048
  • soft — tizimga kirishda amalda bo'ladigan standart qiymat. Foydalanuvchi uni o'sha sessiya ichida hard chegaragacha o'zi oshirishi mumkin;
  • hard — faqat root oshira oladigan yuqori chegara;
  • @ bilan boshlangan nom bitta akkauntga emas, guruhga tegishli.
su - postgres -c 'ulimit -n'
1024

Agar kutilgan cheklov amalda bo'lmasa, eng keng tarqalgan sabab — uni tekshirayotgan sessiya aslida pam_limits.so yuklangan PAM session bosqichidan o'tmagan. su - login shell’i bu bosqichdan o'tadi, lekin cron vazifasi yoki systemd servisi odatda o'tmaydi. Ular uchun cheklovlarni boshqa mexanizm orqali (masalan, systemd unit’ining LimitNOFILE= sozlamasi bilan) o'rnatish kerak.

pam_env: tizimga kirishda muhit o'zgaruvchilarini o'rnatish

Yana session bosqichidagi pam_env.so foydalanuvchi shell’i ishga tushishidan oldin /etc/security/pam_env.conf dan muhit o'zgaruvchilarini o'rnatadi. Bu .bashrc ni hech qachon o'qimaydigan interaktiv bo'lmagan yoki login bo'lmagan sessiya uchun ham mavjud bo'lishi kerak bo'lgan o'zgaruvchilar uchun foydali:

TZ  DEFAULT=Europe/Tashkent

PAM o'zgarishini o'zingizni qulflab qo'ymasdan sinash

PAM stack’lari tizimga kirishning o'zini boshqaradi, bu esa bu yerdagi xatoni alohida xavfli qiladi. common-auth yoki sshd ning PAM faylidagi buzilgan auth qatori, buzilgan sudoers fayli kabi, mashinadagi har bir akkauntni, jumladan root’ni ham qulflab qo'yishi mumkin. Lekin undan tiklanish ehtimol qiyinroq, chunki hatto konsoldan to'g'ridan-to'g'ri kirishga ham ta’sir qilishi mumkin.

Ishlab turgan PAM faylini zaxira sessiya ochiq bo'lmasdan hech qachon tahrirlamang

/etc/pam.d/ ostidagi yoki u ulaydigan fayldagi biror narsani o'zgartirishdan oldin:

  1. joriy, allaqachon autentifikatsiyadan o'tgan terminal sessiyangizni ochiq qoldiring — o'zgarish tekshirilmaguncha uni yopmang;
  2. avval faylning zaxira nusxasini oling: sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak-$(date +%F);
  3. o'zgarishni kiriting, keyin birinchisini yopmasdan, ikkinchi, yangi sessiyada autentifikatsiyani sinab ko'ring;
  4. agar yangi sessiya muvaffaqiyatsiz bo'lsa, hali ochiq turgan birinchi sessiyadan zaxira nusxani darhol tiklang;
  5. masofaviy serverda SSH’dan mustaqil, oxirgi chora sifatida out-of-band konsolni (masalan, hosting provayderining web konsolini) tayyor saqlang.

Stack’ni boshqarishni distributivga topshirish

/etc/pam.d/common-auth ni to'g'ridan-to'g'ri qo'lda tahrirlash ishlaydi, lekin Debian/Ubuntu’da odatda pam-auth-update orqali ishlagan yaxshiroq. U standart "profillar" to'plamini (Unix autentifikatsiyasi, pam_faillock va boshqalar) boshqaradi va hosil qilingan fayllarni bir-biriga mos holda saqlaydi:

sudo pam-auth-update
┌─────────────────┤ Configure Linux PAM ├──────────────────┐
│ Select the authentication profiles that should be enabled│
│ [*] Unix authentication                                  │
│ [ ] Faillock (lock out after failed attempts)            │
└────────────────────────────────────────────────────────────┘

RHEL oilasida uning ekvivalenti — authselect:

sudo authselect current
Profile ID: sssd
Enabled features: with-faillock

Ikkala vosita ham aynan qo'lda tahrirlangan PAM stack’larida nozik xato qilish oson bo'lgani va ularni serverlar parki bo'ylab mazmunli taqqoslash (diff) qiyin bo'lgani uchun mavjud. sudo xavfsizligi maqolasida sudoers uchun keltirilgan markazlashtirish dalili bu yerda ham amal qiladi.

Keng tarqalgan xatolar

  • PAM faylini zaxira sessiya ochiq bo'lmagan holda tahrirlash. Yuqorida ko'rib chiqilganidek, bu PAM bilan bog'liq eng xavfli xato: sintaksis xatosi yoki haddan tashqari cheklovchi requisite qatori barcha akkauntlarni birdaniga qulflab qo'yishi mumkin.
  • Tarmoqqa qaragan servisda aniq sababsiz pam_unix.so da nullok/nullok_secure ni qoldirish. Bu shadow parol maydoni bo'sh bo'lgan har qanday akkauntga parolsiz autentifikatsiyadan o'tishga imkon beradi.
  • Debian/Ubuntu’da pam-auth-update o'rniga common-auth ni qo'lda tahrirlash. To'g'ridan-to'g'ri tahrirlar keyingi safar pam-auth-update ishga tushganda (masalan, o'z profilini ro'yxatdan o'tkazadigan paket o'rnatilgandan keyin) jimgina qayta yozib yuboriladi va o'zgarish aniq sababsiz yo'qoladi.
  • pam_limits cron vazifasi yoki systemd servisiga ham qo'llaniladi deb kutish. session bosqichidagi PAM modullari faqat PAM’ning session ishlovidan haqiqatan o'tadigan sessiyalar uchun ishlaydi. Login shell yoki SSH sessiyasi undan o'tadi, cron vazifasi yoki systemd unit’i esa odatda o'tmaydi.

Mashqlar

  1. Lab tizimida (yoki kirish huquqingiz bor haqiqiy tizimda) /etc/pam.d/sshd ni o'qing va to'rtta PAM turining har biridan bittadan qatorni aniqlang.
  2. Tizimingizning pam_unix.so qatorlarida biror joyda nullok yoki nullok_secure borligini tekshiring va uni olib tashlash nimani o'zgartirishini tushuntiring.
  3. /etc/security/limits.conf da test guruhi uchun nofile soft cheklovini o'rnating, shu guruh a’zosi sifatida tizimga kiring va cheklovni ulimit -n bilan tekshiring.
  4. Buzilgan PAM stack’ini masofadan tuzatish buzilgan sudoers faylidan nega xavfliroq deyish mumkinligini va bu xavfni qanday ehtiyot chorasi yo'qqa chiqarishini tushuntiring.

Xulosa

PAM — sudo, su, login, sshd va boshqalar ortidagi umumiy autentifikatsiya framework’i. U auth, account, password va session modullaridan iborat stack bo'lib, ularning har birini natijasi umumiy natijaga qanday ta’sir qilishini hal qiladigan flag boshqaradi. pam_unix an’anaviy shadow fayl tekshiruvini, pam_limits har bir sessiya uchun resurs chegaralarini ta’minlaydi, pam_env esa tizimga kirishda muhit o'zgaruvchilarini o'rnatadi. Root va sudo maqolasida chuqur ko'rib chiqilgan pam_faillock takroriy muvaffaqiyatsiz urinishlardan keyin akkauntlarni bloklaydi. PAM tizimga kirishning o'zini boshqargani uchun har bir o'zgarishdan oldin zaxira sessiya ochiq bo'lishi kerak. Keyingi maqola, Parol siyosatlari, bevosita shu poydevorga quriladi — pam_pwquality va pam_pwhistory password turidagi PAM modullari.

Manbalar