Ubuntu 24.04: SSH працював вчора, тепер «Permission denied» — виправте 5 найпоширеніших причин

Було корисно?

09:12. У вас відкритий деплой, колега чекає, а термінал почав відповідати двома найменш корисними словами в операційному житті: Permission denied. Вчора ви могли під’єднатись по SSH до машини. Сьогодні — ні. Нічого «не змінилось», але насправді все змінюється.

Це польовий посібник для Ubuntu 24.04 (Noble), коли SSH перестає вас пускати. Не теорія — робоча реальність: ключі, що раніше працювали, облікові записи, що існували, конфіги, які «повинні бути в порядку», і політики, що тихо блокують доступ, запевняючи, що ви не праві.

Швидкий план діагностики (перший/другий/третій)

Коли SSH раптово змінюється з «працює» на «permission denied», не починайте з правки випадкових файлів. Почніть з доказів: що відбувається, де це ламається і яка сторона вас «бреше». Ось найшвидший шлях, який я знаю і що не створює нових проблем у погоні за старими.

Перший крок: підтвердіть, що ви підключаєтесь до правильної машини й від імені правильного користувача

  1. Вирішіть ціль і зафіксуйте шлях. Підтвердіть відповідність хостнейма → IP та чи йдете ви через bastion/ProxyJump.
  2. Підтвердіть ім’я користувача. «Permission denied» часто означає «невірний користувач» плюс «немає дозволених резервних методів автентифікації».
  3. Перевірте цілісність host key. Неправильний хост або перебудована машина проявляються як зміна host key, але люди часто «вирішують» це, видаляючи known_hosts і підключаючись до невірної машини.

Другий крок: зробіть один вербозний виклик клієнта і читайте його як лог

  1. Використайте -vvv один раз. Не гадіть; клієнт скаже, які ідентифікатори він пропонував і що прийнято чи відхилено.
  2. Визначте: воно ламається на виборі ключа, прийнятті host key чи авторизації облікового запису?

Третій крок: перегляньте логи сервера (або використайте консоль, якщо вас заблоковано)

  1. Якщо у вас є будь-який привілейований шлях (консоль хмарного провайдера, IPMI/iDRAC, серійна консоль, KVM), використайте його. Це не «обман» — за це ви платите.
  2. Читайте journalctl для sshd та повідомлень PAM/облікового запису.
  3. Виправляйте найвужчу річ, яка пояснює логи. Перезапуск sshd рідко вирішує проблему; найчастіше він перетворює невелику помилку в аварію.

Що насправді означає «Permission denied» в SSH

Повідомлення відоме своєю некорисністю, бо це зведення клієнта багатокрокової переговорної фази. На Ubuntu 24.04 з OpenSSH «Permission denied» зазвичай означає:

  • Сервер прийняв з’єднання, але жоден метод автентифікації не спрацював.
  • Сервер відхилив ваш ключ, пароль або keyboard-interactive спробу.
  • Або, більш тонко: автентифікація пройшла, але на етапі обробки облікового запису сталося відхилення (PAM, правила доступу, заблокований користувач, недійсний shell), і користувацький досвід зводиться до «Permission denied».

Є три широкі категорії причин:

  1. Проблеми на стороні клієнта з ідентифікацією: невірний ключ, невірний агент, невірний username, невірний stanza в конфігу.
  2. Проблеми на боці сервера з файлами/конфігом: пошкоджені права, Match блоки, нечитабельний authorized_keys, невірний шлях AuthorizedKeysFile тощо.
  3. Політика/облікові обмеження: обліковий запис заблоковано, прострочений, обмеження PAM, AllowUsers/DenyUsers, вимоги MFA не виконані.

Цитата, щоб не піддаватися спокусі «просто перезавантажити, поки працює»:

«Hope is not a strategy.» — Gene Kranz

Цікаві факти та коротка історія (бо це важливо)

Трохи контексту робить вас швидшими при діагностиці, бо ви перестаєте очікувати, що SSH поводиться як єдина монолітна річ. Це стек.

  1. SSH замінив rsh/telnet головно тому, що ці старі інструменти передавали облікові дані у відкритому вигляді. Модель безпеки SSH — причина, чому він примхливий, і чому ви теж повинні бути примхливими.
  2. Строгі перевірки прав OpenSSH — свідомі. Якщо ваш ~/.ssh має запис для групи, OpenSSH вважає, що хтось може інжектувати ключі. Краще лишити вас поза доступом, ніж бути «допоміжним».
  3. «Permission denied (publickey)» — це підсумок на стороні клієнта. Сервер може відхиляти ключі з багатьох причин: невірний тип ключа, невірний principal, погані права, обмеження forced-command або політика облікового запису.
  4. Host keys — це ідентичність сервера. Вони запобігають MITM-атакам. Коли люди сліпо видаляють known_hosts, вони на користь зручності відмовляються від виявлення атак.
  5. PAM може відхилити вас після успішної автентифікації. Саме тому логи важливі: ви можете «проавтентифікуватися» і все одно бути викинутим на стадії account/session.
  6. Параметри за замовчуванням OpenSSH змінюються. Алгоритми та розміри ключів, які були прийнятні десять років тому, зараз можуть бути відключені. Оновлення можуть «зламати» старі ключі, особливо слабкі RSA.
  7. Інтеграція OpenSSH в Ubuntu тісно пов’язана з systemd. Логи зазвичай у journald, і поведінка сервісу (наприклад socket activation у деяких налаштуваннях) може змінювати очікування.
  8. Cloud-образи часто використовують набір специфічних налаштувань SSH. Наприклад, відключені паролі, певні користувачі за замовчуванням і cloud-init, що управляє authorized_keys.

Причина #1: Ви не використовуєте той ключ, про який думаєте (агент, identity, файл)

Це найпоширеніша «працювало вчора» несправність у реальному житті, бо зазвичай сервер у порядку. Проблема — у вас, у вашому ноутбуці, у агенті, у конфігу, у VPN зі спліт-тунелю, у новому терміналі або в корпоративному інструменті управління, що щось повернув іншому режимі вночі.

Задача 1: Запустіть один вербозний виклик SSH і визначте, який ключ пропонується

cr0x@server:~$ ssh -vvv user@host.example.com
OpenSSH_9.6p1 Ubuntu-3ubuntu13, OpenSSL 3.0.13 30 Jan 2024
debug1: Reading configuration data /home/cr0x/.ssh/config
debug1: Connecting to host.example.com [203.0.113.10] port 22.
debug1: identity file /home/cr0x/.ssh/id_ed25519 type 3
debug1: identity file /home/cr0x/.ssh/id_rsa type 0
debug1: Offering public key: /home/cr0x/.ssh/id_ed25519 ED25519 SHA256:abc... agent
debug1: Authentications that can continue: publickey
debug1: Offering public key: /home/cr0x/.ssh/id_rsa RSA SHA256:def... agent
debug1: Authentications that can continue: publickey
user@host.example.com: Permission denied (publickey).

Що це означає: Ви запропонували два ключі. Обидва були відхилені. Це звужує поле: або на сервері немає відповідного публічного ключа в authorized_keys, або його не можуть прочитати, або політика сервера блокує вас.

Рішення: Якщо ви очікували інший ключ — виправляйте клієнт (явний -i, почистіть ~/.ssh/config або виправте агент). Якщо ви очікували, що один із цих ключів працюватиме — переходьте до перевірок на сервері (Причина #2 і #3).

Задача 2: Примусьте використати ключ і вимкніть плутанину з агентом

cr0x@server:~$ ssh -i ~/.ssh/prod_ed25519 -o IdentitiesOnly=yes -vv user@host.example.com
debug1: identity file /home/cr0x/.ssh/prod_ed25519 type 3
debug1: Offering public key: /home/cr0x/.ssh/prod_ed25519 ED25519 SHA256:xyz...
debug1: Authentications that can continue: publickey
user@host.example.com: Permission denied (publickey).

Що це означає: Ви однозначно запропонували потрібний ключ. Він усе одно не пройшов.

Рішення: Перестаньте крутити ноутбук. Перевірте, що на сервері є відповідний публічний ключ і що він читається.

Задача 3: Перевірте, які ключі фактично в агенті

cr0x@server:~$ ssh-add -l
256 SHA256:abc... /home/cr0x/.ssh/id_ed25519 (ED25519)
2048 SHA256:def... /home/cr0x/.ssh/id_rsa (RSA)

Що це означає: Це ідентифікатори, які ваш агент запропонує, якщо ви його не обмежите.

Рішення: Якщо потрібного ключа немає — додайте його (ssh-add ~/.ssh/prod_ed25519) або вкажіть SSH його явно з -i і IdentitiesOnly=yes. Якщо потрібний ключ є, але його відхиляють — ідемо на сервер.

Задача 4: Перевірте пріоритети конфігу SSH (мовчазна пастка)

cr0x@server:~$ ssh -G host.example.com | sed -n '1,80p'
user user
hostname host.example.com
port 22
identityfile ~/.ssh/id_ed25519
identitiesonly no
proxyjump bastion.example.com
pubkeyauthentication yes
passwordauthentication no

Що це означає: ssh -G показує фінальний обчислений конфіг. Якщо identityfile не такий, як ви очікуєте — або user не той — клієнт робить саме те, що ви йому сказали, просто не те, що ви мали на увазі.

Рішення: Виправте ~/.ssh/config, щоб для продакшен-хостів явно вказувати IdentityFile і IdentitiesOnly yes. Невизначеність хороша в романах, але не в контролі доступу.

Жарт у стилі сухого гумору #1: SSH-агенти — як «допоміжні» колеги: приходять без запрошення й впевнено підсовують не ті облікові дані.

Причина #2: На сервері зламалися права/власність (home, .ssh, authorized_keys)

Якщо авторизація ключем раніше працювала і раптом перестала, найпоширеніший серверний винуватець — зміна прав. Це трапляється після:

  • міграції домашнього каталогу,
  • надмірного chmod -R,
  • відновлення з бекапу з неправильною власністю,
  • зміни користувачів/груп (включно з централізованою ідентичністю),
  • або скрипта «хардінгу безпеки», що неправильно розумів правила OpenSSH.

Задача 5: Прочитайте логи сервера для причин відхилення ключа

Потрібен доступ до консолі або інший привілейований шлях, якщо SSH зовсім не працює.

cr0x@server:~$ sudo journalctl -u ssh -n 80 --no-pager
Aug 07 10:12:01 host sshd[12345]: Authentication refused: bad ownership or modes for directory /home/user
Aug 07 10:12:01 host sshd[12345]: Connection closed by authenticating user user 198.51.100.22 port 51234 [preauth]

Що це означає: Класика: права на домашній каталог користувача (або .ssh) надто відкриті, або власник некоректний.

Рішення: Виправте власність і права. Не «послаблюйте» sshd, щоб дозволити погані права; вирішіть проблему на файловій системі.

Задача 6: Перевірте власність і права для home та SSH файлів

cr0x@server:~$ sudo namei -l /home/user/.ssh/authorized_keys
f: /home/user/.ssh/authorized_keys
drwxr-xr-x root root /
drwxr-xr-x root root home
drwxrwxr-x user user user
drwxr-xr-x user user .ssh
-rw-r--r-- user user authorized_keys

Що це означає: /home/user має дозвіл на запис групи (drwxrwxr-x). Це вже достатня підстава для відмови OpenSSH, залежно від конфігурації. Навіть якщо .ssh виглядає нормально, батьківський каталог може провалити перевірку.

Рішення: Приберіть груповий запис на домашньому каталозі і переконайтесь, що власник правильний.

Задача 7: Застосуйте розумні права (хірургічно, а не рекурсивним хаосом)

cr0x@server:~$ sudo chown -R user:user /home/user/.ssh
cr0x@server:~$ sudo chmod 0755 /home/user
cr0x@server:~$ sudo chmod 0700 /home/user/.ssh
cr0x@server:~$ sudo chmod 0600 /home/user/.ssh/authorized_keys
cr0x@server:~$ sudo ls -ld /home/user /home/user/.ssh /home/user/.ssh/authorized_keys
drwxr-xr-x  9 user user 4096 Aug  7 10:00 /home/user
drwx------  2 user user 4096 Aug  7 10:01 /home/user/.ssh
-rw-------  1 user user  402 Aug  7 10:01 /home/user/.ssh/authorized_keys

Що це означає: Це консервативні значення за замовчуванням, які задовольняють sshd: home без запису для групи/інших; .ssh приватний; файл authorized_keys приватний.

Рішення: Повторно спробуйте підключення. Якщо все ще відмовляє і логи більше не скаржаться на власність/режими, переходьте до конфіг/політики.

Задача 8: Підтвердіть, що публічний ключ на сервері відповідає приватному ключу, яким ви користуєтесь

Це уникає «зайчика з чужою парою ключів».

cr0x@server:~$ ssh-keygen -lf /home/user/.ssh/authorized_keys | head -n 3
256 SHA256:xyz... comment@laptop (ED25519)
2048 SHA256:old... legacy@laptop (RSA)

Що це означає: Це відбитки публічних ключів у authorized_keys. Порівняйте з відбитком вашого клієнтського ключа.

Рішення: Якщо на сервері немає потрібного ключа — додайте його (краще через стандартний шлях провізування). Якщо ключ присутній — переходьте до конфігурації sshd і політик.

Причина #3: Змінено sshd конфіг (AllowUsers, Match blocks, auth methods)

На Ubuntu 24.04 зазвичай працюєте з OpenSSH, де конфіг розбитий між /etc/ssh/sshd_config і include-файлами в /etc/ssh/sshd_config.d/. Це добре. Це також спосіб, як «невелика» зміна стає сюрпризом.

Задача 9: Перевірте синтаксис і валідність конфігу sshd

cr0x@server:~$ sudo sshd -t
cr0x@server:~$ echo $?
0

Що це означає: Код виходу 0 означає, що синтаксис вірний. Нульовий — якщо синтаксис зламаний; у вас може ще працювати демон, але reload/restart не вдасться.

Рішення: Якщо синтаксис не валідний — виправте це. Якщо синтаксис вірний — перегляньте ефективні налаштування.

Задача 10: Виведіть ефективні налаштування sshd (правда, а не те, що ви пам’ятаєте)

cr0x@server:~$ sudo sshd -T | egrep -i 'passwordauthentication|pubkeyauthentication|authorizedkeysfile|allowusers|denyusers|permitrootlogin|match'
pubkeyauthentication yes
passwordauthentication no
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2
permitrootlogin prohibit-password

Що це означає: Це обчислений конфіг (без контексту Match, якщо ви його не тестували). Показує, чи дозволено password auth і де sshd очікує ключі.

Рішення: Якщо AuthorizedKeysFile вказує не там, де ви зберігаєте ключі — вони можуть бути в невірному місці. Якщо PubkeyAuthentication вимкнено — ось ваша причина. Якщо є Allow/Deny правила — перевірте їх далі.

Задача 11: Перевірте наявність Match блоків, що застосовуються до вашого користувача або джерела IP

cr0x@server:~$ sudo awk 'BEGIN{p=0} /^Match /{p=1} {if(p)print}' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf 2>/dev/null
Match User user
    AuthenticationMethods publickey
    X11Forwarding no

Що це означає: У вас є політика, прив’язана до конкретного користувача. Можливо, хтось додав AuthenticationMethods publickey (нормально), але видалив потрібний ключ, або поєднав з іншою вимогою, або встановив forced command, що тепер не працює.

Рішення: Переконайтесь, що Match блок відображає реальність. Якщо вимагаєте лише publickey — ключ має бути присутнім і читабельним. Якщо вимагаєте кілька методів — упевніться, що клієнт може їх виконати.

Задача 12: Підтвердіть, що sshd використовує той конфіг, який ви думаєте

cr0x@server:~$ systemctl status ssh --no-pager
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
     Active: active (running) since Wed 2025-08-07 09:59:10 UTC; 15min ago
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1122 (sshd)
      Tasks: 1 (limit: 2321)
     Memory: 2.3M
        CPU: 79ms
     CGroup: /system.slice/ssh.service
             └─1122 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Що це означає: sshd працює. Це добре. Це не означає, що він дозволяє вам доступ. Але це означає, що ви можете безпечно робити reload після змін у конфігу (перевіряйте sshd -t перед цим).

Рішення: Якщо ви змінили конфіг і не перезавантажили його — зробіть безпечний reload після валідації.

cr0x@server:~$ sudo sshd -t && sudo systemctl reload ssh

Що це означає: Reload застосовує конфіг без розриву існуючих сесій. Restart обриває сесії і може перетворити одну блокувальну помилку на багато блокувань.

Рішення: Віддавайте перевагу reload. Якщо reload не вдається — виправте конфіг і спробуйте знову; не перезавантажуйте з розпачу.

Причина #4: Обліковий запис/політика блокують вас (заблокований користувач, прострочений ключ, PAM, access.conf)

Це зона «все виглядає правильно, ключі співпадають, права в порядку, sshd здоровий, але я все одно не можу зайти». Тут приховані гострі предмети корпоративних середовищ: політики PAM, централізована ідентичність, прострочення облікових записів і «тимчасові» заборони, що стають постійними.

Задача 13: Перевірте, чи обліковий запис заблокований або прострочений

cr0x@server:~$ sudo passwd -S user
user L 2025-07-10 0 99999 7 -1

Що це означає: Позначка L вказує, що обліковий запис заблоковано. Залежно від PAM і конфігурації, SSH-автентифікація ключем може теж блокуватися на стадії account; у багатьох налаштуваннях заблокований пароль ефективно блокує входи.

Рішення: Якщо цей обліковий запис має бути доступним — розблокуйте його через процес зміни (change control). Якщо він має бути заблокований — не намагайтесь обходити політику; використайте правильний break-glass обліковий запис або робочий процес.

Задача 14: Перевірте, чи shell валідний (так, це ще трапляється)

cr0x@server:~$ getent passwd user
user:x:1001:1001:User,,,:/home/user:/usr/sbin/nologin

Що це означає: Shell облікового запису — /usr/sbin/nologin. SSH може автентифікуватися, але відмовити в сесії (часто виглядає як permission denied або миттєве відключення).

Рішення: Якщо користувачу потрібен shell-доступ — встановіть валідний shell, наприклад /bin/bash або інший стандартний. Якщо це навмисно — не боріться з налаштуванням.

Задача 15: Шукаймо обмеження PAM у логах

cr0x@server:~$ sudo journalctl -u ssh -n 120 --no-pager | egrep -i 'pam|account|access|denied|failure'
Aug 07 10:14:09 host sshd[12555]: pam_access(sshd:account): access denied for user `user' from `198.51.100.22'
Aug 07 10:14:09 host sshd[12555]: Failed password for user from 198.51.100.22 port 51288 ssh2

Що це означає: PAM відхиляє доступ на основі IP-адреси або правил. Рядок про метод автентифікації може вводити в оману; відмова явна.

Рішення: Перегляньте /etc/security/access.conf і PAM-стек для sshd. Виправте правило або припущення щодо джерела IP. Не вимикайте модулі PAM легковажно; ви отримаєте доступ, але втратите аудит/комплаєнс.

Задача 16: Перевірте конфіг PAM для sshd (які модулі виконуються)

cr0x@server:~$ sudo grep -nE 'pam_access|pam_sss|pam_faillock|pam_tally2' /etc/pam.d/sshd
15:account    required     pam_access.so
22:account    [default=bad success=ok user_unknown=ignore] pam_sss.so

Що це означає: pam_access.so активний. Це пояснює блоки за джерелом. pam_sss.so свідчить про централізовану ідентичність (SSSD).

Рішення: Якщо правила доступу надто суворі — відкоригуйте їх. Якщо SSSD не працює або неправильно налаштований — відновіть роботу служби ідентичності (не лише SSH).

Задача 17: Виявіть відмови SSSD / служби ідентичності, що маскуються під помилки SSH

cr0x@server:~$ systemctl status sssd --no-pager
● sssd.service - System Security Services Daemon
     Loaded: loaded (/usr/lib/systemd/system/sssd.service; enabled; preset: enabled)
     Active: active (running) since Wed 2025-08-07 08:01:44 UTC; 2h 13min ago

Що це означає: SSSD працює, але «працює» не означає «працює правильно». Проте мертва SSSD — легка перемога при діагностиці.

Рішення: Якщо SSSD впав — підніміть його. Якщо він працює — дивіться логи на предмет невдач пошуку облікових записів (це виходить за межі статті, але ви знаєте куди рухатися).

Причина #5: Це не та машина (host keys, DNS/IP, bastion, ProxyJump)

Фраза «SSH працював вчора» часто правдива. Просто вчора ви підключалися до іншої машини і не помітили. DNS-зміни, переназначення плаваючих IP, балансувальники навпроти SSH (так, так роблять) і bastion-и можуть створити цю ілюзію.

Задача 18: Підтвердіть DNS і маршрут до цілі

cr0x@server:~$ getent hosts host.example.com
203.0.113.10   host.example.com

Що це означає: Це IP, який ваша система використовує. Якщо він змінився з вчора — ви, ймовірно, стукаєте в інші двері.

Рішення: Якщо IP несподіваний — зупиніться і підтвердіть правильну ціль (інвентар, cloud console). Виправте DNS або оновіть SSH-конфіг, щоб використовувати стабільну адресу.

Задача 19: Перевірте невідповідність host key (чесне попередження)

cr0x@server:~$ ssh user@host.example.com
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Host key verification failed.

Що це означає: Або машина перебудована, або змінився DNS/IP, або хтось перехоплює трафік. В корпоративних мережах перебудови та повторне використання IP поширене; атаки менш імовірні, але вам не дозволено їх ігнорувати.

Рішення: Підтвердіть новий host key поза каналом (консоль, CMDB, логи провізування). Лише потім оновлюйте known_hosts.

Задача 20: Безпечно видаліть одну проблемну запис у known_hosts

cr0x@server:~$ ssh-keygen -R host.example.com
# Host host.example.com found: line 42
/home/cr0x/.ssh/known_hosts updated.
Original contents retained as /home/cr0x/.ssh/known_hosts.old

Що це означає: Ви видалили один запис хоста, а не знищили весь файл.

Рішення: Підключіться знову і перевірте відбиток. Якщо ви не можете його перевірити — не продовжуйте. «Мабуть, нормально» — саме так пишуться інцидентні звіти.

Задача 21: Підтвердіть шлях через ProxyJump/bastion (може блокуватися зверху)

cr0x@server:~$ ssh -G host.example.com | egrep -i 'proxyjump|proxycommand|hostname|user'
user user
hostname host.example.com
proxyjump bastion.example.com

Що це означає: Ваше з’єднання йде через bastion. Permission denied може відбуватися на рівні bastion, а не кінцевого хоста.

Рішення: Спробуйте підключитися до bastion напряму з вербозністю і підтвердіть автентифікацію там спочатку.

cr0x@server:~$ ssh -vvv user@bastion.example.com
debug1: Authentications that can continue: publickey
user@bastion.example.com: Permission denied (publickey).

Що це означає: Bastion відхиляє вас. Можливо, ціль у порядку.

Рішення: Виправляйте доступ до bastion (ключі, allowlist-и, політики) перш ніж чіпати кінцевий хост.

Жарт у стилі сухого гумору #2: Нічого так не загартовує характер, як годинне налагодження «Permission denied» — щоб потім виявити, що ви SSHились до стейджингової машини з продакшеновою впевненістю.

Три корпоративні міні-історії (реалістично, анонімізовано і повчально)

Міні-історія 1: Інцидент, спричинений неправильною припущенням

У них був флот серверів Ubuntu за bastion-ом. Доступ лише за ключами, паролі вимкнені, і компанія щойно розгорнула новий інструмент управління ноутбуками. Інструмент тихенько змінив інтеграцію SSH-агента — агент залишився, але більше не завантажував ті самі ключі за замовчуванням.

О 08:30 інженер намагався запатчити критичний CVE. SSH відповів Permission denied (publickey). Він припустив, що сервер зламався, бо «я нічого не міняв». Інший інженер отримав ту ж помилку і вирішив, що bastion впав. Вони відкрили інцидент, підключили платформний тайм і почали планувати екстрений доступ через консоль.

Логи на bastion-е були ясні: десятки відхилених ключів, жоден не відповідав потрібному відбитку. На клієнтах ssh -vvv показував агент, що пропонує старий RSA-ключ і GitHub-ключ — жоден не авторизований для продакшену. Вірний ключ лежав на диску, але не пропонувався, бо новий інструмент змінив поведінку агента й у ~/.ssh/config не було явного IdentityFile для bastion-а.

Виправлення було нудним: оновити SSH-конфіг, щоб прив’язати правильну ідентичність для bastion-а і встановити IdentitiesOnly yes. Постмортем теж був нудним — отже корисним: неправильне припущення було «сервер змінився». Сервер не змінився. Клієнт змінився.

Вони також додали передполітну перевірку в runbook: якщо SSH не працює, збирайте ssh -G і ssh -vvv перед ескалацією. Цей простий крок запобіг великій кількості майбутніх хибних тривог.

Міні-історія 2: Оптимізація, що дала протилежний ефект

Інша компанія провела «спринт жорсткого підвищення безпеки». Хтось вирішив стандартизувати права домашніх каталогів на всіх Linux-машинах. Скрипт виставив /home/* у 0775, щоб спільна група могла «допомагати в колаборації». Це виглядало нешкідливо. Навіть затверджено у тикеті, бо рецензент думав, що «group write» впливає лише на локальні редагування.

За кілька хвилин SSH авторизація ключем почала падати для підмножини користувачів. Не для всіх — лише для тих, чиї домашні стали group-writable і чиї sshd-настроювання зберегли строгі перевірки режимів (за замовчуванням). On-call бачив Permission denied (publickey) і думав, що ключі видалені або cloud-init перезаписав authorized_keys.

Логи sshd сказали правду: Authentication refused: bad ownership or modes for directory /home/user. Оптимізація (колаборація через group write) порушила перевірки OpenSSH. Спринт з жорсткого підвищення безпеки іронічно знизив безпеку, тому що люди почали пропонувати відключити строгі перевірки, щоб відновити доступ.

Виправили: повернули права домашніх до 0755 (або більш обмежувальні), і реалізували співпрацю через спільну проектну директорію з коректними ACL, а не послабленням меж домашніх. Також змінили скрипти, щоб застосовувати права лише до відомих безпечних шляхів, а не знищувати весь деревоподібний простір.

Урок: не «не автоматизуйте». Автоматизуйте розумно — розуміючи інваріанти системи. SSH залежить від інваріантів прав файлів. Порушіть їх — демон правильно припустить компрометацію.

Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію

Одна команда працювала на Ubuntu 24.04 на міксі фізичних хостів і cloud-інстансів. У них була проста практика: кожна зміна, що впливає на SSH, вимагала (1) валідації через sshd -t, (2) systemctl reload ssh, а не restart, і (3) відкриту другу сесію, перш ніж закривати першу.

Це не було ефектно. Не робилося для слайдів. Але це запобігло аваріям.

Під час maintenance інженер додав Match Address блок, щоб посилити автентифікацію з публічного інтернету і зберегти внутрішній доступ гладким. Конфіг був синтаксично валідний, але логічно неправильний: він потрапляв під більшу кількість адрес, ніж передбачалось, фактично застосувавши «публічні» правила до внутрішніх jump-хостів. Результат: люди почали отримувати відмови.

Оскільки вони використовували reload і мали другу сесію, вони ніколи не заблокували себе. Вони відразу перечитали логи, побачили поведінку match, виправили умову, знову зробили reload і перевірили з обох шляхів. Жодної драми, жодного консолі, жодних героїчних дій опівночі.

Практика, що врятувала їх — не геніальна. Вона дисциплінована: валідація, reload, тримати запасну сесію до підтвердження, що двері працюють.

Типові помилки: симптом → корінна причина → виправлення

Цей розділ суб’єктивний, бо описує те, що люди роблять під стресом. Якщо ви впізнали себе — вітаю: ви людина. Тепер припиніть це робити.

1) Симптом: «Permission denied (publickey)» після звичайного копіювання файлів на сервер

  • Корінна причина: Права ~/.ssh або домашнього каталогу змінились (group writable, невірний власник).
  • Виправлення: Використайте namei -l, щоб знайти першу проблемну директорію; встановіть home в 0755, .ssh в 0700, authorized_keys в 0600.

2) Симптом: Працює з одного ноутбука, не працює з іншого

  • Корінна причина: Інший ключ пропонується через розбіжності в агенті/конфігу; або джерело IP заблоковано правилами PAM/access.
  • Виправлення: Порівняйте ssh -G і ssh -vvv на обох машинах; перевірте логи сервера на відмови pam_access.

3) Симптом: «Permission denied» одразу після того, як ви «почистили» known_hosts

  • Корінна причина: Ви підключились до невірного хоста (DNS/IP змінився) і тепер довіряєте новому ключу сліпо, або ви на інстансі, що відновлений без правильних authorized_keys.
  • Виправлення: Підтвердіть IP цілі через getent hosts. Підтвердіть host key поза каналом. Потім перевірте, що authorized keys присутні й коректні.

4) Симптом: Ви можете автентифікуватися, але вас одразу відключає

  • Корінна причина: Невірний shell (/usr/sbin/nologin), forced command не виконується, або помилка PAM session-модуля.
  • Виправлення: Перевірте shell через getent passwd, перегляньте логи sshd і перевірте будь-які forced command або обмежене середовище.

5) Симптом: Заблокований лише один користувач; інші можуть заходити

  • Корінна причина: Match блок для цього користувача, невірний authorized_keys, заблокований обліковий запис або політика на рівні користувача.
  • Виправлення: Знайдіть Match User в sshd_config і sshd_config.d. Перевірте статус облікового запису через passwd -S. Виправте власність/режими домашнього каталогу цього користувача.

6) Симптом: Все зламалось відразу після оновлення OpenSSH/Ubuntu

  • Корінна причина: Застарілий алгоритм або тип ключа відключено; або поведінка sshd змінена вкладеними фрагментами конфігу.
  • Виправлення: Підтвердіть тип ключа (ssh-keygen -lf), віддавайте перевагу ED25519. Перегляньте ефективні налаштування через sshd -T і перевірте include-файли в /etc/ssh/sshd_config.d/.

Контрольні списки / покроковий план

Якщо вам потрібен план, який ви можете виконати під тиском — ось він. Сформульовано так, щоб мінімізувати побічні ефекти і максимально швидко отримати сигнал.

Контрольний список A: Тріаж на стороні клієнта (2 хвилини)

  1. Підтвердіть користувача/хост, до якого ви звертаєтесь (не смійтеся; зробіть це).
  2. Запустіть ssh -vvv один раз і збережіть вивід.
  3. Перевірте обчислений конфіг: ssh -G host | head.
  4. Перегляньте ключі агента: ssh-add -l.
  5. Повторіть спробу з прив’язаним ключем: ssh -i ~/.ssh/prod_ed25519 -o IdentitiesOnly=yes user@host.

Контрольний список B: Серверна частина «чому sshd мене відхилив?» (5–10 хвилин)

  1. Читайте логи: journalctl -u ssh -n 120.
  2. Якщо логи згадують власність/режими, запустіть namei -l /home/user/.ssh/authorized_keys.
  3. Виправте права (home, .ssh, authorized_keys), потім протестуйте знову.
  4. Якщо логи згадують PAM access — перегляньте /etc/pam.d/sshd та /etc/security/access.conf.
  5. Перевірте конфіг sshd: sshd -t та ефективні налаштування: sshd -T.
  6. Безпечно застосуйте зміни: systemctl reload ssh.

Контрольний список C: «Чи ми взагалі говоримо з правильною машиною?» (3 хвилини)

  1. Розв’яжіть хост: getent hosts host.example.com.
  2. Перевірте, чи змінився host key (не ігноруйте попередження).
  3. Якщо використовуєте bastion, протестуйте автентифікацію на bastion окремо.
  4. Підтвердіть, що відбиток SSH host key машини співпадає з очікуваним через консоль.

Операційні поради, які можна запозичити

  • Завжди тримайте одну робочу сесію відкритою під час змін, що стосуються SSH.
  • Використовуйте reload, а не restart, якщо не бажаєте спонтанних блокувань.
  • Не послаблюйте перевірки прав SSH, щоб «повернути доступ». Виправте права. Демон має рацію бути строгим.
  • Зробіть ідентичність явною у ~/.ssh/config для критичних хостів: шлях до ключа, користувач і IdentitiesOnly yes.

Питання та відповіді

1) Чому SSH каже «Permission denied», якщо мій ключ точно на сервері?

Бо «на сервері» — замало. sshd має вміти прочитати його, і має довіряти шляху до файлу. Погані права на /home/user або ~/.ssh часто призводять до мовчазного відхилення ключа з логом типу «bad ownership or modes».

2) Як дізнатись, який ключ намагається використати SSH?

Використайте ssh -vvv. Шукайте рядки на кшталт «Offering public key:» і «identity file … type …». Якщо пропонують ключ, який ви не очікували — змусьте потрібний за допомогою -i і IdentitiesOnly=yes.

3) Чи безпечно видаляти ~/.ssh/known_hosts?

Так само безпечно, як вимикати сигналізацію через те, що вона пищить. Видаляйте лише конкретний запис хоста за допомогою ssh-keygen -R, і лише після того, як перевірили новий відбиток хоста.

4) SSH працював, потім після перезавантаження зламався. Що змінилось?

Часто: служби ідентичності (SSSD) не піднялись, домашні каталоги змонтувались інакше, права змінились автоматизацією, або IP інстансу змінився і ви підключаєтесь до іншої машини. Починайте з логів (journalctl -u ssh) і перевірте, чи підключаєтесь до очікуваного IP.

5) Чи може заблокований пароль завадити входу по SSH ключу?

Так, залежно від PAM і політик облікових записів. Навіть якщо public key auth пройшла, стадія account у PAM може відхилити заблокований/просрочений обліковий запис. Перевірте через passwd -S user і логи PAM.

6) Я отримую лише «Permission denied (publickey)» і жодних інших методів. Чому?

Бо сервер, ймовірно, має PasswordAuthentication no і/або KbdInteractiveAuthentication no. Це звичайно й добре. Але це означає, що ваш шлях до ключа має бути коректним, а ключ — авторизований і читаємий.

7) Яка найшвидша серверна команда, щоб побачити, чи конфіг sshd — проблема?

sudo sshd -T для виведення ефективних налаштувань і sudo sshd -t для перевірки синтаксису. Поєднайте з journalctl -u ssh, щоб побачити, чому демон вас відхиляє.

8) Чому SSH відмовляє лише з офісної мережі, але працює з дому (або навпаки)?

Політика, що базується на джерелі: правила pam_access, firewall, AllowUsers з шаблонами user@host або Match блоки за адресою. Логи зазвичай показують точку рішення.

9) Я бачу «Authentication refused: bad ownership or modes», але все виглядає нормально в ~/.ssh. Що робити?

Перевірте весь шлях за допомогою namei -l. Погані права часто на /home/user або батьківській директорії, а не в самому .ssh.

10) Чи варто перезапускати sshd під час налагодження?

Віддавайте перевагу systemctl reload ssh після sshd -t. Перезапуск може обірвати останню робочу сесію і перетворити виправлення в блокування. Reload — дорослий вибір.

Практичні наступні кроки

Якщо SSH працював вчора, а сьогодні — «Permission denied», ваше завдання — перетворити цю невизначену скаргу на одну з п’яти конкретних причин: невірний ключ, погані права, конфіг sshd, політика облікового запису або невірний цільовий хост. Не імпровізуйте — вимірюйте.

  1. Запустіть ssh -vvv і визначте, який ключ пропонується і відхилюється.
  2. Підтвердіть обчислений клієнтський конфіг через ssh -G і прив’яжіть правильну ідентичність.
  3. На сервері прочитайте journalctl -u ssh. Він зазвичай каже реальну причину.
  4. Виправте права, використовуючи namei -l, щоб знайти першу небезпечну директорію в шляху.
  5. Перевірте конфіг sshd через sshd -t, підтвердіть ефективні налаштування sshd -T і безпечно зробіть reload.
  6. Коли логи вказують на PAM або стан облікового запису — розглядайте це як інцидент ідентичності/політики, а не лише як проблему SSH.

І коли ви знову отримаєте доступ: зробіть SSH детермінованим. Явні ключі для кожного хоста, суворі права і runbook, що починається з логів. Майбутній ви буде втомленим і заслуговуватиме на таку турботу.

← Попередня
Оновлення Ubuntu 24.04 зламали модулі ядра: правильно перебудуйте initramfs (випадок №28)
Наступна →
Управління ключами ZFS: Частина, яку всі забувають до Дня Катастрофи

Залишити коментар