Настройка SSH-доступа¶
Пошагово: что нажать в админке и что положить на ваш сервер. Что это за функция и зачем нужны два механизма — в обзоре раздела.
Настройка делается один раз. После неё сотрудник входит обычной командой
ssh, а вы управляете доступом из интерфейса.
Шаг 1. Разрешите выдачу в админке¶
Ключ не появляется у сотрудника сам: сначала выдачу разрешает администратор.
- Откройте Настройки → Политика выдачи и включите строку «SSH» в
колонке «Выдаём». У каждой цели здесь свой переключатель: включать
«mTLS пользователя» или любую другую цель ради SSH не требуется. Если
выдача включается не для всего парка машин, а точечно — откройте
Устройства, раскройте строку нужной машины и в блоке «Цели на этой
машине» переключите
sshс «как в системе» на «разрешить сверх системного» (или наоборот — «запретить вопреки системному», если у вас включена выдача по всему парку, а этой машине SSH не положен). - Откройте Устройства, раскройте строку машины и назначьте ей цель
ssh. Цель — это то, что Alatyr выдаёт на устройство; цельsshозначает SSH-ключ.
Результат. Через несколько минут агент на машине сотрудника создаст ключ и пришлёт его на одобрение.
Если ключ не появляется
Откройте Настройки → SSH-ключи и посмотрите на настройку
«Требовать подтверждение identity у SSH-ключей». Если выбрано
«Обязательно», сервер отклоняет регистрацию ключа до тех пор, пока на
этом же устройстве нет одобренного сертификата user_mtls, ad_logon
или k8s. Окно агента в этом случае покажет «Сервер отказал в
регистрации ключа» и причину. Для начала работы выберите «Наблюдение»:
вердикт продолжит записываться, но вход будет работать.
Шаг 2. Одобрите ключ¶
Откройте раздел SSH-ключи в левом меню. Новый ключ появится в списке со
статусом pending. Проверьте, что владелец и устройство те самые, и нажмите
«Одобрить».
Результат. Статус сменится на active — с этого момента Alatyr считает
ключ действующим. Осталось научить ваш сервер спрашивать об этом.
Шаг 3. Возьмите два значения из админки¶
Откройте Настройки → SSH-ключи и найдите блок «Доверие на ваших серверах». В нём два значения:
- Публичный ключ SSH CA — им подписаны сертификаты. Скопируйте его и
сохраните на сервере как
/etc/ssh/alatyr_user_ca.pub. - Список отзыва (KRL) — перечень отозванных сертификатов. Скачайте его и
положите на сервер как
/etc/ssh/alatyr.krl.
Оба значения открытые: их можно копировать, хранить в системе управления конфигурацией и раздавать на серверы обычным способом.
Результат. На вашем сервере лежат два файла: alatyr_user_ca.pub и
alatyr.krl.
Шаг 4. Разрешите вашему серверу спрашивать Alatyr¶
Ваш сервер обращается к Alatyr через Keyholder — служебный интерфейс, предназначенный для серверов, а не для людей. По умолчанию он закрыт для всех, и его нужно открыть для ваших адресов.
В том же разделе Настройки → SSH-ключи:
-
В поле «Разрешённые сети (CIDR)» перечислите подсети, из которых будут приходить запросы, — например
10.0.5.0/24. Пустое поле означает «закрыто для всех». Это не оплошность, а умолчание: пока вы не назовёте хотя бы одну подсеть, ваши серверы будут получать отказ.Подсеть должна быть узкой: не шире
/24для IPv4 и не шире/64для IPv6. Это граница между «наши хосты» и «наша сеть»: Keyholder — служебный интерфейс для считанных серверов, и сеть вроде10.0.0.0/8впустила бы к нему всех, кто в неё попадает. Список из нескольких/24— норма; одна широкая запись сервер отклонит с ошибкой, и это не сбой, а тот же предел. 2. Если ограничения по сети вам недостаточно, включите «Серверный токен держателя ключа» и создайте токен кнопкой ниже. Значение токена показывается один раз — сохраните его сразу, восстановить нельзя.
Результат. Запросы с ваших серверов больше не отклоняются по адресу.
Что даёт разрешённая сеть, а что нет
Список подсетей ограничивает, откуда можно спрашивать, но не о ком. Любой хост из разрешённой сети может запросить ключи любого сотрудника. Если это неприемлемо, включайте токен.
Шаг 5. Настройте ваш сервер¶
Положите на сервер файл настроек:
# /etc/ssh/sshd_config.d/alatyr.conf
# Сертификаты: сервер проверяет подпись сам, в сеть не ходит.
TrustedUserCAKeys /etc/ssh/alatyr_user_ca.pub
RevokedKeys /etc/ssh/alatyr.krl
# Ключи из реестра: сервер спрашивает Alatyr на каждый вход.
AuthorizedKeysCommand /etc/ssh/alatyr-keys.sh
AuthorizedKeysCommandUser root
И сам скрипт, который ходит за ключами:
#!/bin/sh
# /etc/ssh/alatyr-keys.sh — sshd передаёт имя учётной записи первым аргументом
set -eu
. /etc/ssh/alatyr.env
curl -fsS -m 5 \
-H "Authorization: Bearer $KEYHOLDER_TOKEN" \
"$ALATYR_URL/api/v1/keyholder/keys?principal=$1" \
| python3 -c 'import json,sys; [print(k) for k in json.load(sys.stdin)["keys"]]'
Рядом — файл с адресом сервера и токеном:
# /etc/ssh/alatyr.env
ALATYR_URL=https://alatyr.example.com
KEYHOLDER_TOKEN=<значение из шага 4>
sudo chown root:root /etc/ssh/alatyr.env
sudo chmod 0600 /etc/ssh/alatyr.env
Отдельный файл нужен не для порядка: sshd запускает
AuthorizedKeysCommand с пустым окружением, поэтому переменные,
заданные в профиле или в systemd, до скрипта не доходят.
ALATYR_URL — адрес вашего сервера Alatyr, тот же, что в адресной строке
админки. Если токен вы не включали (шаг 4), строку с Authorization из
скрипта уберите, а KEYHOLDER_TOKEN из файла удалите.
Разбирайте ответ целиком, а не поиском по строке
Ключи Alatyr начинаются с ecdsa-sha2-nistp256, а не с ssh-. Пример
выше разбирает JSON, поэтому работает с любым типом ключа; самодельный
фильтр вида grep ssh- не найдёт ничего и даст отказ входа без
объяснения.
Скрипт должен принадлежать root — иначе sshd откажется его запускать:
sudo chown root:root /etc/ssh/alatyr-keys.sh
sudo chmod 0755 /etc/ssh/alatyr-keys.sh
# Debian и Ubuntu:
sudo systemctl reload ssh
# RHEL, CentOS, Alma, Rocky, SUSE:
sudo systemctl reload sshd
Права 0755 и владелец root — это требование sshd: он отказывается
запускать команду, в которую может писать кто-то кроме владельца.
Результат. sshd прочитал настройку — проверьте это командой:
sudo sshd -T | grep -i authorizedkeyscommand
В ответе должен быть путь /etc/ssh/alatyr-keys.sh.
Обновление списка отзыва¶
Список отзыва не обновляется сам — поставьте задание по расписанию:
#!/bin/sh
# /etc/ssh/alatyr-krl-update.sh — запускается от root, раз в час
set -eu
. /etc/ssh/alatyr.env
KRL=/etc/ssh/alatyr.krl
TMP=$(mktemp /etc/ssh/.alatyr.krl.XXXXXX)
trap 'rm -f "$TMP"' EXIT
curl -fsS -m 15 -H "Authorization: Bearer $KEYHOLDER_TOKEN" \
"$ALATYR_URL/api/v1/keyholder/krl" -o "$TMP"
[ -s "$TMP" ] || { echo "пустой список отзыва — не подменяю" >&2; exit 1; }
ssh-keygen -Q -l -f "$TMP" >/dev/null || { echo "файл не разбирается" >&2; exit 1; }
chmod 644 "$TMP"; mv "$TMP" "$KRL"; trap - EXIT
Три проверки в скрипте — не перестраховка:
- Скачиваем во временный файл.
sshdчитает этот файл на каждый вход; оборванная загрузка прямо в боевой файл закроет вход всем, включая вас. - Не подменяем пустым. Пустой файл означает «никто не отозван». Положив его, вы вернёте доступ тем, у кого его забрали.
- Проверяем, что файл читается. Битый файл
sshdне примет.
Скрипт пишет в /etc/ssh, поэтому запускается от root. Раз в час —
достаточно: сертификат живёт сутки, и час задержки отзыва укладывается в его
срок жизни.
sudo chown root:root /etc/ssh/alatyr-krl-update.sh
sudo chmod 0755 /etc/ssh/alatyr-krl-update.sh
echo '0 * * * * root /etc/ssh/alatyr-krl-update.sh' | sudo tee /etc/cron.d/alatyr-krl
Результат. Файл /etc/ssh/alatyr.krl существует и обновляется — проверьте
дату командой ls -l /etc/ssh/alatyr.krl через час после установки задания.
Шаг 6. Направьте ssh сотрудника на ключ в чипе¶
Ключ живёт в чипе, и подаёт его агент Alatyr через свой сокет — а не обычный
ssh-agent и не файл в ~/.ssh. В большинстве случаев клиент ssh находит
этот сокет сам:
- Windows — агент дописывает в
~/.ssh/configстрокуIdentityAgent, указывающую на его канал; - Linux — пакет кладёт
/etc/profile.d/alatyr-agent-ssh-agent.sh, и обычная оболочка входа (bash,zsh,ksh) получаетSSH_AUTH_SOCKавтоматически; - macOS — сокет поднимается в пользовательской сессии.
Проверьте, что клиент видит именно ключ Alatyr:
ssh-add -l
# в списке должен быть ключ с пометкой (alatyr-agent)
Если ключа в списке нет — клиент смотрит на чужой ssh-agent. Так бывает,
когда переменную SSH_AUTH_SOCK уже занял системный ключ-агент рабочего стола
(GNOME Keyring и подобные) или оболочка не читает /etc/profile.d (например
fish). Направьте клиент на сокет Alatyr явно.
Сокет агента:
Linux: ~/.local/state/alatyr-agent/ssh-agent.sock
macOS: ~/Library/Application Support/AlatyrAgent/ssh-agent.sock
Способ 1 — строка в ~/.ssh/config (действует всегда и переживает системный
ключ-агент, и для ssh, и для scp, rsync, git):
Host *
IdentityAgent ~/.local/state/alatyr-agent/ssh-agent.sock
Способ 2 — переменная окружения (в текущей оболочке или в профиле входа):
export SSH_AUTH_SOCK=~/.local/state/alatyr-agent/ssh-agent.sock
Теперь пробуйте вход с машины сотрудника:
ssh ivan@server.example.com
На Linux и macOS в момент входа агент попросит подтвердить присутствие — в окне на рабочем столе сотрудника. Пока оно не подтверждено, вход ждёт; без ответа примерно через минуту он завершится ошибкой. Это ожидаемое поведение, а не сбой.
Окно разблокировки: чтобы не подтверждать присутствие на каждый вход¶
Подтверждение присутствия из предыдущего абзаца можно один раз выдать на
несколько входов вперёд, а не проходить заново на каждую команду ssh. Срок
такой выдачи называется окном разблокировки, и на трёх платформах он
устроен по-разному:
- Windows. Сотрудник сам задаёт себе окно командой агента:
alatyr-agent ssh-grant-window [минуты]
Без аргумента команда показывает текущее значение; с аргументом — задаёт
новое, от 0 до 1440 минут (сутки). Пока окно не истекло, повторные входы
подписываются без нового запроса Windows Hello. Значение 0 означает «спрашивать
на каждый вход» — так и работает по умолчанию, пока сотрудник не задал своё.
- macOS. Персонального значения нет: длительность выбирается прямо на
уведомлении, которое появляется в момент подтверждения — кнопками на
1 минуту и на действующий максимум минут (число подставляется в подпись
кнопки), плюс кнопка «Не сохранять». Дольше 5 минут окно не бывает ни
при каком потолке, заданном администратором, — это жёсткий предел Touch ID
(LATouchIDAuthenticationMaximumAllowableReuseDuration), а не решение
продукта: macOS сам перестаёт держать повторное использование биометрии
после этого срока.
- Linux. Окна разблокировки нет вовсе: подпись SSH-ключа на Linux не
поднимает системного запроса, который окно могло бы подавлять.
Потолок для всех платформ задаёт администратор: Настройки →
Безопасность по умолчанию → «Окно разблокировки SSH — потолок для всех
платформ (минуты, макс. 1440)». Своё значение, заданное сотрудником на
Windows командой ssh-grant-window, не может превысить этот потолок —
меньшее из двух побеждает всегда. На macOS потолок всё равно не даст больше
5 минут: платформенный предел применяется поверх административного. Значение
0 (по умолчанию) отключает повторное использование для всех: подтверждение
присутствия спрашивается на каждый вход независимо от того, что сотрудник
выставил себе сам.
Если вход прошёл — готово. Посмотрите в журнале сервера, чем именно вошли:
sudo journalctl -u ssh | grep "Accepted publickey" # RHEL и SUSE: -u sshd
# ECDSA — ключ из реестра
# ECDSA-CERT — сертификат
Если вход не проходит¶
Проверяйте по порядку: сверху — самые частые причины.
«Permission denied (publickey)», а в журнале Alatyr нет ни одного обращения
к /keyholder/keys. Ваш сервер не спрашивает Alatyr. Проверьте, что файл
alatyr.conf действительно прочитан (sshd -T | grep -i authorizedkeyscommand)
и что sshd перезапущен. Если на сервере уже был другой
AuthorizedKeysCommand, смотрите
«Совмещение с FreeIPA».
Проверьте Keyholder отдельно от входа. Выполните на вашем сервере:
. /etc/ssh/alatyr.env
curl -fsS -H "Authorization: Bearer $KEYHOLDER_TOKEN" \
"$ALATYR_URL/api/v1/keyholder/keys?principal=ivan"
Успешный ответ выглядит так:
{"keys": ["ecdsa-sha2-nistp256 AAAAE2VjZHNh... alatyr-agent"]}
Пустой список {"keys": []} означает «действующих ключей для этого имени
нет». Он же приходит для несуществующего имени — так сделано намеренно, чтобы
перебором нельзя было узнать состав сотрудников.
Обращения есть, ответ пустой. Сервер Alatyr не считает ключ действующим.
Откройте раздел SSH-ключи: ключ должен быть в статусе active, а имя
учётной записи в запросе (principal) — совпадать с учётной записью на
вашем сервере.
principal — это логин сотрудника на его рабочей машине; агент присылает его
сам при регистрации ключа, и он виден в разделе SSH-ключи. Если на вашем
сервере учётная запись называется иначе, вход не пройдёт: сервер спросит
ключи для ivan, а зарегистрированы они на i.petrov.
Ответ 403. Адрес вашего сервера не попал в разрешённые сети — либо
токен включён, а в запросе его нет.
Окно агента показывает «Сервер отказал в регистрации ключа». Причина написана там же, рядом. Чаще всего дело в настройке «Требовать подтверждение identity у SSH-ключей» — смотрите примечание к шагу 1.
Ключ у сотрудника не появляется вовсе. Проверьте, назначена ли машине
цель ssh и включён ли переключатель «SSH» в колонке «Выдаём» (шаг 1).
Полоса на вкладке Политика выдачи перечисляет цели, у которых собственный
переключатель сейчас выключен.
Что дальше¶
- Отзыв доступа — как забрать ключ и когда это подействует.
- Нюансы и пределы — чего механизм не обещает.
- Реестр ключей и Keyholder API — устройство, форматы, токены.