Усі люблять «підвищення безпеки», поки не внесуть зміни, не перезавантажать sshd і не зрозуміють, що лишилися без єдиного шляху віддаленого доступу. Машина ще працює. Ви це відчуваєте. Але зайти не можете. Це не безпека — це самостворений простій.
Це орієнтований на продакшн посібник із посилення SSH для Ubuntu 24.04, який передбачає, що ви хочете міцнішу автентифікацію, меншу площу атаки та кращу аудитованість — без ставка на одну-єдину зміну. Ми навмисно підемо нудним шляхом: поетапні зміни, команди перевірки та плани відкату.
Принципи посилення, що запобігають блокуванням
Посилення SSH — це вправи з надійності, замасковані під задачу безпеки. Мета не «максимальна параноя». Мета — «мінімум жалю». Ось принципи, що збережуть вам роботу:
- Ніколи не змінюйте SSH одним кроком. Робіть зміни поетапно. Перевіряйте. Лише потім застосовуйте жорстко.
- Майте другий шлях доступу. Другу SSH-сесію, іншого користувача, інший метод автентифікації або консольний доступ (IPMI/KVM/серійна консоль хмари). Краще — два.
- Перевіряйте конфіг перед перезавантаженням. Використовуйте
sshd -tі виведіть ефективну конфігурацію, щоб упевнитися, що станеться. - Використовуйте блоки «Match», щоб обмежити ризики. Впровадьте суворі налаштування для більшості користувачів і залиште «break-glass» користувача обмеженим, але працездатним.
- Спочатку закрийте мережу, потім посилюйте автентифікацію. Обмеження того, хто може дістатися до SSH, безпечніше, ніж гадати, які клієнти зможуть погодити ваші нові криптоналаштування.
- Вимірюйте, перш ніж налаштовувати. Якщо ви не знаєте, які методи автентифікації використовуються зараз, ви зламаєте когось важливого о 2:00 ночі.
Цитата, яку варто пам’ятати: «Сподівання — не стратегія.»
— Gene Kranz. Коротко, трохи суворо і справедливо для операцій.
Жарт №1: Змінювати sshd_config у п’ятницю — чудовий спосіб дізнатися, наскільки хороша ваша ротація на виклики.
Цікаві факти та історичний контекст (бо це пояснює сьогоднішні налаштування за замовчуванням)
- SSH замінив Telnet здебільшого тому, що Telnet передавав облікові дані в незашифрованому вигляді. Це було не «трохи небезпечно»; це було «Wireshark — ваш менеджер паролів».
- OpenSSH з’явився як вільна форка SSH у 1999 році. Ця форка стала стандартним інструментом віддаленого доступу в більшості Unix-подібних систем, бо була відкритою, аудиторованою і нудною — в найкращому розумінні.
- Порт 22 не магічний. Це просто призначений IANA стандартний порт. Переїзд знижує шум сканування, але не зупиняє цілеспрямовані атаки і може ускладнити брандмауери та інструменти.
- Раніше версії протоколу SSH були реальною проблемою. SSH-1 — застарілий; SSH-2 — стандарт. Сучасні Ubuntu/OpenSSH вже відключають погані старі речі.
- Раніше «root login» був зручний для адміністраторів. Він ускладнював аудит і робив так, що будь-який витік облікових даних означав повний компроміс. Тому порада «без root по SSH» стала стандартною.
- Слабкі алгоритми для ключів були застарілими з причини. DSA практично музейний експонат. RSA все ще є, але дедалі більше обмежується політиками; Ed25519 став популярним через швидкість, міцність і меншу кількість помилок у використанні.
- Суворі криптоналаштування можуть зламати стару автоматизацію. Деякі вбудовані клієнти та застарілі бібліотеки не підтримують сучасні KEX/MAC-комбінації. Це не ваша провина, але це ваш простій, якщо ви одразу вмикаєте обмеження без інвентаризації.
- Брутфорс-атаки не стали гіршими; вони стали дешевшими. Масштабне сканування в хмарі зробило «парольна автентифікація на інтернет-доступному SSH» програшною стратегією з часом.
Базова перевірка: дізнайтеся, що в вас запущено і хто може підключатися
Посилення починається з базової перевірки. Ви повинні знати:
- Яка версія OpenSSH-сервера встановлена (набір можливостей, значення за замовчуванням, доступні директиви).
- На яких портах і інтерфейсах ви слухаєте.
- Які методи автентифікації використовуються зараз.
- Які мережі можуть дістатися до SSH.
- Як відновити доступ, якщо ви щось зламаєте.
На Ubuntu 24.04 openssh-server зазвичай керується systemd (ssh.service) і налаштовується через /etc/ssh/sshd_config плюс фрагменти у /etc/ssh/sshd_config.d/ (якщо ви вирішите їх використовувати). Підхід із «drop-in» чистіший для контролю змін: ви можете зберегти мінімальну базу дружню до пакунків і керувати власним фрагментом.
Практичні завдання (команди + значення виводу + рішення)
Ось реальні завдання, які ви можете виконати на Ubuntu 24.04. Кожне містить: команду, що ви маєте побачити, і яке рішення прийняти. Це серцевина «посилення без блокувань»: ви ніколи не змінюєте те, чого не спостерігали.
Task 1: Confirm OpenSSH server is installed and versioned
cr0x@server:~$ dpkg -l | grep -E '^ii\s+openssh-server'
ii openssh-server 1:9.6p1-3ubuntu13 amd64 secure shell (SSH) server, for secure access from remote machines
Що це означає: Ви запускаєте OpenSSH 9.6p1 упакований для Ubuntu. Версія важлива для підтримуваних директив і крипто-значень за замовчуванням.
Рішення: Якщо openssh-server не встановлено або він несподівано застарілий — зупиніться і виправте це перед «посиленням». Посилення застарілого демона — це полірування іржавого замка.
Task 2: Check whether SSH is running and how it started
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 Mon 2025-12-30 09:14:22 UTC; 2h 18min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1247 (sshd)
Tasks: 1 (limit: 18962)
Memory: 6.3M
CPU: 1.221s
CGroup: /system.slice/ssh.service
└─1247 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
Що це означає: Сервіс активний і керується systemd. Видно PID і запуск.
Рішення: Якщо він не працює — не «посилюйте» його, а відновіть здоров’я сервісу спочатку. Якщо у вас хост без консолі, ви хочете мати стабільний SSH перед правками.
Task 3: Identify listening port(s) and interfaces
cr0x@server:~$ ss -tulpn | grep -E 'sshd|:22'
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1247,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1247,fd=4))
Що це означає: SSH слухає на всіх IPv4 та IPv6 інтерфейсах на порту 22.
Рішення: Якщо це хост, доступний з інтернету, ви, ймовірно, надто відкриті. Плануйте мережеві обмеження (фаєрвол + allowlist) і, можливо, прив’язку до інтерфейсу управління.
Task 4: See effective sshd configuration (not just the file)
cr0x@server:~$ sudo sshd -T | egrep -i 'port |listenaddress|passwordauthentication|pubkeyauthentication|permitrootlogin|authenticationmethods'
port 22
listenaddress 0.0.0.0
listenaddress ::
permitrootlogin prohibit-password
passwordauthentication yes
pubkeyauthentication yes
authenticationmethods any
Що це означає: Це конфігурація, яку sshd дійсно використає після зчитування всіх include і значень за замовчуванням.
Рішення: Ви посилюєте, виходячи з ефективної конфігурації, а не зі своїх припущень. Якщо PasswordAuthentication yes, вам потрібен план, як безпечно його відключити (після підтвердження ключів і автоматизації).
Task 5: Validate your current config syntax before touching anything
cr0x@server:~$ sudo sshd -t
Що це означає: Відсутність виводу — добре. Вивід означає синтаксичні помилки, і sshd відмовиться стартувати/перезавантажуватися.
Рішення: Якщо ви коли-небудь бачите помилки тут — не перезавантажуйте sshd. Виправте синтаксис спочатку. Синтаксичні помилки — найчистіший генератор блокувань.
Task 6: Confirm you have a working key-based login (from another terminal)
cr0x@server:~$ ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -v ops@127.0.0.1 'echo OK'
OpenSSH_9.6p1 Ubuntu-3ubuntu13, OpenSSL 3.0.13 30 Jan 2024
debug1: Authenticating to 127.0.0.1:22 as 'ops'
debug1: Authentication succeeded (publickey).
OK
Що це означає: Ви можете автентифікуватися за ключем і явно відхиляєте парольну підміну.
Рішення: Якщо це не вдається — не відключайте парольну автентифікацію ще. Виправте ключі, агент або authorized_keys спочатку.
Task 7: Inspect authorized_keys permissions (silent killers)
cr0x@server:~$ sudo ls -ld /home/ops /home/ops/.ssh /home/ops/.ssh/authorized_keys
drwxr-x--- 6 ops ops 4096 Dec 30 09:01 /home/ops
drwx------ 2 ops ops 4096 Dec 30 09:03 /home/ops/.ssh
-rw------- 1 ops ops 742 Dec 30 09:03 /home/ops/.ssh/authorized_keys
Що це означає: Права виглядають розумними: домашня тека не має запису для світу, .ssh — 700, authorized_keys не записуваний іншими.
Рішення: Якщо ви бачите біт групи/світу на запис або неправильну власність — виправте їх. sshd ігноруватиме ключі, які вважає небезпечними, і не сповістить про це в явному вигляді.
Task 8: Confirm which users are allowed and which groups matter
cr0x@server:~$ getent group sudo
sudo:x:27:ops,deploy
Що це означає: ops і deploy у групі sudo; ймовірно, це інтерактивні адміністратори.
Рішення: Якщо ви плануєте використовувати AllowGroups, переконайтеся, що знаєте, які групи дозволяти. Неправильне охоплення — класична причина «чому я не можу залогінитися?».
Task 9: Check firewall state and existing SSH allowances
cr0x@server:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN 10.20.0.0/16
22/tcp ALLOW IN 192.168.50.0/24
Що це означає: UFW активний, за замовчуванням відхиляє вхідні з’єднання, і SSH дозволений лише з двох приватних мереж.
Рішення: Це добре. Якщо ви бачите 22/tcp ALLOW IN Anywhere на хості в інтернеті — виправляйте фаєрвол перед тим, як підсовувати крипто-зміни.
Task 10: Observe auth events and brute-force noise
cr0x@server:~$ sudo journalctl -u ssh --since "2 hours ago" | tail -n 12
Dec 30 10:44:01 server sshd[8621]: Failed password for invalid user admin from 203.0.113.77 port 51244 ssh2
Dec 30 10:44:06 server sshd[8621]: Failed password for invalid user admin from 203.0.113.77 port 51244 ssh2
Dec 30 10:44:10 server sshd[8621]: Connection closed by invalid user admin 203.0.113.77 port 51244 [preauth]
Dec 30 11:02:33 server sshd[9012]: Accepted publickey for ops from 10.20.8.41 port 49912 ssh2: ED25519 SHA256:2d3v...
Що це означає: Є спроби брутфорсу паролів (ймовірно, інтернет- або VPN-експозиція) і легітимні логіни по ключу.
Рішення: Якщо бачите повторювані спроби паролів — відключення паролів стає пріоритетнішим. Якщо бачите тільки логіни по ключу — ви можете суворіше посилити автентифікацію з меншим ризиком.
Task 11: Check current SSH client compatibility (from your workstation)
cr0x@server:~$ ssh -G ops@server | egrep -i 'kexalgorithms|ciphers|macs|hostkeyalgorithms' | head
ciphers chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr
macs umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
kexalgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
hostkeyalgorithms ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512,rsa-sha2-256
Що це означає: Ваш клієнт підтримує сучасні алгоритми, включно з гібридними постквантовими KEX-опціями (підхід OpenSSH) і Ed25519.
Рішення: Перед тим як жорстко обмежувати серверні алгоритми, зробіть інвентар підтримки клієнтів. Те, що ваш робочий стіл сучасний, не означає, що ваша автоматизація така сама.
Task 12: Create a safe “sshd on a different port” canary (temporary)
cr0x@server:~$ sudo /usr/sbin/sshd -D -p 2222 -o PermitRootLogin=no -o PasswordAuthentication=no -o PubkeyAuthentication=yes
Що це означає: Це запускає sshd у передньому плані на порті 2222 з жорсткими налаштуваннями автентифікації, не чіпаючи основний демон.
Рішення: Використайте це, щоб протестувати нові політики, тримаючи порт 22 як страховку. Після валідації перенесіть налаштування у конфіг і перезавантажте реальний сервіс.
Task 13: Test reload safely (after changes) and confirm it took effect
cr0x@server:~$ sudo sshd -t && sudo systemctl reload ssh && sudo sshd -T | egrep -i 'passwordauthentication|permitrootlogin'
passwordauthentication no
permitrootlogin no
Що це означає: Синтаксис коректний, reload пройшов успішно, і ефективна конфігурація тепер показує суворішу автентифікацію.
Рішення: Якщо reload не вдався — не панікуйте: ваші існуючі сесії зазвичай лишаються. Виправте, потім знову reload. Якщо ви робили restart і сервіс не повернувся, це «час консолі». Уникати restart-ів, якщо це можливо.
Task 14: Confirm you didn’t accidentally block yourself at the network layer
cr0x@server:~$ sudo ufw status numbered
Status: active
To Action From
[ 1] 22/tcp ALLOW IN 10.20.0.0/16
[ 2] 22/tcp ALLOW IN 192.168.50.0/24
Що це означає: Ви чітко бачите, які правила застосовані і в якому порядку.
Рішення: Якщо ви збираєтеся посилювати правила, спочатку додайте нові allow-правила, протестуйте підключення, а потім видаляйте старі широкі. Редагування фаєрвола шляхом віднімання — як ви дізнаєтеся, що ваш VPN не виходить з підмережі, яку ви припускали.
sshd_config: налаштування, які варто змінити (і ті, що призводять до проблем)
Ubuntu 24.04 + OpenSSH вже непогані. Трюк — вибрати зміни, що суттєво знижують ризик, не підірвавши доступ. Ось що я рекомендую і чому, плюс режими відмови.
Use a drop-in file, not a messy monolith
Створіть керований фрагмент, наприклад /etc/ssh/sshd_config.d/50-hardening.conf. Це добре працює з пакунками, робить дифи читабельними і зберігає ваші зміни явними.
cr0x@server:~$ sudo install -m 0644 -o root -g root /dev/null /etc/ssh/sshd_config.d/50-hardening.conf
High-value settings (safe when staged)
- Вимкніть парольну автентифікацію після перевірки ключів:
PasswordAuthentication no. - Вимкніть логін root для інтерактивного SSH:
PermitRootLogin no. Якщо потрібен привілейований доступ — використовуйте sudo з іменованими користувачами, що аудитується. - Обмежте, хто може логінитися:
AllowUsersабоAllowGroups. Це знижує радіус ураження у випадку витоку облікових даних. - Зменшіть площу атаки:
X11Forwarding no, якщо це вам справді не треба; багато хто не потребує цього. Також розгляньте обмеженняAllowTcpForwardingна користувача. - Встановіть розумні таймаути:
ClientAliveIntervalіClientAliveCountMaxдля очищення «пеших» сесій. - Логування з наміром:
LogLevel VERBOSEдопомагає аудиту (та може додати шум; не вмикайте бездумно на високонавантажених бастіонах).
Settings that are “secure” but frequently cause lockouts
- Занадто жорстке звуження алгоритмів без інвентаризації клієнтів. Якщо ви приберете підтримку RSA SHA-2 або забороните KEX, який потрібен старим клієнтам, отримаєте помилки рукшейку.
- Неправильне встановлення
AuthenticationMethods. Це потужне й гостре. Одна помилка може зажадати «двох факторів», які ви насправді не налаштували. - Використання
AllowUsersі забуті сервісні акаунти (автоматизація, бекапи, конфігур-менеджмент). Система не зламається; зламається ваш pipeline.
A solid baseline drop-in (adapt it)
Це консервативно для більшості флотів і достатньо суворо, щоб мати значення. Застосовуйте тільки після підтвердження роботи ключової автентифікації для всіх потрібних акаунтів.
cr0x@server:~$ sudo tee /etc/ssh/sshd_config.d/50-hardening.conf >/dev/null <<'EOF'
# Managed hardening settings (Ubuntu 24.04)
Protocol 2
# Safer defaults: no root, no passwords
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
# Reduce opportunistic abuse
MaxAuthTries 4
LoginGraceTime 20
MaxStartups 10:30:60
# Hygiene
X11Forwarding no
PermitTunnel no
PermitUserEnvironment no
AllowAgentForwarding no
# Keepalive to clear dead sessions
ClientAliveInterval 300
ClientAliveCountMax 2
# Prefer explicit allowlists (set these to match your org)
# AllowGroups ssh-users
LogLevel VERBOSE
EOF
Як застосувати без драм: Тримайте активну сесію відкритою, перевірте конфіг (sshd -t), зробіть reload (не restart) і протестуйте нові логіни з другого терміналу.
Стратегія автентифікації: ключі, паролі, MFA і режим «break-glass»
Автентифікація SSH — це не один перемикач. Це стратегія. У продакшні ви хочете:
- Основну автентифікацію, яка сильна і автоматизована (публічні ключі, бажано з контрольованим процесом забезпечення).
- Захист від повторного використання облікових даних і брутфорсу (немає паролів або принаймні немає паролів із загальнодоступного інтернету).
- Break-glass доступ, який контрольований, аудитується і тестується (бо він знадобиться в найгірший момент).
Keys: do them properly
Ed25519 ключі — сучасний вибір для інтерактивних користувачів. Вони малі, швидкі і стійкі до багатьох історичних помилок. Для автоматизації у вас можуть ще бути RSA-ключі; це прийнятно, якщо вони використовують SHA-2 підписи і не мають застарілих розмірів.
cr0x@server:~$ ssh-keygen -t ed25519 -a 64 -C "ops@laptop"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/cr0x/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/cr0x/.ssh/id_ed25519
Your public key has been saved in /home/cr0x/.ssh/id_ed25519.pub
Що це означає: -a 64 підвищує кількість раундів KDF для захисту пароля. Це важливо, якщо приватний ключ коли-небудь витече.
Рішення: Для людей: використовуйте парольну фразу. Для автоматизації: розгляньте підходи з агентом або ключі з обмеженими дозволами та прив’язані до джерела.
Deploy keys with a controlled method
Якщо ви користуєтесь ssh-copy-id, робіть це тоді, коли парольна автентифікація ще увімкнена (тимчасово), потім відключіть паролі після перевірки.
cr0x@server:~$ ssh-copy-id -i ~/.ssh/id_ed25519.pub ops@server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/cr0x/.ssh/id_ed25519.pub"
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'ops@server'"
Рішення: Негайно протестуйте з PasswordAuthentication=no, як показано раніше. Не довіряйте «added: 1» як доказу доступу.
MFA: useful, but don’t improvise in production
MFA для SSH можна реалізувати через PAM (наприклад TOTP) або через ключі з апаратною підтримкою (FIDO2/U2F з OpenSSH). Пастка надійності: зміни в PAM — це глобальна авторизаційна логіка. Невелика помилка може зламати не тільки SSH, а й локальні консолі залежно від налаштування.
Практичний підхід:
- Почніть з ключів-only SSH + мережевих allowlist-ів + моніторингу. Це вже велике покращення.
- Додавайте MFA на бастіонах спочатку, а не на кожному вузлі, якщо у вас немає зрілого плану розгортання та відновлення.
- Якщо використовуєте FIDO-ключі, переконайтеся, що у кожного адміністратора є два пристрої і є процес для втрати ключа.
Break-glass: the boring account that saves you
Створіть спеціального користувача breakglass з такими властивостями:
- Тільки автентифікація ключем
- Обмежені адреси джерела (VPN або офісні діапазони)
- Права sudo згідно з вашою політикою (часто повний sudo, але жорстко контрольований і аудитується)
- Без щоденного використання
cr0x@server:~$ sudo adduser --disabled-password --gecos "" breakglass
Adding user `breakglass' ...
Adding new group `breakglass' (1002) ...
Adding new user `breakglass' (1002) with group `breakglass (1002)' ...
Creating home directory `/home/breakglass' ...
Copying files from `/etc/skel' ...
Adding new user `breakglass' to supplemental / extra groups `users' ...
Adding user `breakglass' to group `users' ...
Рішення: Тримайте цей акаунт поза звичайними робочими процесами. Якщо він з’являється у регулярних логах входу — ставтеся до цього як до пожежного сигналу.
Мережеві засоби контролю: UFW, allowlist-и та «не відкривайте порт 22 для всіх»
Мережеві обмеження — найменш гламурні зміни, але найефективніші. Якщо атакуючий не може дістатися до порту, ваша політика автентифікації стає другою лінією захисту, а не першою.
Bind SSH to a management IP (when you have one)
Якщо хост має виділений інтерфейс/VLAN для управління, прив’яжіть SSH до нього. Це зменшить експозицію навіть якщо правила фаєрвола дрейфуватимуть.
cr0x@server:~$ sudo tee /etc/ssh/sshd_config.d/10-listen.conf >/dev/null <<'EOF'
ListenAddress 10.20.8.10
EOF
Рішення: Робіть це лише якщо впевнені, що IP стабільний і доступний з ваших адміністраторських мереж. Інакше ви придумаєте нові матюки.
UFW allowlist pattern (add before remove)
Якщо SSH зараз відкритий, не закривайте його різко. Спочатку додайте вузьке allow-правило, протестуйте, потім видаляйте широкі правила.
cr0x@server:~$ sudo ufw allow from 10.20.0.0/16 to any port 22 proto tcp
Rule added
Що це означає: Дозволено адміністраторську мережу.
Рішення: Підтвердьте, що можете підключитися з цієї мережі. Лише потім видаліть правила «Anywhere».
Consider a bastion instead of direct node access
У багатьох корпоративних середовищах найкраще посилення SSH — це архітектурне рішення: зробіть більшість серверів недоступними з користувацьких мереж і вимагайте підключення через бастіон з жорсткішим моніторингом. SSH стає контрольованою точкою, а не тисячами розкиданих входів.
Жарт №2: Бастіон — як рецепціоніст в офісі: всі скаржаться, поки не прибереш його.
Стійкість до зловживань: обмеження швидкості, Fail2ban і реакції на основі логів
Якщо ваш SSH доступний, його будуть сканувати. Навіть з ключовою автентифікацією, атакуючі будуть випробовувати імена користувачів і різні граничні випадки. Ваше завдання — зробити цей шум дешевим для ігнорування і дорогим для підтримки.
Use systemd journal + rate limiting as your first line
OpenSSH має вбудовані ручки (MaxStartups, LoginGraceTime, MaxAuthTries). Вони зменшують використання ресурсів і уповільнюють брутфорс.
Не виставляйте їх занадто низько на бастіонах; ви нашкодите своїм користувачам під час інциденту, коли багато людей підключаються одночасно.
Fail2ban: still useful, but not a substitute for allowlists
Fail2ban парсить логи і динамічно додає правила фаєрвола. Він корисний для інтернет-доступних точок, але реактивний і його можна обдурити. Розглядайте як швабру, а не як дамбу.
cr0x@server:~$ sudo apt-get update -y && sudo apt-get install -y fail2ban
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
fail2ban
cr0x@server:~$ sudo systemctl enable --now fail2ban
Created symlink /etc/systemd/system/multi-user.target.wants/fail2ban.service → /usr/lib/systemd/system/fail2ban.service.
cr0x@server:~$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 24
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 1
|- Total banned: 3
`- Banned IP list: 203.0.113.77
Що це означає: Jail працює, відслідковує невдалі спроби і банить зловмисні IP.
Рішення: Якщо ви бачите, що баняться внутрішні корпоративні IPи — можливо, allowlist-и/VPN/NAT поводяться так, що спільні вихідні IPи блокуються. Налаштуйте jail або, краще, виправте мережевий шлях.
Криптополітика: шифри, MAC, KEX і ключі хосту (без ламання клієнтів)
Криптопосилення — це місце, де добрі наміри призводять до реальних відмов. Правильний підхід — поступовий: інвентар клієнтів, вибір політики, поетапне розгортання і моніторинг відмов рукшейку.
First rule: don’t outsmart your fleet
OpenSSH в Ubuntu 24.04 вже сучасний. Якщо у вас немає вимог відповідності, часто не потрібно явно вказувати Ciphers/MACs/KexAlgorithms. Значення за замовчуванням еволюціонують з оновленнями; фіксація може вас «заморозити».
Коли потрібно їх встановлювати (комплаєнс, аудитори, крос-дистро політика) — робіть це з інвентаризацією і планом відкату.
Inventory failures: watch for “no matching…” messages
cr0x@server:~$ ssh -vvv legacy@server
debug1: kex: algorithm: (no match)
Unable to negotiate with 10.20.8.10 port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
Що це означає: Клієнт древній і пропонує лише слабкий KEX. Ваш жорсткий сервер відкидає його. Це, швидше за все, правильно.
Рішення: Оновіть клієнта або ізолюйте його за контрольованим бастіоном, який може з ним говорити. Не ослаблюйте флот заради одного динозавра.
Host keys: keep them sane, keep them stable
Ключі хосту — це ідентичність сервера. Ротація без плану тригерить «REMOTE HOST IDENTIFICATION HAS CHANGED!» попередження, які користувачі навчаться ігнорувати. Це протилежне бажаному.
cr0x@server:~$ sudo ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:8t7mZlQZ9l8m0n3H9Jx7qWzYkqvHqQx0mJv4pYkq8mE root@server (ED25519)
Рішення: Переконайтеся, що маєте сучасні ключі хосту (Ed25519, ECDSA, RSA SHA-2). Якщо плануєте ротацію — координуйте оновлення known_hosts через конфіг-менеджмент, а не електронною поштою.
Операційні запобіжники: контроль змін, тестування і відкат
«Посилення» — це не геройський акт. Це контрольоване розгортання.
Keep an active session and open a second one before reload
Коли ви reload-ите sshd, існуючі сесії, як правило, лишаються. Це ваша страховка. Відкрийте другу сесію перед змінами, щоб протестувати нові логіни, залишивши відомо-діючий канал.
Prefer reload over restart
systemctl reload ssh просить sshd перечитати конфігурацію без розриву існуючих з’єднань. Restart більш руйнівний і ймовірніше залишить вас без доступу, якщо старт не вдасться.
Know your out-of-band access before you need it
Консоль хмари, IPMI, консоль гіпервізора або фізичний доступ. Тестуйте щоквартально. Так — щоквартально. Перший раз, коли ви ним користуєтеся, не має бути під час вікна інциденту зі Slack, що заповнюється думками.
Back up config files with a timestamp
cr0x@server:~$ sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F_%H%M%S)
Рішення: Якщо щось піде не так, вам потрібен відомо-діючий файл, а не пам’ять про те, що ви змінювали.
Швидкий плейбук діагностики
Коли SSH «ламається», зазвичай це одна з чотирьох категорій: демон впав, мережа заблокована, відмова автентифікації або збій під час криптонеговорів. Діагностуйте у цьому порядку. Швидко. Без блукання.
1) Is sshd up and listening?
- На консолі сервера (або через існуючу сесію): перевірте статус сервісу і сокети, що слухають.
cr0x@server:~$ systemctl is-active ssh; ss -tulpn | grep sshd
active
tcp LISTEN 0 128 10.20.8.10:22 0.0.0.0:* users:(("sshd",pid=1247,fd=3))
Якщо не активний/не слухає: синтаксис конфігурації, права або проблеми з пакунком. Перейдіть до sshd -t і журналів systemd.
2) Is the network path open?
- З боку клієнта: чи маєте ви TCP-підключення або таймаут?
- З боку сервера: чи дозволяють правила фаєрволу ваш IP джерела?
cr0x@server:~$ sudo ufw status verbose
Status: active
Default: deny (incoming), allow (outgoing), disabled (routed)
Таймаути зазвичай означають мережу/фаєрвол. Миттєве «connection refused» зазвичай означає, що sshd не слухає (або порт не той).
3) Is it auth policy?
- З клієнта: використовуйте детальний режим SSH.
- З сервера: перевірте логи ssh на «Authentication refused» або «user not allowed».
cr0x@server:~$ ssh -vvv ops@server
debug1: Authentications that can continue: publickey
debug1: Offering public key: /home/cr0x/.ssh/id_ed25519 ED25519 SHA256:2d3v...
debug1: Server accepts key: /home/cr0x/.ssh/id_ed25519
debug1: Authentication succeeded (publickey).
Якщо бачите «Permission denied (publickey)»: перевірте розгортання ключа, права файлів, AllowUsers/AllowGroups і будь-які блоки Match.
4) Is it crypto negotiation?
Шукайте повідомлення «no matching»: KEX, алгоритм ключів хосту, шифр або MAC. Це часто проблема з віком клієнта або надмірно зафіксованою серверною політикою.
Поширені помилки: симптом → корінь проблеми → виправлення
1) Symptom: Existing sessions stay up, but new logins fail immediately
Корінь проблеми: Ви перечитали sshd з суворішою політикою (PasswordAuthentication no, AllowGroups або AuthenticationMethods) і ваш тестовий користувач не підпадає під неї.
Виправлення: У існуючій сесії запустіть sshd -T, підтвердіть ефективні налаштування і відкоригуйте allowlist-и або тимчасово відновіть парольну автентифікацію, поки не виправите доступ по ключах.
2) Symptom: “Connection refused”
Корінь проблеми: sshd не слухає на цьому інтерфейсі/порті (неправильний ListenAddress, інший порт, сервіс вимкнений).
Виправлення: Використайте ss -tulpn, щоб підтвердити слухачі; journalctl -u ssh для помилок при старті; виправте конфіг і потім reload або restart за потреби.
3) Symptom: “Connection timed out”
Корінь проблеми: Фаєрвол/група безпеки/ACL мережі блокує або проблема з маршрутизацією/VPN.
Виправлення: Перевірте правила UFW і правила вище по ланцюжку. Додайте тимчасове вузьке allow з вашого поточного IP, протестуйте, потім почистіть.
4) Symptom: “Permission denied (publickey)” but your key is present
Корінь проблеми: sshd ігнорує authorized_keys через небезпечні права або неправильну власність; або користувач не дозволений через AllowUsers/AllowGroups.
Виправлення: Встановіть 700 для .ssh і 600 для authorized_keys. Перевірте власність. Підтвердіть allow-правила.
5) Symptom: “REMOTE HOST IDENTIFICATION HAS CHANGED!” after a maintenance event
Корінь проблеми: Ключі хосту були змінені несподівано (відновлення, ребілд або зміна образу) без синхронізації known_hosts.
Виправлення: Підтвердіть новий fingerprint поза каналом і оновіть known_hosts централізовано. Не вчіть користувачів ігнорувати попередження.
6) Symptom: Some automation breaks, humans are fine
Корінь проблеми: Ви вимкнули парольну автентифікацію, а автоматизація досі її використовує; або клієнт бібліотеки автоматизації не може погодити нові алгоритми.
Виправлення: Визначте облікові записи, що падають, в логах, переведіть автоматизацію на ключі або сертифікати SSH і тестуйте з точною версією клієнта, що використовується в CI/CD.
Чеклисти / покроковий план
Phase 0: Pre-flight (don’t skip this)
- Підтвердьте, що існує і працює консольний/поза-канальний доступ (серійна консоль хмари, IPMI, консоль гіпервізора).
- Відкрийте дві SSH-сесії з різних терміналів.
- Зробіть бекап конфігурації SSH і зафіксуйте поточні ефективні налаштування:
sudo cp -a /etc/ssh/sshd_config ...sudo sshd -T > /root/sshd-effective.before
- Інвентаризуйте, хто і як входить (журнали, логи бастіону, облікові записи автоматизації).
Phase 1: Network-first tightening
- Впровадьте allowlist-и в UFW (або правила груп безпеки в хмарі), щоб обмежити джерела SSH до адміністраторських/VPN мереж.
- Протестуйте підключення з кожної дозволеної мережі.
- Лише після цього видаляйте широкі правила.
Phase 2: Key auth everywhere
- Переконайтеся, що кожен потрібний користувач та акаунт автоматизації має робочий вхід за ключем.
- Перевірте з
PasswordAuthentication=noна клієнті. - Заздалегідь виправте права та власність файлів.
Phase 3: Enforce no-password, no-root
- Додайте керований drop-in з
PasswordAuthentication noіPermitRootLogin no. - Запустіть
sudo sshd -t. - Зробіть reload sshd, а не restart.
- Протестуйте свіжий логін як звичайний адміністратор і як break-glass користувач.
Phase 4: Reduce SSH features you don’t need
- Вимкніть X11 forwarding, якщо не потрібно.
- За замовчуванням вимкніть agent forwarding. Якщо робочий процес вимагає — вмикайте його для конкретних користувачів через блоки
Match. - Обмежте портфорвардінг, якщо SSH використовується лише для shell-доступу.
Phase 5: Abuse resistance and monitoring
- Встановіть
MaxAuthTries,LoginGraceTime,MaxStartupsу розумні значення. - Розгорніть Fail2ban там, де потрібно (публічні кінцеві точки), але не покладайтеся на нього як на основний контроль.
- Оглядайте логи щотижня, поки система не стабілізується, потім щомісяця.
Три корпоративні історії з практики сумнівних змін SSH
Mini-story 1: The incident caused by a wrong assumption
Компанія мала змішане середовище: деякі Ubuntu, деякі RHEL, кілька апаратних пристроїв, про які ніхто не хотів зізнаватися, що вони ще в експлуатації. Інженер вирішив стандартизувати політики SSH під час «security sprint». Розумна мета. Вони додали AllowGroups ssh-admins по всьому парку, впевнені, що «всі адміністратори в тій групі».
На папері вони були праві. На практиці існувало три різних джерела ідентичності: локальні користувачі на старих хостах, LDAP на нових і інтеграція з IAM на бастіонах. На кількох серверах група існувала — але адміністраторські акаунти не були її членами, бо ті акаунти були локальними виходами, створеними під час минулих інцидентів. Ніхто їх не почистив. Припущення про централізацію ідентичності виявилося хибним.
Зміна розгорнулась. Існуючі SSH-сесії лишилися активними, що дало хибне відчуття впевненості. Нові сесії не проходили. Команда на виклику почала перемикати термінали, як авіадиспетчери, бо не хотіли втратити останні сесії. Рутинний патч ядра був на півдорозі і не зміг завершити роботу через відсутність підключень.
Виправлення було нудним і трохи принизливим: відкотили AllowGroups, провели аудит членства в групах, потім знову ввели allowlist-и поетапно, використовуючи Match Address для break-glass шляху першим. Урок не в «ніколи не використовуйте AllowGroups». Урок — «не припускайте, що ідентичність уніформна, поки ви цього не довели».
Mini-story 2: The optimization that backfired
Інша організація мала завантажений бастіон. Вони мали тисячі коротких SSH-з’єднань: люди, автоматизація та скрипти, що виконували одну команду й виходили. Хтось помітив піки CPU й вирішив «оптимізувати», загостривши таймаути і зменшивши кількість одночасних неавтентифікованих підключень.
Вони встановили LoginGraceTime агресивно малим і MaxStartups надто строгим, думаючи, що це вдарить лише по ботах. Під час звичайного інциденту флап VPN спричинив одночасне перепідключення багатьох користувачів. Бастіон почав відкидати нові з’єднання саме тоді, коли він був найбільш потрібен. Команда безпеки полюбила нові налаштування; інцидент-командир — ні.
Гірше, режим відмови виглядав як мережна нестабільність. Користувачі бачили перервані з’єднання та таймаути. Люди звинувачували VPN, потім DNS, потім хмарну мережу. Корінь проблеми — самонанесений контроль допуску від sshd під час хвилеподібних перепідключень.
Вони відкотили до більш лояльної кривої MaxStartups і трохи збільшили grace time. CPU-піки залишились керованими, і бастіон став передбачуваним. Мораль: оптимізувати SSH як бенчмарк — значить незабаром побачити, що ваша нагрузка включає людей, які поводяться як скажене стадо.
Mini-story 3: The boring but correct practice that saved the day
Фінансова компанія мала суворе правило: кожна зміна політики SSH вимагала (1) canary-хост, (2) тест поза каналом доступу і (3) скриптовану перевірку логіну тільки по ключу перед відключенням паролів. Звучало бюрократично. Але працювало.
Вони планували відключити парольну автентифікацію по всьому парку. До примусового впровадження їхній пайплайн запускав тест, який намагався залогінитися з PasswordAuthentication=no для кожного привілейованого акаунта. Один canary-пристрій провалився: застаріла автоматизація все ще використовувала пароль для доступу до звітного сервера. Ніхто не знав, бо це було «налаштовано й забуто» роки тому.
Оскільки тест пройшов перед застосуванням, нічого не зламалося. Вони виправили джоб — перевели його на виділений ключ із обмеженим набором команд, повторили тест і лише потім застосували конфіг всюди.
Не було драм, екстреного доступу через консоль чи нічного відкату змін. Поліпшення безпеки прийшло тихо. Ось як у продакшні має виглядати «правильно»: не героїчно, а відтворювано.
Питання й відповіді
1) Should I change the SSH port from 22?
Якщо ви експонуєте хост в інтернет — зміна порту зменшить фоновий шум сканування, але не зупинить цілеспрямованих атак. Робіть це лише якщо це не ускладнить інструменти. Краще мережеві allowlist-и і автентифікація по ключу.
2) Is disabling password authentication always safe?
Це безпечно, коли ви перевірили доступ по ключу для кожного потрібного користувача і шляху автоматизації, і маєте план break-glass. Ризиковано, коли ви «гадаєте», що ключі розгорнуті, але не тестували відключення паролів.
3) What’s the safest way to apply changes: reload or restart?
Спочатку reload. systemctl reload ssh зберігає існуючі сесії. Restart прийнятний за потреби, але підвищує ризик повного блокування при помилці конфігу.
4) Should I set explicit Ciphers/MACs/KexAlgorithms?
Лише якщо це потрібно політикою/комплаєнсом або для крос-дистро узгодженості. Значення за замовчуванням загалом добрі і покращуються з оновленнями. Фіксація алгоритмів може створити майбутній простій при розходженні клієнтів.
5) How do I prevent root access without losing admin capability?
Вимкніть логін root по SSH (PermitRootLogin no) і використовуйте іменовані акаунти з sudo. Ви отримаєте трасування аудиту і зможете чисто відкликати доступ.
6) What about SSH agent forwarding?
Вимкніть його за замовчуванням (AllowAgentForwarding no). Якщо певні робочі процеси потребують — вмикайте через цільові блоки Match User і не вмикайте на бастіонах, якщо ви не довіряєте проміжному хопу.
7) Do I need Fail2ban if I already have UFW allowlists?
Якщо SSH суворо allowlist-ований до приватних мереж — користь Fail2ban зменшується. Якщо SSH доступний з інтернету (навіть тимчасово) — Fail2ban корисний як додатковий шар, але не як основний захист.
8) What’s the single best “won’t lock you out” trick?
Запустіть тимчасовий canary sshd на іншому порту з бажаними жорсткими налаштуваннями, протестуйте його повністю, а потім застосуйте налаштування до основного сервісу.
9) How do I know if I broke crypto compatibility?
Клієнтські ssh -vvv покажуть відмови переговорів, наприклад «no matching key exchange method». Логи сервера також можуть показати відкинуті алгоритми. Зазвичай виправлення — оновити клієнт, а не ослаблювати сервер.
10) Can I enforce different SSH policies for different users?
Так. Використовуйте блоки Match User, Match Group або Match Address, щоб задати суворіші або м’якіше налаштування. Так ви збережете break-glass контрольованим і накладете сильні дефолти для інших.
Висновок: що робити далі
Посилення SSH на Ubuntu 24.04 не має бути театром. Робіть це як оператор: спочатку зменшіть експозицію, доведіть доступ по ключу, потім примусово застосуйте суворішу автентифікацію. Уникайте фіксації алгоритмів без причини. Віддавайте перевагу reload перед restart. Майте break-glass шлях, який ви справді тестуєте, а не лише обговорюєте.
Практичні наступні кроки:
- Виконайте базові завдання: підтвердіть ефективну конфіг, слухачі, межі фаєрвола і реальні шаблони логінів.
- Додайте/підтвердіть break-glass користувача з автентифікацією по ключу і обмеженими мережами джерела.
- Розгорніть drop-in файл посилення поетапно: canary → невелика група → весь флот, з
sshd -tі скриптованими тестами логіну як воротами. - Після примусового застосування проводьте моніторинг логів щодня протягом тижня. Система скаже вам, що ви зламали — якщо ви слухаєте.