Один пользователь смог войти по SSH под другим со своим ключом: не слабость ключей, а права на домашний каталог, позволившие дописать authorized_keys

Что было. Администратор заметил, что с ключом пользователя user1 можно войти на сервер под учётной записью user2, и решил, что вход по RSA-ключам небезопасен.

Что оказалось. Ключи работают ровно как задумано: сервер пускает того, чей публичный ключ лежит в ~/.ssh/authorized_keys целевого пользователя. Проблема была в том, как ключ user1 туда попал: домашний каталог /home/user2 имел группу users с правом записи для группы, а user1 состоял в этой группе и мог создать или изменить .ssh/authorized_keys соседа. Исправление chgrp user2 /home/user2 (и права 750) закрыло дыру; подтверждено. Участники отдельно напомнили: приватный ключ никогда не покидает клиент, в отличие от пароля, поэтому ключи по-прежнему безопаснее.

Почему sshd это пропустил. StrictModes yes (по умолчанию) проверяет права на ~/.ssh и authorized_keys и отказывает, если они доступны на запись другим. Но проверка касается самого каталога .ssh и файла; если .ssh ещё не существовал, а домашний каталог был доступен группе на запись, злоумышленник создаёт .ssh с правильными правами сам, и проверка проходит. Отсюда правило: домашние каталоги не должны быть доступны на запись никому, кроме владельца.

Проверка всей системы за минуту.

find /home -maxdepth 1 -mindepth 1 -type d -perm /g+w,o+w -ls          # каталоги с записью для группы/остальных
find /home -maxdepth 3 -path '*/.ssh*' -perm /g+w,o+w -ls               # .ssh и ключи с лишними правами
for d in /home/*; do u=$(basename "$d"); [ "$(stat -c %U:%G "$d")" = "$u:$u" ] || echo "$d: $(stat -c %U:%G "$d")"; done

Исправление: chown user:user /home/user && chmod 750 /home/user (или 700). В /etc/adduser.conf параметр DIR_MODE=0750 для новых пользователей; в /etc/login.defs UMASK 027.

Дополнительные меры.

  • AuthorizedKeysFile /etc/ssh/authorized_keys/%u в sshd_config: ключи хранятся в каталоге, принадлежащем root, пользователи не могут сами добавлять ключи; администрирование ключей централизовано.
  • Аудит authorized_keys: периодический список отпечатков по всем пользователям (for f in /home/*/.ssh/authorized_keys; do echo $f; ssh-keygen -lf $f; done) и сравнение с реестром выданных ключей.
  • Группа users как основная у всех это устаревшая схема; в Debian/Ubuntu у каждого пользователя своя группа, и не стоит это менять ради «удобства общих папок» (для них есть setgid-каталоги, отдельный разбор).

Параметр описан в документации OpenSSH.