Tarkibga o'tish

SSH kalit autentifikatsiyasi

SSH asoslari maqolasidagi har bir ulanish parol so'rovi bilan tugadi va uning yakuniy izohi muammoni allaqachon ko'rsatib o'tgan edi: parolni brute-force bilan topish mumkin, uni har bir kirishda qo'lda yozish kerak va agar u biror joyda oshkor bo'lsa, unga ega bo'lgan har kim kira oladi. Standart yechim — SSH kalit juftligi bilan autentifikatsiya. Bu maqola kalit juftligi aslida qanday ishlashini, uni qanday yaratishni va serverga qanday o'rnatishni ko'rib chiqadi.

Asimmetrik kriptografiya: amaliy qismi

SSH kalit autentifikatsiyasi asimmetrik kriptografiyaga asoslangan: matematik jihatdan bog'liq ikkita kalit birga yaratiladi —

  • private key (yopiq kalit) — faqat sizning mashinangizda qoladi va hech qachon hech qayerga, hech kimga yuborilmaydi;
  • public key (ochiq kalit) — istalgan sondagi serverlarga nusxalanishi mumkin, chunki undan private key’ni qayta tiklab bo'lmaydi.

Autentifikatsiya paytida server tasodifiy ma’lumot bo'lagini yuboradi, klient uni private key bilan imzolaydi, server esa o'zida allaqachon saqlanayotgan public key yordamida shu imzoni tekshiradi. Imzo to'g'ri chiqsa, demak klientda mos private key bor — tarmoq orqali hech qachon parol o'tmaydi.

Bundan kelib chiqadigan qoida oddiy: public key serverlarga boradi; private key hech qachon mashinangizdan chiqmaydi. Ikkalasini adashtirish yoki private key’ni serverga nusxalash keng tarqalgan va jiddiy xato.

ssh-keygen: kalit juftligini yaratish

ssh-keygen -t ed25519 -C "alice@laptop"
  • -t ed25519 — kalit algoritmini tanlaydi. Ed25519 zamonaviy, tez va kriptografik jihatdan kuchli bo'lib, yangi tizimlar uchun sukut bo'yicha tanlov. Uni qo'llab-quvvatlamaydigan eski serverlarda zaxira variant — -t rsa -b 4096 (4096 bitli RSA);
  • -C — kalitga izoh biriktiradi, odatda user@machine ko'rinishida; bu keyinroq bir nechta kalit to'planganda qaysi kalit qayerdan kelganini ajratishni osonlashtiradi.

Buyruq ishga tushgach, u bir nechta narsani so'raydi:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/alice/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
  • fayl yo'lini odatda o'zgartirish shart emas — ko'p vositalar kalitni avtomatik ravishda sukut bo'yicha joydan (~/.ssh/id_ed25519) qidiradi;
  • passphrase private key faylining o'zini shifrlaydi (quyida alohida ko'rib chiqiladi).

Natijada ikkita fayl hosil bo'ladi:

~/.ssh/id_ed25519       # private key — never share this
~/.ssh/id_ed25519.pub   # public key — safe to copy to servers

Fayl ruxsatlarini tekshirish:

ls -l ~/.ssh/id_ed25519*
-rw------- 1 alice alice 411 Jul 25 10:02 /home/alice/.ssh/id_ed25519
-rw-r--r-- 1 alice alice  98 Jul 25 10:02 /home/alice/.ssh/id_ed25519.pub

Private key fayli 600 bo'lishi shart (faqat egasi o'qiy va yoza oladi) — OpenSSH klienti bundan kengroq ruxsatli kalit faylidan foydalanishni rad etadi. Bunday ruxsatlar modelining mantiqi Fayl ruxsatlari maqolasida ko'rib chiqilgan.

Public key’ni serverga o'rnatish

ssh-copy-id bilan (tavsiya etilgan usul)

ssh-copy-id [email protected]

Bu buyruq serverga allaqachon ishlayotgan autentifikatsiya usuli (odatda parol) bilan ulanadi, ~/.ssh/id_ed25519.pub mazmunini masofaviy ~/.ssh/authorized_keys fayliga qo'shadi va shu jarayonda katalog hamda fayl ruxsatlarini to'g'ri o'rnatadi. Muvaffaqiyatli ishga tushish shunday ko'rinadi:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

Qo'lda o'rnatish (ssh-copy-id mavjud bo'lmaganda)

cat ~/.ssh/id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Bu bitta qator bir vaqtda bir nechta ishni bajaradi: agar ~/.ssh mavjud bo'lmasa, uni yaratadi, uni 700 ga o'rnatadi, public key’ni authorized_keys oxiriga qo'shadi va bu faylni 600 ga o'rnatadi. Bu ruxsat qadamlarining har biri muhim — OpenSSH server quyida tushuntiriladigan xavfsizlik sabablariga ko'ra haddan tashqari ochiq .ssh katalogi yoki authorized_keys faylini indamay e’tiborsiz qoldiradi yoki butunlay rad etadi.

authorized_keys: tuzilishi va mantiqi

~/.ssh/authorized_keys serverdagi har bir foydalanuvchining uy katalogida turadi va shu foydalanuvchi sifatida kirishga ruxsat berilgan public key’larni ro'yxatlaydi. Har bir qator — bitta kalit:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGx3k9F... alice@laptop
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHq2mPZ... alice@work-desktop

Bitta foydalanuvchi bir nechta qurilmadan (noutbuk, ish kompyuteri) kirishi uchun har bir qurilmaning public key’i shu faylga alohida qator sifatida qo'shiladi. Bitta kalitni bir nechta qurilmada qayta ishlatmaslik kerak, chunki qurilmalardan biri buzib olinsa, uni yopish uchun faqat o'sha bitta qatorni olib tashlash kifoya bo'ladi.

Kalit autentifikatsiyasi sozlangach, ulanish endi parol so'ramaydi:

Enter passphrase for key '/home/alice/.ssh/id_ed25519':

(Agar kalit yaratilganda passphrase o'rnatilgan bo'lsa — bu server tomonidagi parol emas, private key faylining o'zini himoya qiladigan passphrase; u keyingi bo'limda tushuntiriladi.)

Passphrase: nega va qachon

Passphrase private key faylining o'zi diskda shifrlangan holda saqlanishini ta’minlaydi. Agar noutbuk o'g'irlansa yoki private key fayliga ruxsatsiz kirilsa, passphrase’siz kalitdan darhol foydalanish mumkin; passphrase bilan himoyalangan kalit esa baribir avval passphrase’ni talab qiladi.

Tip

Shaxsiy ish stantsiyasi yoki noutbukdagi kalitlar uchun passphrase o'rnatish tavsiya etiladi. Avtomatlashtirilgan skriptlar yoki CI/CD tizimlari ishlatadigan kalitlar odatda passphrase’siz yaratiladi, chunki avtomatlashtirilgan jarayon passphrase’ni interaktiv tarzda kirita olmaydi — bunday holatda kalit buning o'rniga alohida, kirish huquqi cheklangan xizmat hisobida saqlanishi kerak.

Har safar foydalanishda passphrase yozish zerikarli bo'lishi mumkin — buni ssh-agent hal qiladi: u passphrase’ni sessiyada bir marta so'raydi va shundan keyin uni xotirada saqlaydi. Bu SSH-agent va host tekshiruvi maqolasida ko'rib chiqiladi.

Amaliy vaziyat: "Permission denied (publickey)" ni aniqlash

Muammo: kalit yaratildi, ssh-copy-id muvaffaqiyatli ishladi, lekin ssh [email protected] baribir quyidagini qaytaryapti:

[email protected]: Permission denied (publickey).

1-qadam — klient aslida qaysi kalitni taklif qilayotganini ko'rish:

-v chiqishidan Offering public key qatorlarini qidiring — noto'g'ri kalit fayli birinchi bo'lib sinab ko'rilayotgan bo'lishi mumkin (masalan, bir nechta kalit mavjud bo'lsa va noto'g'risi ustun kelsa).

2-qadam — serverdagi authorized_keys mazmunini tekshirish (agar boshqa kirish usuli hali mavjud bo'lsa):

cat ~/.ssh/authorized_keys

Yozuv mavjudligini va klientdagi id_ed25519.pub fayli mazmuniga aynan mos kelishini tasdiqlang.

3-qadam — ruxsatlarni tekshirish:

ls -ld ~/ ~/.ssh ~/.ssh/authorized_keys
drwxr-xr-x 5 alice alice 4096 Jul 25 09:40 /home/alice
drwx------ 2 alice alice 4096 Jul 25 09:41 /home/alice/.ssh
-rw------- 1 alice alice  103 Jul 25 09:41 /home/alice/.ssh/authorized_keys

OpenSSH server bu yerda xavfsizlik sababli qattiqqo'l: agar foydalanuvchining uy katalogi, .ssh katalogi yoki authorized_keys ning o'zi guruh yoki boshqalar tomonidan yozish mumkin bo'lsa (masalan, drwxrwxr-x), server bu faylni ataylab e’tiborsiz qoldiradi — chunki nazariy jihatdan uni boshqa foydalanuvchi o'zgartirgan bo'lishi mumkin. Bunday holatda hech qanday xato xabari chiqmaydi; kalit shunchaki ishlamaydi.

4-qadam — server log'laridan tasdiqlash (agar hali boshqa yo'l bilan kira olsangiz):

sudo journalctl -u ssh --since '5 min ago' | grep -i authentication

Log odatda aniq sababni aytadi — masalan, Authentication refused: bad ownership or modes for directory.

5-qadam — tuzatish va tekshirish:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Klientdan qayta ulaning va parol so'rovi endi chiqmasligini tasdiqlang.

6-qadam — hujjatlashtirish: aynan qaysi ruxsat noto'g'ri bo'lganini va nega (masalan, fayl boshqa jarayon tomonidan qattiqroq qiymat o'rniga 022 umask bilan yaratilgan) qayd qiling.

Keng tarqalgan xatolar

Private key’ni serverga yoki boshqa biror joyga nusxalash

Private key u yaratilgan mashinadan hech qachon chiqmasligi kerak — hatto o'zingizga tegishli boshqa serverga ham. Agar bir nechta qurilmaga kirish kerak bo'lsa, har biri o'z kalit juftligini yaratadi va serverlarga faqat public key’lar qo'shiladi.

Kalitni authorized_keys ga noto'g'ri qo'shish

Faylni > (qayta yozish) bilan ochish avval saqlangan barcha kalitlarni o'chirib yuboradi; har doim >> (oxiriga qo'shish) yoki ssh-copy-id dan foydalaning.

Fayl ruxsatlarini e’tiborsiz qoldirish

Yuqoridagi vaziyatda ko'rsatilganidek, bu kalit autentifikatsiyasi "sirli ravishda" ishlamay qolishining eng keng tarqalgan yagona sababi. Bunday bo'lganda avval ~, ~/.ssh va authorized_keys ruxsatlarini tekshiring.

Klientga bir vaqtda juda ko'p kalit taklif qilishga yo'l qo'yish

Bir nechta private key mavjud bo'lsa yoki ssh-agent ga ko'p identifikatsiyalar yuklangan bo'lsa, ssh ularni birma-bir taklif qiladi — server esa har birini muvaffaqiyatsiz urinish sifatida sanaydi. Serverning MaxAuthTries chegarasidan oshgach, u ishlaydigan kalitga yetib bormasdanoq ulanishni Received disconnect ... Too many authentication failures bilan uzadi. Buning oldini olish uchun aniq kalitni belgilang:

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 [email protected]

IdentitiesOnly=yes (uni SSH konfiguratsiyasi maqolasida ko'riladigan ~/.ssh/config da host bo'yicha ham yozish mumkin) klientga o'zi biladigan har bir identifikatsiyani emas, faqat -i/IdentityFile nomlagan kalitni taklif qilishni buyuradi.

Bitta kalitni bir nechta odam yoki xizmat o'rtasida bo'lishish

Har bir odam yoki xizmatning o'z kaliti bo'lishi kerak. Umumiy kalit keyinchalik aynan kim va qachon kirganini aniqlashni imkonsiz qiladi — bu audit va hodisalarga javob berish uchun real muammo.

Mashqlar

  1. ssh-keygen -t ed25519 bilan yangi kalit juftligini yarating, so'ng ls -l ~/.ssh/ chiqishidan private va public key fayllarining ruxsatlari nega har xil ekanini tushuntiring.
  2. Public key’ni laboratoriya serveriga ssh-copy-id bilan o'rnating va parolsiz kirish endi ishlashini tasdiqlang.
  3. Serverda ~/.ssh ga ataylab chmod 777 qo'llang, ulanishga urinib, muvaffaqiyatsizlikni kuzating, so'ng sababni journalctl orqali toping va ruxsatni tuzating.
  4. Boshqa fayl nomi bilan ikkinchi kalit juftligini yarating (masalan, ssh-keygen -t ed25519 -f ~/.ssh/id_work), uning public key’ini ham authorized_keys ga qo'shing va ssh -i ~/.ssh/id_work ... bilan aynan shu kalitdan foydalanib ulaning.

Mashqni bajardim deyish uchun: 3-mashqda tuzatishni qo'llashdan oldin ssh -v server kalitni ruxsatlar sababli faol rad etayotganini ko'rsatishi kerak (bu oddiy umumiy muvaffaqiyatsizlik sifatida emas, journalctl da ko'rinadi) — agar bunday log yozuvi chiqmasa, ehtimol siz mo'ljallangan ruxsatdan boshqa narsani buzgansiz.

Manbalar