09:12. У вас відкритий деплой, колега чекає, а термінал почав відповідати двома найменш корисними словами в операційному житті: Permission denied. Вчора ви могли під’єднатись по SSH до машини. Сьогодні — ні. Нічого «не змінилось», але насправді все змінюється.
Це польовий посібник для Ubuntu 24.04 (Noble), коли SSH перестає вас пускати. Не теорія — робоча реальність: ключі, що раніше працювали, облікові записи, що існували, конфіги, які «повинні бути в порядку», і політики, що тихо блокують доступ, запевняючи, що ви не праві.
Швидкий план діагностики (перший/другий/третій)
Коли SSH раптово змінюється з «працює» на «permission denied», не починайте з правки випадкових файлів. Почніть з доказів: що відбувається, де це ламається і яка сторона вас «бреше». Ось найшвидший шлях, який я знаю і що не створює нових проблем у погоні за старими.
Перший крок: підтвердіть, що ви підключаєтесь до правильної машини й від імені правильного користувача
- Вирішіть ціль і зафіксуйте шлях. Підтвердіть відповідність хостнейма → IP та чи йдете ви через bastion/ProxyJump.
- Підтвердіть ім’я користувача. «Permission denied» часто означає «невірний користувач» плюс «немає дозволених резервних методів автентифікації».
- Перевірте цілісність host key. Неправильний хост або перебудована машина проявляються як зміна host key, але люди часто «вирішують» це, видаляючи known_hosts і підключаючись до невірної машини.
Другий крок: зробіть один вербозний виклик клієнта і читайте його як лог
- Використайте
-vvvодин раз. Не гадіть; клієнт скаже, які ідентифікатори він пропонував і що прийнято чи відхилено. - Визначте: воно ламається на виборі ключа, прийнятті host key чи авторизації облікового запису?
Третій крок: перегляньте логи сервера (або використайте консоль, якщо вас заблоковано)
- Якщо у вас є будь-який привілейований шлях (консоль хмарного провайдера, IPMI/iDRAC, серійна консоль, KVM), використайте його. Це не «обман» — за це ви платите.
- Читайте
journalctlдляsshdта повідомлень PAM/облікового запису. - Виправляйте найвужчу річ, яка пояснює логи. Перезапуск sshd рідко вирішує проблему; найчастіше він перетворює невелику помилку в аварію.
Що насправді означає «Permission denied» в SSH
Повідомлення відоме своєю некорисністю, бо це зведення клієнта багатокрокової переговорної фази. На Ubuntu 24.04 з OpenSSH «Permission denied» зазвичай означає:
- Сервер прийняв з’єднання, але жоден метод автентифікації не спрацював.
- Сервер відхилив ваш ключ, пароль або keyboard-interactive спробу.
- Або, більш тонко: автентифікація пройшла, але на етапі обробки облікового запису сталося відхилення (PAM, правила доступу, заблокований користувач, недійсний shell), і користувацький досвід зводиться до «Permission denied».
Є три широкі категорії причин:
- Проблеми на стороні клієнта з ідентифікацією: невірний ключ, невірний агент, невірний username, невірний stanza в конфігу.
- Проблеми на боці сервера з файлами/конфігом: пошкоджені права, Match блоки, нечитабельний authorized_keys, невірний шлях AuthorizedKeysFile тощо.
- Політика/облікові обмеження: обліковий запис заблоковано, прострочений, обмеження PAM, AllowUsers/DenyUsers, вимоги MFA не виконані.
Цитата, щоб не піддаватися спокусі «просто перезавантажити, поки працює»:
«Hope is not a strategy.» — Gene Kranz
Цікаві факти та коротка історія (бо це важливо)
Трохи контексту робить вас швидшими при діагностиці, бо ви перестаєте очікувати, що SSH поводиться як єдина монолітна річ. Це стек.
- SSH замінив rsh/telnet головно тому, що ці старі інструменти передавали облікові дані у відкритому вигляді. Модель безпеки SSH — причина, чому він примхливий, і чому ви теж повинні бути примхливими.
- Строгі перевірки прав OpenSSH — свідомі. Якщо ваш
~/.sshмає запис для групи, OpenSSH вважає, що хтось може інжектувати ключі. Краще лишити вас поза доступом, ніж бути «допоміжним». - «Permission denied (publickey)» — це підсумок на стороні клієнта. Сервер може відхиляти ключі з багатьох причин: невірний тип ключа, невірний principal, погані права, обмеження forced-command або політика облікового запису.
- Host keys — це ідентичність сервера. Вони запобігають MITM-атакам. Коли люди сліпо видаляють
known_hosts, вони на користь зручності відмовляються від виявлення атак. - PAM може відхилити вас після успішної автентифікації. Саме тому логи важливі: ви можете «проавтентифікуватися» і все одно бути викинутим на стадії account/session.
- Параметри за замовчуванням OpenSSH змінюються. Алгоритми та розміри ключів, які були прийнятні десять років тому, зараз можуть бути відключені. Оновлення можуть «зламати» старі ключі, особливо слабкі RSA.
- Інтеграція OpenSSH в Ubuntu тісно пов’язана з systemd. Логи зазвичай у journald, і поведінка сервісу (наприклад socket activation у деяких налаштуваннях) може змінювати очікування.
- 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 хвилини)
- Підтвердіть користувача/хост, до якого ви звертаєтесь (не смійтеся; зробіть це).
- Запустіть
ssh -vvvодин раз і збережіть вивід. - Перевірте обчислений конфіг:
ssh -G host | head. - Перегляньте ключі агента:
ssh-add -l. - Повторіть спробу з прив’язаним ключем:
ssh -i ~/.ssh/prod_ed25519 -o IdentitiesOnly=yes user@host.
Контрольний список B: Серверна частина «чому sshd мене відхилив?» (5–10 хвилин)
- Читайте логи:
journalctl -u ssh -n 120. - Якщо логи згадують власність/режими, запустіть
namei -l /home/user/.ssh/authorized_keys. - Виправте права (home,
.ssh,authorized_keys), потім протестуйте знову. - Якщо логи згадують PAM access — перегляньте
/etc/pam.d/sshdта/etc/security/access.conf. - Перевірте конфіг sshd:
sshd -tта ефективні налаштування:sshd -T. - Безпечно застосуйте зміни:
systemctl reload ssh.
Контрольний список C: «Чи ми взагалі говоримо з правильною машиною?» (3 хвилини)
- Розв’яжіть хост:
getent hosts host.example.com. - Перевірте, чи змінився host key (не ігноруйте попередження).
- Якщо використовуєте bastion, протестуйте автентифікацію на bastion окремо.
- Підтвердіть, що відбиток 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, політика облікового запису або невірний цільовий хост. Не імпровізуйте — вимірюйте.
- Запустіть
ssh -vvvі визначте, який ключ пропонується і відхилюється. - Підтвердіть обчислений клієнтський конфіг через
ssh -Gі прив’яжіть правильну ідентичність. - На сервері прочитайте
journalctl -u ssh. Він зазвичай каже реальну причину. - Виправте права, використовуючи
namei -l, щоб знайти першу небезпечну директорію в шляху. - Перевірте конфіг sshd через
sshd -t, підтвердіть ефективні налаштуванняsshd -Tі безпечно зробіть reload. - Коли логи вказують на PAM або стан облікового запису — розглядайте це як інцидент ідентичності/політики, а не лише як проблему SSH.
І коли ви знову отримаєте доступ: зробіть SSH детермінованим. Явні ключі для кожного хоста, суворі права і runbook, що починається з логів. Майбутній ви буде втомленим і заслуговуватиме на таку турботу.