SSH-сертификаты с подписью - самый простой и мощный способ доступа на сервер с точки зрения простоты настройки и независимости от платформы. Используя возможности Stronghold по созданию CA и функциональность, встроенную в OpenSSH, клиенты могут подключаться к удаленным хостам по SSH, используя свои собственные локальные SSH-ключи.
В этом разделе термин «клиент» (client) относится к человеку или машине, выполняющей операцию SSH. Термин «хост» (host) относится к удаленной машине. Если вас это смущает, замените «клиент» на «пользователь».
На этой странице представлен быстрый старт по использованию этого механизма секретов.
Подпись ключей клиентов
Первоначально необходимо настроить механизм SSH-секретов Stronghold, после чего клиенту будет доступна возможность подписи своего SSH-ключа. Обычно эти действия выполняет администратор stronghold или команда безопасности. Также можно автоматизировать эти действия с помощью инструментов управления конфигурацией, таких как Chef, Puppet, Ansible или Salt.
Создание ключа подписи и настройка роли
Следующие шаги выполняются администратором Stronghold, командой безопасности или средствами управления конфигурацией.
- Смонтируйте механизм секретов. Без этой операции, механизм секретов SSH работать не будет.
$ stronghold secrets enable -path=ssh-client-signer ssh
Successfully mounted 'ssh' at 'ssh-client-signer'!
Эта команда включает механизм секретов SSH по пути «ssh-client-signer»
.
Можно подключать один и тот же механизм секретов несколько раз, используя разные аргументы -path
.
Имя «ssh-client-signer»
не является специальным - оно может быть любым, в данной документации будет использоваться «ssh-client-signer»
в качестве примера.
- Настройте Stronghold c CA для подписи клиентских ключей с помощью метода (endpoint)
/config/ca
. Если у вас нет внутреннего CA, Stronghold может сгенерировать публичный и приватный ключи для вас.
$ stronghold write ssh-client-signer/config/ca generate_signing_key=true
Key Value
--- -----
public_key ssh-rsa AAAAB3NzaC1yc2EA...
Если у вас уже есть пара ssh-ключей, укажите части открытого и закрытого ключей в составе команды:
$ stronghold write ssh-client-signer/config/ca \
private_key="..." \
public_key="..."
Механизм секретов SSH позволяет настраивать несколько сертификатов доверенного центра сертификации (CA) в одном монтировании.
Эта возможность предназначена для облегчения ротации CA. При настройке CA один эмитент (issuer) назначается по умолчанию - его операции будут использоваться во всех случаях, когда при создании роли не указан конкретный эмитент.
Эмитента по умолчанию можно изменить в любой момент, сгенерировав новый CA или обновив его через метод конфигурации, такой подход обеспечивает беспрепятственную ротацию CA.
Независимо от того, сгенерирован или загружен открытый ключ, он доступен через API в методе /public_key
или через CLI (см. следующий шаг).
- Добавьте открытый ключ во все конфигурации SSH хоста. Этот процесс можно выполнить вручную или автоматизировать с помощью инструмента управления конфигурацией. Открытый ключ доступен через API и не требует аутентификации.
curl -o /etc/ssh/trusted-user-ca-keys.pem http://127.0.0.1:8200/v1/ssh-client-signer/public_key
stronghold read -field=public_key ssh-client-signer/config/ca > /etc/ssh/trusted-user-ca-keys.pem
Добавьте путь, где хранится содержимое открытого ключа, в конфигурационный файл SSH в качестве опции TrustedUserCAKeys
.
# /etc/ssh/sshd_config
# ...
TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
Перезагрузите службу SSH, чтобы применить изменения.
- Создайте в Stronghold роль с произвольным именем для подписи клиентских ключей. Из-за реализации некоторых функции сертификата SSH, опции передаются в виде ключ-значение.
Следующий пример добавляет расширение permit-pty
к сертификату и позволяет пользователю указать собственные значения для permit-pty
и permit-port-forwarding
при запросе сертификата.
$ stronghold write ssh-client-signer/roles/my-role -<<"EOH"
{
"algorithm_signer": "rsa-sha2-256",
"allow_user_certificates": true,
"allowed_users": "*",
"allowed_extensions": "permit-pty,permit-port-forwarding",
"default_extensions": {
"permit-pty": ""
},
"key_type": "ca",
"default_user": "ubuntu",
"ttl": "30m0s"
}
EOH
Аутентификация клиента по SSH
Следующие шаги выполняются клиентом (пользователем), который хочет аутентифицироваться на машинах, управляемых Stronghold. Эти команды обычно выполняются с локальной рабочей станции клиента.
- Найдите или сгенерируйте открытый ключ SSH. Обычно он расположен по пути
~/.ssh/id_rsa.pub
.
Если у вас нет пары ключей SSH, сгенерируйте их:
ssh-keygen -t rsa -C "user@example.com"
- Попросите Stronghold подписать ваш публичный ключ (public key). Этот файл обычно заканчивается на
.pub
, а его содержимое начинается сssh-rsa ...
.
$ stronghold write ssh-client-signer/sign/my-role \
public_key=@$HOME/.ssh/id_rsa.pub
Key Value
--- -----
serial_number c73f26d2340276aa
signed_key ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1...
Результат будет содержать серийный номер (уникальный идентификатор сертификата) и подписанный ключ. Этот подписанный ключ является еще одним открытым ключом. Чтобы настроить параметры подписи, используйте запрос в формате JSON:
$ stronghold write ssh-client-signer/sign/my-role -<<"EOH"
{
"public_key": "ssh-rsa AAA...",
"valid_principals": "my-user",
"key_id": "custom-prefix",
"extensions": {
"permit-pty": "",
"permit-port-forwarding": ""
}
}
EOH
- Сохраните полученный подписанный открытый ключ на диске. При необходимости ограничьте права доступа.
$ stronghold write -field=signed_key ssh-client-signer/sign/my-role \
public_key=@$HOME/.ssh/id_rsa.pub > signed-cert.pub
Если вы сохраняете сертификат непосредственно рядом с парой ключей SSH, добавьте в имя файла суффикс -cert.pub
(~/.ssh/id_rsa-cert.pub
).
При такой схеме именования OpenSSH будет автоматически использовать его при аутентификации.
- (Необязательно) Просмотр включенных расширений, списка пользователей, хостов и метаданных подписанного ключа.
ssh-keygen -Lf ~/.ssh/signed-cert.pub
-Выполните на локальной машине команду ssh
, используя подписанный ключ. Вы должны передать как подписанный открытый ключ, так и соответствующий закрытый ключ в качестве аутентификации для установки SSH-соединения.
ssh -i signed-cert.pub -i ~/.ssh/id_rsa username@10.0.23.5
Подпись ключа хоста (host)
Для дополнительного уровня безопасности мы рекомендуем включить подпись ключей хоста. Эта функциональность используется вместе с подписью клиентских ключей для обеспечения дополнительного уровня целостности. Если эта функция включена, агент SSH будет проверять, что удаленный хост является действительным и доверенным, прежде чем попытаться выполнить SSH. Это снизит вероятность того, что пользователь случайно подключится по SSH к вредоносной машине.
Настройка подписи ключа
- Подключите Stronghold к другому пути, отличному от пути подписи клиента.
$ stronghold secrets enable -path=ssh-host-signer ssh
Successfully mounted 'ssh' at 'ssh-host-signer'!
- Настройте Stronghold c CA для подписания ключей хоста с помощью метода
/config/ca
. Если у вас нет внутреннего CA, Stronghold может сгенерировать ключевую пару для вас.
$ stronghold write ssh-host-signer/config/ca generate_signing_key=true
Key Value
--- -----
public_key ssh-rsa AAAAB3NzaC1yc2EA...
Если у вас уже есть пара ключей SSH, укажите части открытого и закрытого ключей в составе запроса:
$ stronghold write ssh-host-signer/config/ca \
private_key="..." \
public_key="..."
Открытый ключ подписывающего хоста доступен через API в методе /public_key
.
- Увеличение времени TTL сертификата ключа хоста.
stronghold secrets tune -max-lease-ttl=87600h ssh-host-signer
- Создайте роль для подписи ключей хоста. Обязательно заполните список разрешенных доменов, установите
allow_bare_domains
или и то, и другое.
$ stronghold write ssh-host-signer/roles/hostrole \
key_type=ca \
algorithm_signer=rsa-sha2-256 \
ttl=87600h \
allow_host_certificates=true \
allowed_domains="localdomain,example.com" \
allow_subdomains=true
- Подпишите открытый ключ SSH хоста.
$ stronghold write ssh-host-signer/sign/hostrole \
cert_type=host \
public_key=@/etc/ssh/ssh_host_rsa_key.pub
Key Value
--- -----
serial_number 3746eb17371540d9
signed_key ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1y...
- Установите полученный подписанный сертификат в качестве
HostCertificate
в конфигурации SSH на хост-машине.
$ stronghold write -field=signed_key ssh-host-signer/sign/hostrole \
cert_type=host \
public_key=@/etc/ssh/ssh_host_rsa_key.pub > /etc/ssh/ssh_host_rsa_key-cert.pub
Установите права доступа к сертификату на 0640
:
chmod 0640 /etc/ssh/ssh_host_rsa_key-cert.pub
Добавьте ключ хоста и сертификат хоста в файл конфигурации SSH.
# /etc/ssh/sshd_config
# ...
# For client keys
TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
# For host keys
HostKey /etc/ssh/ssh_host_rsa_key
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
Перезапустите службу SSH, чтобы применить изменения.
Верификация хоста на стороне клиента
- Получите открытый ключ CA хоста для проверки подписи хоста.
curl http://127.0.0.1:8200/v1/ssh-host-signer/public_key
stronghold read -field=public_key ssh-host-signer/config/ca
- Добавьте полученный открытый ключ в файл
known_hosts
.
# ~/.ssh/known_hosts
@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAA...
- Можно выполнять вход по SSH на удаленные машины.
Устранение неполадок
Для облегчения настройки и отладки процесса подписания ключей, включите функцию VERBOSE
в конфигурации SSH.
# /etc/ssh/sshd_config
# ...
LogLevel VERBOSE
Выполните перезапуск SSH после внесения изменений.
По умолчанию SSH ведет журнал в /var/log/auth.log
, но в нем так же будут записи от других служб. Чтобы извлечь только журналы SSH, выполните следующие действия:
tail -f /var/log/auth.log | grep --line-buffered "sshd"
Если вам не удается установить соединение с хостом, логи сервера SSH могут помочь в поиске причин.
Имя пользователя не входит в список основных пользователей
Если в auth.log
отображаются следующие сообщения:
# /var/log/auth.log
key_cert_check_authority: invalid certificate
Certificate invalid: name is not a listed principal
Сертификат не разрешает использовать имя пользователя в качестве основного имени для аутентификации в системе.
Скорее всего, это связано с ошибкой OpenSSH (подробнее см. в known issues).
Эта ошибка не учитывает значение опции allowed_users
, равное «*». Вот способы обойти эту проблему:
- Установите роли
default_user
. Если вы всегда аутентифицируетесь под одним и тем же пользователем, установите рольdefault_user
на имя пользователя, с которым вы подключаетесь по SSH к удаленной машине:
stronghold write ssh/roles/my-role -<<"EOH"
{
"default_user": "YOUR_USER",
// ...
}
EOH
- Установите
valid_principals
во время подписания. В ситуациях, когда несколько пользователей могут проходить аутентификацию в SSH через Stronghold, установите, чтобы список основных имен пользователей при подписании ключа включал текущее имя пользователя:
$ stronghold write ssh-client-signer/sign/my-role -<<"EOH"
{
"valid_principals": "my-user"
// ...
}
EOH
Нет приглашения для ввода команд после входа в систему
Если вы не видите приглашения для ввода команд после аутентификации на хост-машине, возможно, в подписанном сертификате отсутствует расширение permit-pty
.
Существует два способа добавить это расширение в подписанный сертификат.
- В рамках создания роли
$ stronghold write ssh-client-signer/roles/my-role -<<"EOH"
{
"default_extensions": {
"permit-pty": ""
}
// ...
}
EOH
- В рамках самой операции подписи:
$ stronghold write ssh-client-signer/sign/my-role -<<"EOH"
{
"extensions": {
"permit-pty": ""
}
// ...
}
EOH
Нет переадресации портов
Если переадресация портов с удаленного компьютера на хост не работает, возможно, в подписанном сертификате отсутствует расширение permit-port-forwarding
.
Добавьте расширение в процессе создания или подписи роли, чтобы включить переадресацию портов. Примеры см. в предыдущем разделе.
{
"default_extensions": {
"permit-port-forwarding": ""
}
}
Нет переадресации x11
Если переадресация X11 с удаленного компьютера на хост не работает, возможно, в подписанном сертификате отсутствует расширение permit-X11-forwarding
.
Добавьте расширение в процессе создания или подписи роли, чтобы включить переадресацию X11. Примеры см. в разделе “Нет подсказки после входа в систему”.
{
"default_extensions": {
"permit-X11-forwarding": ""
}
}
Нет переадресации агента
Если переадресация агентов с удаленного компьютера на хост не работает, в подписанном сертификате может отсутствовать расширение permit-agent-forwarding
.
Добавьте расширение в процессе создания или подписи роли, чтобы включить переадресацию агентов. Примеры см. в разделе “Нет подсказки после входа в систему”.
{
"default_extensions": {
"permit-agent-forwarding": ""
}
}
Комментарии для ключа
Если требуется сохранение атрибутов комментариев в ключах, то для этой операции могут быть необходимы дополнительные шаги.
Закрытый и открытый ключи могут иметь комментарии, например, аналогично тому как используется ssh-keygen
с параметром -C
:
ssh-keygen -C "...Comments" -N "" -t rsa -b 4096 -f host-ca
Значения ключей, содержащие комментарии, должны быть переданы вместе с параметрами, связанными с данным ключем. Ниже приведены примеры команд с использованием Stronghold CLI и API.
# Using CLI:
stronghold secrets enable -path=hosts-ca ssh
KEY_PRI=$(cat ~/.ssh/id_rsa | sed -z 's/\n/\\n/g')
KEY_PUB=$(cat ~/.ssh/id_rsa.pub | sed -z 's/\n/\\n/g')
# Create / update keypair in stronghold
stronghold write ssh-client-signer/config/ca \
generate_signing_key=false \
private_key="${KEY_PRI}" \
public_key="${KEY_PUB}"
# Using API:
curl -X POST -H "X-Vault-Token: ..." -d '{"type":"ssh"}' http://127.0.0.1:8200/v1/sys/mounts/hosts-ca
KEY_PRI=$(cat ~/.ssh/id_rsa | sed -z 's/\n/\\n/g')
KEY_PUB=$(cat ~/.ssh/id_rsa.pub | sed -z 's/\n/\\n/g')
tee payload.json <<EOF
{
"generate_signing_key" : false,
"private_key" : "${KEY_PRI}",
"public_key" : "${KEY_PUB}"
}
EOF
# Create / update keypair in stronghold
curl -X POST -H "X-Vault-Token: ..." -d @payload.json http://127.0.0.1:8200/v1/hosts-ca/config/ca
Не добавляйте пароль к закрытому ключу, так как Stronghold не сможет его расшифровать. Уничтожьте открытый и закрытый ключи и payload.json
с вашего хоста сразу после подтверждения успешной загрузки.
Известные проблемы
-
В системах, поддерживающих SELinux, вам может потребоваться настроить связанные типы, чтобы демон SSH мог их читать. Например, установить для подписанного сертификата хоста тип
sshd_key_t
. -
В некоторых версиях SSH вы можете получить следующую ошибку:
no separate private key for certificate
Эта ошибка появилась в OpenSSH версии 7.2 и была исправлена в версии 7.5. См. OpenSSH bug 2617
- В некоторых версиях SSH вы можете получить следующую ошибку на хосте:
userauth_pubkey: certificate signature algorithm ssh-rsa: signature algorithm not supported [preauth]
Исправление заключается в добавлении следующей строки в /etc/ssh/sshd_config
CASignatureAlgorithms ^ssh-rsa
Алгоритм ssh-rsa больше не поддерживается в OpenSSH 8.2