Лабораторная работа 2. Безопасный доступ по SSH без потери управления
Сложность: средняя
Время: 60–75 минут
Целевая ОС: учебные Astra Linux Special Edition 1.7 или 1.8
Формат: две виртуальные машины
Результат работы
Вы настроите отдельный ключ SSH с парольной фразой, сверите ключ хоста по доверенному каналу, запретите парольные методы и прямой вход root, проверите эффективную, а не только записанную конфигурацию и примените её без разрыва контрольной сессии.
Схема стенда
| Роль | Имя | Учебный адрес |
|---|---|---|
| Клиент администратора | infra |
10.0.1.254 |
| SSH-сервер | server1 |
10.0.1.1 |
Во всех командах замените адреса на фактические. Учётная запись sa должна существовать на обеих ВМ, иметь домашний каталог и командную оболочку. На server1 до копирования ключа временно разрешён парольный вход sa.
Границы и меры безопасности
- Используйте только учебные ВМ без рабочих данных и создайте снимки обеих машин.
- Убедитесь, что доступна консоль
server1в гипервизоре. - Не закрывайте текущую консольную или SSH-сессию до успешного входа во втором терминале.
- Если сетевой экран включён, TCP/22 разрешают только от учебного клиента; отсутствие ответа ICMP не доказывает недоступность SSH.
- Для максимального уровня назначьте
saнеобходимые атрибуты и метки штатными средствами Astra Linux до начала работы.
Шаг 1. Предварительная проверка обеих ВМ
На обеих машинах зафиксируйте версию и текущий уровень:
cat /etc/os-release
test -r /etc/astra_version && cat /etc/astra_version
command -v astra-modeswitch >/dev/null && sudo astra-modeswitch getname
id sa
getent passwd sa
На server1 проверьте пакет сервера. Устанавливайте его только из настроенного учебного репозитория:
if ! dpkg-query -W -f='${Status}\n' openssh-server 2>/dev/null | grep -q 'install ok installed'; then
sudo apt update
sudo apt install openssh-server
fi
sudo systemctl enable --now ssh
sudo systemctl --no-pager --full status ssh
sudo ss -H -ltnp 'sport = :22'
На infra проверьте маршрут. Интерактивное SSH-подключение до сверки ключа хоста не выполняйте:
ip route get 10.0.1.1
ping -c 4 10.0.1.1 || echo "ICMP недоступен; доступность SSH проверим безопасно на следующем шаге"
Не принимайте неизвестный host key и не вводите временный пароль до независимого сравнения fingerprint.
Шаг 2. Сверить ключ хоста по доверенному каналу
На консоли server1 получите fingerprint ключа хоста:
HOST_KEY_FILE=/etc/ssh/ssh_host_ed25519_key.pub
if ! sudo test -f "$HOST_KEY_FILE"; then
sudo ls -1 /etc/ssh/ssh_host_*_key.pub
echo "Выберите существующий публичный ключ хоста и повторите шаг"
exit 1
fi
sudo ssh-keygen -lf "$HOST_KEY_FILE"
Если Ed25519-ключ отсутствует, задайте HOST_KEY_FILE как путь к существующему публичному ключу из выведенного списка. Запишите его тип, например rsa.
На infra посмотрите fingerprint, получаемый по сети:
HOST_KEY_TYPE=ed25519 # замените на фактический тип с консоли server1
ssh-keyscan -T 5 -t "$HOST_KEY_TYPE" 10.0.1.1 2>/dev/null | ssh-keygen -lf -
Сравните SHA256 fingerprint символ в символ с результатом на консоли. ssh-keyscan сам по себе не устанавливает доверие: продолжать можно только после независимого сравнения. После совпадения выполните первое интерактивное подключение, подтвердите именно проверенный ключ и введите временный пароль sa:
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=ask sa@10.0.1.1 exit
Шаг 3. Создать отдельный лабораторный ключ
На infra под sa выберите один поддерживаемый тип ключа. Предпочтительный вариант Ed25519:
LAB_KEY="$HOME/.ssh/id_ed25519_astra_lab"
if test -e "$LAB_KEY" || test -e "$LAB_KEY.pub"; then
echo "STOP: лабораторный ключ уже существует"
exit 1
fi
ssh-keygen -t ed25519 -a 64 -f "$LAB_KEY" \
-C "sa@infra astra ssh lab"
chmod 700 "$HOME/.ssh"
chmod 600 "$LAB_KEY"
chmod 644 "$LAB_KEY.pub"
umask 077
printf '%s\n' "$LAB_KEY" > "$HOME/astra-lab2-key-path.txt"
Если криптографическая политика целевой сборки запрещает Ed25519, согласованный запасной вариант:
LAB_KEY="$HOME/.ssh/id_rsa_astra_lab"
if test -e "$LAB_KEY" || test -e "$LAB_KEY.pub"; then
echo "STOP: лабораторный ключ уже существует"
exit 1
fi
ssh-keygen -t rsa -b 3072 -o -a 64 -f "$LAB_KEY" \
-C "sa@infra astra ssh lab"
chmod 700 "$HOME/.ssh"
chmod 600 "$LAB_KEY"
chmod 644 "$LAB_KEY.pub"
umask 077
printf '%s\n' "$LAB_KEY" > "$HOME/astra-lab2-key-path.txt"
Оба варианта требуют парольную фразу. Дальнейшие команды читают выбранный путь из astra-lab2-key-path.txt, поэтому fallback не оставляет скрытых Ed25519-зависимостей.
Шаг 4. Установить открытый ключ и доказать метод входа
На infra:
LAB_KEY="$(cat "$HOME/astra-lab2-key-path.txt")"
ssh-copy-id -i "$LAB_KEY.pub" sa@10.0.1.1
ssh -vv -i "$LAB_KEY" -o IdentitiesOnly=yes \
sa@10.0.1.1 true
В диагностическом выводе найдите подтверждение аутентификации методом publickey. Запрос парольной фразы локального закрытого ключа допустим; запрос пароля учётной записи на сервере — нет.
Шаг 5. Подготовить безопасное изменение сервера
На server1 создайте отдельную резервную копию:
LAB2_BACKUP="/root/astra-lab2-$(date +%Y%m%d-%H%M%S)"
sudo install -d -m 700 "$LAB2_BACKUP" || {
echo "STOP: не удалось создать резервную директорию"
exit 1
}
sudo cp -a /etc/ssh "$LAB2_BACKUP/ssh" || {
echo "STOP: не удалось скопировать /etc/ssh"
exit 1
}
sudo test -f "$LAB2_BACKUP/ssh/sshd_config" || {
echo "STOP: резервная копия sshd_config отсутствует"
exit 1
}
umask 077
printf '%s\n' "$LAB2_BACKUP" > "$HOME/astra-lab2-backup-path.txt" || exit 1
sudo grep -RnsE '^[[:space:]]*(Include|Match|PermitRootLogin|PubkeyAuthentication|PasswordAuthentication|KbdInteractiveAuthentication|ChallengeResponseAuthentication|AuthenticationMethods|AllowUsers|AllowGroups|MaxAuthTries|X11Forwarding|ClientAlive)' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d 2>/dev/null
OpenSSH обычно использует первое полученное глобальное значение. Поэтому нельзя бездумно дописывать второй набор директив в конец файла. Если главный файл рано подключает каталог sshd_config.d, создайте отдельный первый лабораторный drop-in; иначе редактируйте первые действующие глобальные значения до блока Match в основном файле:
if sudo grep -Eq '^[[:space:]]*Include[[:space:]]+/etc/ssh/sshd_config\.d/\*\.conf' \
/etc/ssh/sshd_config; then
LAB2_POLICY=/etc/ssh/sshd_config.d/00-astra-lab-hardening.conf
sudo test ! -e "$LAB2_POLICY" || {
echo "STOP: $LAB2_POLICY уже существует"
exit 1
}
else
LAB2_POLICY=/etc/ssh/sshd_config
fi
printf '%s\n' "$LAB2_POLICY" > "$HOME/astra-lab2-policy-path.txt"
sudoedit "$LAB2_POLICY"
При работе с новым drop-in поместите в него целевой профиль целиком. При работе с основным файлом изменяйте первые активные определения, не создавая поздние дубли. Если sshd -T ниже показывает другое значение, найдите более ранний Include, drop-in или глобальное определение; резервная копия всего /etc/ssh уже создана.
Целевая эффективная конфигурация учебного стенда:
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
AuthenticationMethods publickey
X11Forwarding no
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers sa
ChallengeResponseAuthentication оставлен для совместимости с обновлениями, где это историческое имя параметра ещё используется. Если SSH нужен другим администраторам, добавьте только заранее проверенные учётные записи в одну строку AllowUsers; не лишайте аварийную учётную запись доступа.
Шаг 6. Проверить синтаксис и эффективные значения
На server1:
sudo /usr/sbin/sshd -t
sudo /usr/sbin/sshd -T -C user=sa,host=infra,addr=10.0.1.254 | \
grep -E '^(permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|challengeresponseauthentication|authenticationmethods|maxauthtries|x11forwarding|clientaliveinterval|clientalivecountmax|allowusers)\b'
sudo /usr/sbin/sshd -T -C user=root,host=infra,addr=10.0.1.254 | \
grep -x 'permitrootlogin no'
Проверка не пройдена, если среди эффективных значений нет как минимум:
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
authenticationmethods publickey
x11forwarding no
maxauthtries 3
allowusers sa
Не применяйте конфигурацию, пока фактический вывод отличается от целевого. Ищите ранний дубль, Include или подходящий блок Match.
Шаг 7. Применить без потери доступа
Оставьте текущую консоль или SSH-сессию открытой. На server1:
sudo /usr/sbin/sshd -t || {
echo "Синтаксис SSH повреждён; конфигурацию не применяем"
exit 1
}
sudo systemctl reload ssh
sudo systemctl is-active ssh
sudo journalctl -u ssh -n 30 --no-pager
Во втором терминале на infra:
LAB_KEY="$(cat "$HOME/astra-lab2-key-path.txt")"
ssh -vv -i "$LAB_KEY" -o IdentitiesOnly=yes \
sa@10.0.1.1 id
Только после успешного нового подключения можно закрыть контрольную сессию.
Шаг 8. Отрицательные проверки
Убедитесь, что сервер не предлагает пароль или keyboard-interactive:
ssh -vv \
-o PubkeyAuthentication=no \
-o PreferredAuthentications=password,keyboard-interactive \
-o NumberOfPasswordPrompts=1 \
sa@10.0.1.1
Ожидается отказ; среди доступных методов сервер должен оставлять только publickey либо не предлагать совместимого метода.
Проверьте запрет прямого входа root без интерактивных запросов:
LAB_KEY="$(cat "$HOME/astra-lab2-key-path.txt")"
ssh -o BatchMode=yes -i "$LAB_KEY" \
-o IdentitiesOnly=yes root@10.0.1.1 true
Ожидается отказ, но это только дополнительная функциональная проверка: у root обычно нет лабораторного ключа sa, поэтому один такой отказ ещё не доказывает действие PermitRootLogin no. Основное доказательство — строка permitrootlogin no в эффективной конфигурации для контекста user=root. Не устанавливайте отдельный ключ root ради теста. Успешный TCP handshake сам по себе не означает успешную аутентификацию.
Аварийное восстановление
Если второе подключение не работает, не закрывайте контрольную сессию. На консоли server1:
test -r "$HOME/astra-lab2-backup-path.txt" || {
echo "STOP: файл с путём к резервной копии отсутствует"
exit 1
}
LAB2_BACKUP="$(cat "$HOME/astra-lab2-backup-path.txt")"
[[ "$LAB2_BACKUP" =~ ^/root/astra-lab2-[0-9]{8}-[0-9]{6}$ ]] || {
echo "STOP: недопустимый путь резервной копии"
exit 1
}
sudo test -d "$LAB2_BACKUP/ssh" &&
sudo test -f "$LAB2_BACKUP/ssh/sshd_config" || {
echo "STOP: резервная копия /etc/ssh неполна; откат не начинаем"
exit 1
}
if sudo test -f /etc/ssh/sshd_config.d/00-astra-lab-hardening.conf; then
sudo install -d -m 700 "$LAB2_BACKUP/created-artifacts" || exit 1
sudo mv /etc/ssh/sshd_config.d/00-astra-lab-hardening.conf \
"$LAB2_BACKUP/created-artifacts/" || exit 1
fi
sudo cp -a "$LAB2_BACKUP/ssh/sshd_config" /etc/ssh/sshd_config || exit 1
if sudo test -d "$LAB2_BACKUP/ssh/sshd_config.d"; then
sudo install -d -m 755 /etc/ssh/sshd_config.d || exit 1
sudo cp -a "$LAB2_BACKUP/ssh/sshd_config.d/." /etc/ssh/sshd_config.d/ || exit 1
fi
sudo /usr/sbin/sshd -t || {
echo "Откат не прошёл проверку; службу не перезагружаем"
exit 1
}
sudo systemctl reload ssh
sudo systemctl is-active ssh
Для полного возврата удалите из ~sa/.ssh/authorized_keys только строку с комментарием sa@infra astra ssh lab, удалите только отдельный лабораторный ключ на infra и восстановите снимки обеих ВМ. Не удаляйте весь authorized_keys и не отключайте модули КСЗ.
Что сдать
- Версии, текущие уровни и адреса обеих ВМ.
- Сверенные SHA256 fingerprints ключа хоста.
- Фрагмент
ssh -vv, подтверждающий методpublickey. - Полный отфильтрованный вывод
sshd -T -C. - Результаты двух отрицательных проверок.
- Путь к резервной копии и описание успешного входа во втором терминале.
Контрольные вопросы
- Почему
ssh-keyscanнельзя считать доверенным источником без сравнения fingerprint? - Чем парольная фраза закрытого ключа отличается от пароля удалённой учётной записи?
- Почему
sshd -tнедостаточно и нужна командаsshd -T? - Как
AuthenticationMethods publickeyстрахует ошибку в настройке других методов? - Почему конфигурацию применяют через
reloadи проверяют во второй сессии?
Критерии зачёта
Работа зачтена, если ключ хоста сверён по доверенному каналу, вход sa доказан методом publickey, эффективные значения соответствуют профилю, парольные методы и прямой вход root отвергаются, а откат выполняется через доступную консоль без удаления чужих ключей.