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

На Ubuntu 22.04 и 24.04 вход root по SSH должен быть выключен: PermitRootLogin no, администрирование — отдельная учётка admin с ключом и sudo. Сначала создайте пользователя, положите свой ключ в authorized_keys, проверьте второй SSH-сессией ssh -o BatchMode=yes admin@10.0.20.10, и только потом systemctl reload ssh. Не оставляйте prohibit-password как «достаточно»: ключ на root — это всё ещё root. Не открывайте пароль root «на пять минут» в интернет.

Хост host.example (10.0.20.10). Консоль гипервизора или BMC держите открытой до подтверждения входа admin.

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

Типичная картина:

  • ssh root@10.0.20.10 даёт shell, а не Permission denied;
  • в журнале Accepted publickey for root или Accepted password for root;
  • sshd -T | grep permitrootlogin показывает yes или prohibit-password;
  • в /root/.ssh/authorized_keys лежат ключи подрядчиков.

Отличия:

Что видноЭто не «root SSH»Куда
Permission denied (publickey) для root, для admin тожеключи/AllowUsersбезопасный sshd
Боты долбят root/admin паролемпарольный доступпарольный SSH
Root локально с консоли, SSH уже noнормаэта статья не про консоль
После reload нет ни root, ни adminlockoutконсоль, откат drop-in

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

От частых к редким:

  1. Образ провайдера или cloud-init: /etc/ssh/sshd_config.d/50-cloud-init.conf с PermitRootLogin yes.
  2. В /etc/ssh/sshd_config стоит yes, drop-in с no имеет раннее имя и проигрывает позднему файлу.
  3. Match User root ниже по конфигу снова разрешает вход.
  4. Ansible/роль «удобный bootstrap» выставляет root-ключ навсегда.
  5. Входите не в sshd, а в дропбер (Teleport, ForceCommand) — тогда смотрите его ACL, не только sshd -T.
  6. Контейнер/LXC с PermitRootLogin в шаблоне, хост при этом уже закрыт.

Диагностика

С рабочей сессии admin или с консоли. Сохраните вывод в каталог заявки.

1. Эффективный sshd, не «файл глазами»

sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers|allowgroups|authenticationmethods'
sudo ls -l /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
sudo grep -RniE 'PermitRootLogin|Match |AllowUsers|AllowGroups' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

sshd -T учитывает Include и порядок. Комментарий в sshd_config ничего не значит, если 60-cloud.conf переопределил параметр.

2. Кто реально логинился как root

sudo journalctl -u ssh --since '7 days ago' --no-pager | grep -E 'Accepted .+ for root|Failed password for root'
sudo grep -E 'Accepted .+ for root' /var/log/auth.log 2>/dev/null | tail
getent passwd root
sudo ls -l /root/.ssh/authorized_keys

На Ubuntu 24.04 часть образов без rsyslog: смотрите journal, не удивляйтесь отсутствию auth.log.

3. Есть ли замена root

getent passwd admin
id admin
sudo grep -R 'admin' /etc/sudoers /etc/sudoers.d/ 2>/dev/null
sudo test -r /home/admin/.ssh/authorized_keys && sudo wc -l /home/admin/.ssh/authorized_keys

Нет admin и нет другого sudo-пользователя — не ставьте PermitRootLogin no в этой же минуте.

Решение

Сценарий A. Есть только root по SSH

  1. С консоли или текущей root-сессии создайте админа (не копируйте UID 0):
sudo adduser --disabled-password --gecos 'System admin' admin
sudo usermod -aG sudo admin
sudo install -d -m 700 -o admin -g admin /home/admin/.ssh
  1. Положите ваш публичный ключ, не ключ с чужой флешки:
# с вашей станции, ключ уже в агенте
ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@10.0.20.10

Если ssh-copy-id недоступен — вставьте одну строку ssh-ed25519 AAAA… comment в /home/admin/.ssh/authorized_keys, chown admin:admin, режим 600 на файл и 700 на .ssh.

  1. Проверьте второе окно, не закрывая первое:
ssh -o BatchMode=yes -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 admin@10.0.20.10 true
ssh -t admin@10.0.20.10 sudo -n true || ssh -t admin@10.0.20.10 sudo -l

sudo должен работать. Если нужен пароль sudo — это нормально и лучше, чем NOPASSWD:ALL; широкие sudo разбирайте отдельно: sudo слишком широкий.

Сценарий B. Закрыть root в sshd

Файл с поздним именем, чтобы перебить cloud-init:

sudo tee /etc/ssh/sshd_config.d/99-no-root.conf >/dev/null <<'EOF'
PermitRootLogin no
EOF
sudo sshd -t && sudo systemctl reload ssh

Не правьте только /etc/ssh/sshd_config, если Include подхватывает 50-cloud-init.conf с yes — вы проиграете лексическому порядку *.conf.

Повторно:

sudo sshd -T | grep permitrootlogin

Ожидание: permitrootlogin no.

Сценарий C. Ключи в /root/.ssh

После перехода на admin ключи root по SSH больше не используются, но файл остаётся целью, если кто-то снова включит root login.

sudo install -d -m 700 /root/ssh-keys-retired
sudo mv /root/.ssh/authorized_keys /root/ssh-keys-retired/authorized_keys.$(date +%F)
sudo : > /root/.ssh/authorized_keys
sudo chmod 600 /root/.ssh/authorized_keys

Инцидент с украденным ключом — не «переименовать файл», а отзыв ключа.

Сценарий D. Нужен аварийный root

Аварийный доступ — консоль гипервизора, BMC, или break-glass пользователь с ключом в сейфе, не PermitRootLogin yes на 0.0.0.0. Пароль root, если он есть, только для консоли, сложный, в секретнице, не в wiki.

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

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

ssh -o BatchMode=yes -o PreferredAuthentications=publickey root@10.0.20.10 true; echo root_exit:$?
ssh -o BatchMode=yes admin@10.0.20.10 true; echo admin_exit:$?
sudo sshd -T | grep permitrootlogin

root должен получить отказ (часто Permission denied). admin — код 0. В journal новых Accepted … for root по SSH нет.

Проверка sudo без SSH-root:

ssh -t admin@10.0.20.10 'sudo -l && hostname -f'

Должны увидеть host.example и список sudo.

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

  • sshd -T всё ещё yes: ищите Match и файл с именем после 99-no-root.conf (например zz-vendor.conf).
  • Ubuntu 24.04, unit ssh.socket: reload ssh.service; при странностях systemctl status ssh.socket ssh.service. Не маскируйте ssh.service.
  • Cloud-init при каждом ребуте переписывает 50-cloud-init.conf: зафиксируйте ssh_pwauth/disable_root в user-data или держите 99-*.conf.
  • Входите по IPv6 на другой адрес, где крутится второй sshd: ss -tlnp | grep ssh.
  • AllowUsers root в конфиге: уберите root из списка, оставьте AllowUsers admin.
  • После закрытия root боты не исчезнут — это парольный доступ и Fail2Ban, не откат PermitRootLogin.

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

  • Золотой образ и cloud-init: сразу admin + ключ, disable_root: true.
  • Мониторинг: алерт, если sshd -Tpermitrootlogin no, или в логе Accepted для uid 0 по sshd.
  • Запрет держать персональные ключи в /root/.ssh «для удобства ansible» — отдельный пользователь деплоя без интерактивного shell, если нужен CI.
  • Регулярный baseline вместе с firewall и патчами.
  • Не используйте один ключ root на весь парк: компрометация одного хоста открывает все.

FAQ

Хватит ли PermitRootLogin prohibit-password?

Нет как целевое состояние. Это отсекает пароль root по SSH, но оставляет root-ключ. Цель — no и именной admin.

Почему ssh root всё ещё спрашивает пароль?

Баннер и запрос пароля не равны успеху. Смотрите, принял ли sshd сессию (Accepted). Запрос могут показывать до MaxAuthTries. Закройте и пароли: ключи вместо пароля.

Можно ли оставить root для ansible?

Можно сделать admin с узким sudo на нужные команды. Root по SSH для playbook — удобство ценой общего секрета. Если очень нужно — только с jump-хоста и ключом, который не лежит в git.

Ubuntu 24.04: править ssh или sshd?

Пакет и юнит называются ssh. Бинарь конфигурации — sshd -t / sshd -T. Reload: systemctl reload ssh.

Что с консольным входом root?

PermitRootLogin не трогает TTY/консоль VM. Локальный root на гипервизоре — отдельная политика (пароль в сейфе, не пустой). Не путайте с SSH.