Короткий ответ

Три разных отказа: timed out — пакет не доходит (маршрут, NAT, firewall); refused — до хоста дошли, на порту никто не слушает; Permission denied (publickey) — sshd принял TCP, отверг аутентификацию. Лечить «открыть 22 в ufw» при publickey бессмысленно. На Ubuntu 22.04 обычно ssh.service, на 24.04 часто ssh.socket + on-demand ssh.service. Смотрите ss -tlnp и unit, не копируйте ListenAddress с CentOS.

Консоль гипервизора — запасной путь. Хост host.example (10.0.20.10), пользователь admin.

Симптомы и как отличить

С клиента:

ssh -vvv -o ConnectTimeout=8 admin@10.0.20.10
nc -vz 10.0.20.10 22
СообщениеСлой
timed out / no routeсеть, firewall, неверный IP
refusedнет listen на 22
reset by peer сразуtcp-wrapper/nft reject, не drop
publickeysshd жив, ключ/AllowUsers
DNS NXDOMAIN на host.exampleDNS

Сессия открылась и потом умерла — SSH разрывает соединение, не эта статья.

Возможные причины

  1. sshd не запущен, на 24.04 сломан ssh.socket.
  2. Слушает 127.0.0.1:22 или нестандартный порт в /etc/ssh/sshd_config.d/.
  3. UFW/nftables drop с внешней сети, с localhost работает.
  4. Security group/облако, не гостевой ufw.
  5. AllowUsers/AllowGroups/DenyUsers, PasswordAuthentication no без ключа у admin.
  6. После hardening PermitRootLogin no — вы пытаетесь root, а не admin.
  7. Диск полный — sshd не пишет privilege separation, unit failed.

Диагностика

С консоли или уже открытой сессии.

1. Слушает ли порт

ss -tlnp | grep -E ':22|:2222'
systemctl status ssh.service ssh.socket --no-pager
systemctl is-enabled ssh.service ssh.socket

На 22.04 ssh.socket может быть inactive — это норма, если ssh.service active и ss показывает :22. На 24.04 ssh.socket listen, ssh.service dead до коннекта — тоже норма.

2. Конфиг, не блог 2014 года

sudo sshd -T | grep -Ei 'port |listenaddress|permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers|allowgroups|maxstartups'
sudo sshd -t
ls -l /etc/ssh/sshd_config.d/

sshd -T — эффективный конфиг. Файлы в sshd_config.d/*.conf читаются в лексикографическом порядке.

3. Firewall

sudo ufw status verbose
sudo nft list ruleset | head -n 80
sudo iptables -L -n -v 2>/dev/null | head

UFW на этих Ubuntu сидит на nft. Подробнее: UFW, nftables. Не делайте ufw disable навсегда.

Журнал блокировок:

sudo grep UFW /var/log/syslog | tail
journalctl -k | grep -i 'UFW BLOCK' | tail

4. Аутентификация

sudo journalctl -u ssh.service -u ssh.socket -b --no-pager | tail -n 50
sudo tail -n 50 /var/log/auth.log

Ищите Failed publickey for admin, Connection closed by authenticating user, Invalid user.

Права ключей:

namei -l /home/admin/.ssh
ls -ld /home/admin /home/admin/.ssh
ls -l /home/admin/.ssh/authorized_keys

Каталог .ssh — 700, authorized_keys — 600, владелец admin. Не root:root после sudo cp.

5. С клиента ещё раз после фактов

ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes admin@10.0.20.10

IdentitiesOnly отсекает пачку ключей, из‑за которой sshd отваливается по MaxAuthTries.

Решение

Сценарий A. Никто не слушает 22

sudo systemctl enable --now ssh.service
# Ubuntu 24.04, если используете socket activation:
sudo systemctl enable --now ssh.socket
sudo ss -tlnp | grep :22

Если unit failed — systemd-сервис, часто ENOSPC или битый sshd_config (sshd -t).

Сценарий B. Слушает localhost

В drop-in /etc/ssh/sshd_config.d/50-cloud-init.conf облако могло оставить ListenAddress 127.0.0.1. Исправьте на нужный адрес или уберите директиву, затем:

sudo systemctl reload ssh.service || sudo systemctl restart ssh.socket

Не оставляйте SSH только на публичном IP без второго канала (VPN/консоль).

Сценарий C. Firewall

Разрешите свой источник, не anywhere, если политика компании так требует:

sudo ufw allow OpenSSH
sudo ufw status numbered

ufw allow OpenSSH использует профиль порта 22. Если sshd на 2222 — отдельное правило. Не ufw default allow incoming.

Сценарий D. Ключи

От консоли:

sudo -u admin mkdir -p /home/admin/.ssh
sudo -u admin chmod 700 /home/admin/.ssh
# вставить pubkey в authorized_keys, chmod 600

Сценарий E. AllowUsers отсекает admin

Проверьте sshd -T | grep allowusers. Добавьте admin или уберите директиву через drop-in, не комментируя весь файл пакета.

Ubuntu 22.04 и 24.04: socket activation на практике

На 22.04 пакет openssh-server держит ssh.service в ListenStream. Команда systemctl disable ssh.socket обычно не нужна. На 24.04 ssh.socket содержит ListenStream=0.0.0.0:22 и ListenStream=[::]:22; ssh.service без сокета может не bind'ить. Если вы «для надёжности» enabled оба неправильно, получите Address already in use в journal — это refused для второго слушателя, не firewall.

Проверка баннера с клиента:

nc -v 10.0.20.10 22
# ожидайте SSH-2.0-OpenSSH_

Если баннера нет, а ss локально показывает listen — промежуточный DROP (timeout) или DNAT не туда.

MaxStartups по умолчанию 10:30:100. Сканер ключей заполняет слоты, легитимный admin ловит Connection refused или drop на handshake. Смотрите sshd[…] beginning MaxStartups throttling в auth.log.

cloud-init на первом boot пишет ssh_pwauth и ключи в /home/ubuntu или /home/admin. Если вы создали admin руками, ключ мог остаться у ubuntu. ls /home/*/ .ssh/authorized_keys.

Как проверить, что проблема устранена

С другой машины, не с localhost сервера:

nc -vz 10.0.20.10 22
ssh -o BatchMode=yes -o ConnectTimeout=8 admin@10.0.20.10 'hostname; ss -tlnp | grep :22'

BatchMode не спросит пароль: успех = ключ принят. Проверьте, что root по паролю по-прежнему закрыт.

Если не помогло

  • С LAN работает, из интернета нет: NAT/SG облака, не sshd.
  • TCP есть, сразу баннер не тот: не sshd на 22, а другой сервис.
  • После hardening снова отказ — baseline, не откатывайте все сразу.
  • Сессия рвётся через минуту — следующая статья, keepalive.

Профилактика

  • Два пути: SSH-ключ + консоль гипервизора.
  • Drop-in в sshd_config.d, не правка всего sshd_config вслепую.
  • Мониторинг listen :22 и systemctl is-active.
  • Не фильтровать 22 «до понедельника» без исключения вашего jump-хоста.

FAQ

Ubuntu 24.04: restart ssh.service ничего не слушает?

Смотрите ssh.socket. systemctl restart ssh.service без сокета может не bind'ить порт.

Можно ли PermitRootLogin yes «на час»?

Не нужно, если есть admin и sudo. Root login — отдельный риск, не диагностика.

Connection refused после смены порта

Клиент ещё стучит в 22. Согласуйте порт, ufw и ssh -p.

fail2ban забанил меня

С консоли fail2ban-client set sshd unbanip. Не отключайте fail2ban навсегда.

Cloud-init перезаписывает sshd

Файлы 50-cloud-init.conf и sshd_not_to_be_overwritten. Читайте их до ручной войны с sshd_config.