Автентифікація за паролем через SSH — найбільша відкрита поверхня, яку має звичайний сервер. Проти неї не допомагають ні Fail2ban, ні будь-який поріг: тисяча адрес з однією спробою на годину ніколи не досягне ліміту й підбиратиме рівно доти, доки підбір узагалі можливий. Ключі прибирають саму цю можливість, і з усього списку загартовування це єдине налаштування, яке змінює ситуацію якісно.

Лякає в цьому лише одне: вимкнути пароль і залишитися зовні. Ось порядок, за якого цього не станеться.

Ключ

Генерується на вашій машині, а не на сервері:

ssh-keygen -t ed25519 -C "work laptop"

ed25519 замість RSA: коротший, швидший і без питань про довжину. RSA потрібен лише тоді, коли треба дістатися до чогось дуже старого; тоді -t rsa -b 4096.

Парольну фразу на ключ поставити варто: файл ключа можна вкрасти з ноутбука, і без фрази він працює одразу. Набирати її щоразу не доведеться — це бере на себе ssh-agent, і на macOS та в більшості настільних систем Linux він уже запущений.

Копіювання на сервер — одна команда, поки пароль ще працює:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@203.0.113.25

Якщо ssh-copy-id недоступний, вміст файла .pub додається рядком до ~/.ssh/authorized_keys на сервері. Права мають значення: каталог .ssh 700, файл 600, власник — користувач. За будь-яких інших sshd мовчки відмовляється читати файл, і це найчастіша причина того, що «ключ не працює».

Перевірка, яка все вирішує

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

ssh -o PasswordAuthentication=no user@203.0.113.25

Опція забороняє клієнту повертатися до пароля — отже, якщо вхід удався, він удався за ключем. Доки ця команда не спрацює, далі не рухайтеся. І тримайте перше з’єднання відкритим до самого кінця: саме воно виправить усе, що ви встигнете зламати.

Вимкнення паролів і одна неочевидна пастка

Налаштування кладуть в окремий файл, щоб оновлення пакета їх не перезаписало. Але назва файла має значення:

sudo tee /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PasswordAuthentication no
PermitRootLogin no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LogLevel VERBOSE
EOF

Річ у тім, що OpenSSH використовує перше знайдене значення параметра, а не останнє, як майже всюди. Файли в sshd_config.d читаються за абеткою, а хмарні образи Ubuntu кладуть туди 50-cloud-init.conf, у якому часто є PasswordAuthentication yes. Ваш файл із номером 90 у такій ситуації не зробить нічого: налаштування начебто на місці, а пароль продовжує працювати. Звідси й номер 10 — він читається раніше.

Що вийшло насправді, можна побачити без здогадів:

sudo sshd -T | grep -Ei 'passwordauth|permitrootlogin|pubkeyauth'

Ця команда виводить чинну конфігурацію після всіх включень. Довіряйте їй, а не вмісту файлів.

Далі — перевірка синтаксису і м’яке перезавантаження служби:

sudo sshd -t && sudo systemctl reload ssh

sshd -t обов’язковий: одруківка в конфігурації разом із restart залишає службу лежачою, а вас — зовні. reload до того ж не рве відкриті сесії.

Ubuntu 24.04: порт не там, де ви думаєте

Окрема пастка на свіжих Ubuntu: sshd там запускається через сокет systemd. У цьому режимі рядок Port у sshd_config не робить нічого — слухає сокет, а не демон. Якщо ви змінюєте порт, редагувати треба саме це:

sudo systemctl edit ssh.socket

і ListenStream= (порожнє значення скидає попереднє) має вказувати новий порт. Симптом, який це видає: конфігурацію змінено, службу перезапущено, а сервер усе одно відповідає на 22.

Раз уже зайшла мова про зміну порту: як захист вона не працює — сканери знаходять службу на будь-якому порту за лічені хвилини. Єдиний ефект — тихіші журнали, бо масовий підбір іде лише на 22. Це зручно, але не плутайте це з безпекою.

Кому взагалі можна заходити

Корисне доповнення — явний список:

AllowUsers deploy admin

Усе, чого немає в списку, відсікається ще до перевірки ключа. Це закриває й випадок, коли якийсь пакет створює системного користувача з оболонкою й домашнім каталогом.

Запасний шлях усередину

Один ключ на одному ноутбуці — єдина точка відмови. Диск помирає, ноутбук губиться, і сервер стає недосяжним назавжди. Розумний мінімум:

  • другий ключ з іншого пристрою в authorized_keys;
  • копія приватного ключа в менеджері паролів або на зашифрованій флешці;
  • перевірений доступ до консолі в провайдера — VNC або послідовний. Перевірений означає, що ви заходили через нього хоча б раз, а не що «десь у панелі є кнопка».

Заразом подивіться, що вже лежить у authorized_keys — і у вашого користувача, і в root. Чужий ключ там переживає будь-яку зміну пароля й лишається робочим доступом.

Що далі

Підбір паролів нікуди не подінеться, він просто стане марним: у журналах і далі накопичуватимуться тисячі рядків Failed password, жоден з яких не може завершитися успіхом. Стежити тепер варто за успішними входами: з якої адреси, під яким користувачем, о котрій годині. Успішний вхід за ключем із незнайомої адреси — значно важливіша подія, ніж мільйон невдач, і помітити її в загальному потоці набагато складніше. Саме цю картину показує демосторінка нижче.