Публичные ключи в authorized_keys удобны, пока машин десяток. Когда серверов становится больше, а сотрудники приходят и уходят, начинается ручная работа: копирование ключей, удаление строк, поиск забытых доступов. SSH-сертификаты решают эту задачу иначе: администратор один раз добавляет на сервер доверие к центру сертификации, а пользователи получают подписанные сертификаты с именем, сроком действия и ограничениями. Раздача приватных ключей при этом не нужна. Ниже — рабочая схема для собственной инфраструктуры.

Две роли одного механизма

Не путайте пользовательский и хостовый сертификаты. Первый доказывает серверу, кто вы, и подписывается пользовательским CA. Второй доказывает клиенту, что сервер настоящий, и подписывается хостовым CA. Для этих целей нужны разные ключи: компрометация одного не должна автоматически ломать вторую проверку. Приватные ключи CA храните на отдельной машине с ограниченным доступом, а на серверы копируйте только публичные части.

Создание центров сертификации

Создайте каталог с правами 0700 и два ключа ed25519 с парольной фразой. Пароль на ключе CA обязателен: это не повседневный ключ, а корень доверия.

sudo install -d -m 0700 -o root -g root /etc/ssh/ca
sudo ssh-keygen -t ed25519 -a 100 -C "user CA 2026" -f /etc/ssh/ca/user_ca
sudo ssh-keygen -t ed25519 -a 100 -C "host CA 2026" -f /etc/ssh/ca/host_ca
sudo chmod 600 /etc/ssh/ca/user_ca /etc/ssh/ca/host_ca

Параметр -a 100 увеличивает число итераций KDF при проверке пароля. Публичные файлы *.pub можно свободно раздавать: они нужны серверам и клиентам для проверки подписи. Сделайте резервную копию закрытых ключей на офлайн-носителе и проверьте, что восстановление действительно работает.

Выпуск пользовательского сертификата

Пользователь генерирует обычную пару ключей у себя, отдаёт публичную часть и получает сертификат. Сертификат кладётся рядом с ключом и должен называться так же, с суффиксом -cert.pub: тогда ssh найдёт его автоматически.

ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519
ssh-keygen -s /etc/ssh/ca/user_ca \
  -I "alice@laptop-2026-11" -n alice,deploy -V +12h -z 1042 \
  -O no-agent-forwarding -O no-port-forwarding -O no-x11-forwarding \
  ~/.ssh/id_ed25519.pub
ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub

-I задаёт идентификатор для журналов, -n — список principals, то есть имён, под которыми можно войти. -V +12h ограничивает срок двенадцатью часами, -z задаёт серийный номер для будущего отзыва. Команда ssh-keygen -L показывает содержимое сертификата: principals, срок, серийный номер и разрешения. Читайте этот вывод перед выдачей, а не после инцидента.

Ограничения внутри сертификата

Главная выгода сертификата — политика, подписанная вместе с ключом. Можно разрешить вход только из подсети, привязать сертификат к одной команде или потребовать аппаратную проверку пользователя. Опция clear сбрасывает все разрешения, после чего их нужно выдать явно.

ssh-keygen -s /etc/ssh/ca/user_ca -I "backup-job" \
  -n backup -V +2h -O clear \
  -O force-command="/usr/local/sbin/backup.sh" \
  -O source-address=10.20.0.0/16 /tmp/backup.pub

В примере сертификат не даёт интерактивной оболочки: после clear не разрешён PTY, а force-command заменяет любую команду пользователя. Для интерактивных сотрудников оставьте permit-pty, но уберите переадресацию агента и X11, если они не нужны. Для ключей FIDO2 полезна опция verify-required: она требует PIN при каждом использовании.

Настройка сервера

На каждом сервере добавьте публичный ключ пользовательского CA и запретите обычные файлы авторизации, чтобы доступ нельзя было обойти старым ключом. Список отозванных сертификатов подключается отдельно.

# /etc/ssh/sshd_config.d/10-cert-auth.conf
PubkeyAuthentication yes
TrustedUserCAKeys /etc/ssh/ca/user_ca.pub
AuthorizedKeysFile none
RevokedKeys /etc/ssh/revoked_keys
AuthorizedPrincipalsFile /etc/ssh/principals/%u

AuthorizedPrincipalsFile добавляет вторую проверку: principal из сертификата должен быть перечислен в файле /etc/ssh/principals/alice. Это защищает от ошибки, когда сертификат выписан на слишком широкое имя. Файлы должны принадлежать root и быть недоступны на запись другим. Перед перезагрузкой проверьте конфигурацию через sshd -t, а затем перезагрузите службу. Не отключайте парольный вход, пока не убедились, что сертификат работает в отдельном сеансе.

Сертификаты хостов

Хостовый сертификат убирает вопрос «доверять ли этому отпечатку» при первом подключении. Клиенту достаточно один раз получить публичный ключ хостового CA.

sudo ssh-keygen -s /etc/ssh/ca/host_ca -I "web01-2026" -h \
  -n web01.example.com,10.0.0.11 -V +30d \
  /etc/ssh/ssh_host_ed25519_key.pub
ssh-keygen -L -f /etc/ssh/ssh_host_ed25519_key-cert.pub

В sshd_config добавьте HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub. На клиенте в ~/.ssh/known_hosts появится строка @cert-authority *.example.com ssh-ed25519 AAAA... с публичным ключом хостового CA. После этого новые серверы в домене принимаются автоматически, а подмена хоста без подписи CA обнаруживается. Срок жизни хостовых сертификатов делайте больше пользовательских, но не бесконечным.

Отзыв и ротация

Короткий срок жизни снижает потребность в отзыве, но украденный сертификат нужно уметь заблокировать немедленно. Для этого служит KRL — двоичный список отозванных ключей и серийных номеров. Он генерируется из текстового описания.

printf 'serial: 1042\n' > /tmp/revoke.spec
sudo ssh-keygen -k -f /etc/ssh/revoked_keys \
  -s /etc/ssh/ca/user_ca.pub /tmp/revoke.spec
sudo ssh-keygen -k -u -f /etc/ssh/revoked_keys \
  -s /etc/ssh/ca/user_ca.pub /tmp/revoke-1043.spec
ssh-keygen -Q -f /etc/ssh/revoked_keys /tmp/alice-cert.pub

Флаг -u дополняет существующий KRL, а без него файл создаётся заново. Команда -Q проверяет, попал ли сертификат в список, и возвращает ненулевой код, если он отозван. Серийные номера не переиспользуйте: при подписи берите следующий из базы или используйте -z +1042, чтобы ssh-keygen увеличивал номер для каждого файла в одной команде.

Диагностика

Большинство ошибок видны в подробном выводе клиента и журнале сервера. Ищите строки ED25519-CERT: они подтверждают, что сервер принял именно сертификат, а не обычный ключ.

ssh -vvv alice@web01.example.com 2>&1 | grep -i cert
sudo sshd -T | grep -Ei 'trusteduserca|revokedkeys|authorizedkeysfile'
sudo journalctl -u ssh -n 50 --no-pager

Сообщение «Certificate invalid: not yet valid» означает рассинхронизацию часов, «principal not permitted» — несовпадение имени, «invalid certificate» — сертификат подписан не тем CA. Проверяйте время через timedatectl и права на файлы CA: sshd игнорирует ключ, если файл доступен на запись группе или остальным.

Чек-лист

  • Пользовательский и хостовый CA разделены, закрытые ключи защищены паролем.
  • Сертификаты выдаются на короткий срок и содержат только нужные principals.
  • AuthorizedKeysFile none и TrustedUserCAKeys прописаны на всех серверах.
  • KRL обновляется по процедуре, серийные номера уникальны.
  • Резервная копия CA проверена восстановлением.
  • Мониторинг следит за отказами аутентификации и истечением срока CA.

Итог

SSH-сертификаты заменяют ручную раздачу ключей на управляемую политику: один CA, короткие сроки, principals и ограничения в подписанном виде. Схема требует дисциплины — защиты CA, ротации и отзыва, — но именно она делает доступ к инфраструктуре предсказуемым и проверяемым.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте