24 KiB
Руководство администратора
Практическое руководство по экранам ssh-access-tui и типовым сценариям.
Архитектурные решения и модель угроз — в ARCHITECTURE.md.
Запуск
sudo ssh-access-tui
Требует root (создаёт/блокирует системных пользователей, правит
authorized_keys). Инструмент рассчитан на одного администратора
одновременно на хосте — если кто-то ещё уже открыл TUI, вторая сессия
получит ошибку про занятую блокировку состояния (state.lock), а не молча
перезапишет чужие изменения.
Навигация везде: стрелки/j/k — перемещение по списку, enter —
выбрать/подтвердить, esc — назад, ctrl+c — жёсткий выход в любой момент
(без каких-либо предупреждений — только для аварийных случаев). q как
быстрый выход работает только в главном меню (на остальных экранах он
ничего не делает — «esc» уводит назад). Обычный выход (пункт «Выход» или
q в главном меню) предупредит, если есть:
- пользователи, для которых ни разу не сгенерирован ключ (не были в «Экспорт архивов»);
- пользователи, у которых изменился доступ, но конфиг у них старый
(кто-то поменял группы/каталог после их последнего экспорта или
обновления конфига) — им нужно прислать новый
configчерез «Обновить конфиги», иначе их локальный конфиг не соответствует их реальным правам.
В обоих случаях можно выйти всё равно (enter/y) или вернуться
(esc/n). Главное меню всегда показывает актуальное количество таких
пользователей под списком пунктов, если оно не нулевое — не нужно ждать
выхода, чтобы это заметить.
Любое деструктивное действие (блокировка/удаление пользователя,
удаление хоста/сервиса/группы, перевыпуск уже выданного ключа) требует не
enter/y, а набрать вручную короткую случайную строку, которую
инструмент показывает на экране подтверждения (например kqzvm-482) — она
каждый раз новая. Неверный ввод просто откатывает к полю ввода с пояснением
«не совпадает», ничего не меняя; esc отменяет действие полностью в любой
момент. Это защита именно от «промахнулся мимо enter» — набрать чужую
случайную строку по ошибке невозможно.
Главное меню
Пользователи — создать / заблокировать / разблокировать / удалить
Хосты и сервисы — общий каталог адресов и портов (один раз на всех)
Группы — какие сервисы из каталога входят в каждую группу
Экспорт архивов — сгенерировать ключи и .7z для доставки
Обновить конфиги — перевыпустить config (без ключа) тем, у кого изменился доступ
Аудит / кто в сети — активные сессии и журнал подключений
Выход
Имена хостов, сервисов и групп должны быть без пробелов (латиница, цифры,
. _ -) — они попадают в конфиг и в authorized_keys; инструмент откажет с
понятной ошибкой, если ввести имя с пробелом.
Модель: каталог → группы → пользователи
Хосты и их сервисы (порты) описываются один раз в общем каталоге
(«Хосты и сервисы»), а не заново для каждой группы. Доступ раздаётся по
конкретным сервисам, не по хосту целиком: группа выбирает нужные сервисы
из дерева «хост → его сервисы» — можно взять только ssh этого хоста, не
трогая его же web-admin. Если у вас в разных группах фигурируют одни и те
же хосты/сервисы — их не нужно набивать повторно, только отметить нужные
для очередной группы. Пользователь состоит в одной или нескольких группах;
его реальный доступ — объединение сервисов, выбранных во всех его группах.
Сценарий 1: новый сотрудник, у которого уже есть роль/группа доступа
Обычно каталог и группы настраивают заранее (или один раз добавляют то, чего не хватает), потом заводят пользователей пачками.
- Хосты и сервисы →
n→ имя хоста (напримерdb-prod-1), адрес (как виден с jump-хоста), описание (необязательно) →enter. Сразу открывается список сервисов этого хоста (изначально пуст). n→ имя сервиса (напримерsshилиweb-api), порт на хосте (например22или7888), описание (необязательно) →enter. Повторитеnдля каждого сервиса на этом хосте.esc— назад к списку хостов; повторите шаги 1-2 для остальных хостов, затемesc— в главное меню. Если хост/сервис уже существует и нужно только поправить адрес/порт/описание —eвместоnна нужной записи (можно поменять и имя — все группы, которые ссылались на старое имя, автоматически обновятся).- Группы →
n→ имя группы (напримерteam-billing), описание (необязательно) →enter. - Выбрать группу →
enter— откроется дерево «хост → его сервисы».spaceна строке сервиса отмечает именно его;spaceна строке хоста (заголовок) отмечает/снимает сразу все его сервисы — удобно, когда нужен весь хост, но при желании можно оставить только часть его сервисов.[x]— выбрано всё,[~]— выбрано частично,[ ]— ничего.enterсохранить. - Пользователи →
n→ имя пользователя (латиницей, будущий Linux-логин) и комментарий (например ФИО) →enter. - Отметить
spaceнужные группы (можно несколько). Ниже списка групп на этом же экране — чекбокс «ProxyJump вместо LocalForward»: по умолчанию выключен (клиентский конфиг — одинHost jumpсLocalForwardна каждый сервис, всегда открытое соединение); включите его, если вместо этого нужен конфиг с отдельнымHost <alias>на каждый сервис (ProxyJump jump, обычная командаssh <alias>без постоянно открытого туннеля и без локальных портов) — например, для пользователей с привычными SSH-клиентами не-Windows или когда локальные порты неудобны. Права доступа на сервере не зависят от этого выбора — это только формат выдаваемого файлаconfig. →enter.
Это уже создаёт системный Linux-аккаунт (без пароля, без интерактивного шелла) и запись в состоянии. Ключ ещё не выдан — статус в списке пользователей покажет «ключ не выдан».
- Экспорт архивов → отметить
spaceтолько что созданного пользователя (илиa— отметить всех, удобно при пакетном найме) →enter. Для пользователей без ключа архив генерируется сразу, без лишних вопросов — это не деструктивное действие. Инструмент сгенерирует ключ, пропишетpermitopen=под текущие сервисы группы и соберёт.7z, показав один общий пароль на всю партию — он показывается один раз, запишите/скопируйте сразу. - Передайте каждому пользователю его архив (файл, путь показан на экране,
лежит в
export_dir) любым каналом, а пароль от архива — отдельным каналом (голосом, в личку) и по возможности не всем одним и тем же сообщением в общем чате. - Пользователь распаковывает архив на Windows по инструкции
INSTRUCTIONS.txtвнутри архива — она на простом русском языке, без технических терминов: положить файлы в папку, ввести одну команду и держать окно открытым, дальше список «такой адрес у вас локально → что это → где реально находится», составленный под конкретные сервисы этого пользователя.
Сценарий 1а: изменить группы уже существующего пользователя
Пользователи → выбрать пользователя → g → отметить/снять space
нужные группы → enter. Если у пользователя уже выдан ключ, инструмент
сразу пересоберёт его permitopen= под новый набор сервисов — доступ
меняется немедленно, без переотправки архива и без замены ключа
(изменение групп никогда не ротирует ключ).
На этом же экране есть чекбокс «ProxyJump вместо LocalForward» (см. сценарий 1, шаг 7) — можно переключить режим клиентского конфига и существующему пользователю. В отличие от смены групп, переключение этого чекбокса не применяется автоматически: инструмент не отслеживает смену стиля конфига как «устаревший» (только смену состава сервисов), поэтому после переключения нужно вручную прогнать «Обновить конфиги» (см. ниже), иначе у пользователя на диске просто останется конфиг в старом формате — доступ на сервере это никак не ограничивает.
Если хотите, чтобы у пользователя появился ещё и обновлённый клиентский
config с новыми адресами для новых сервисов (иначе он про них просто не
узнает, хотя доступ уже есть) — или чтобы применить только что
переключённый режим ProxyJump/LocalForward — Пользователи → выбрать
пользователя → c («обновить конфиг»), либо (то же самое, но сразу для
многих) Обновить конфиги в главном меню. Это генерирует архив только с
config + INSTRUCTIONS.txt (без ключа — ключ у пользователя уже есть и
остаётся тем же), пользователю нужно только подменить файл config. Не
требует подтверждения — ключ и доступ этим действием не меняются, это не
деструктивно.
Обновить конфиги в главном меню — то же самое, что c, но пакетно:
список покажет каждого уже выпущенного пользователя с пометкой «конфиг
актуален» или «конфиг устарел — доступ изменился» (см. ниже, как это
отслеживается), можно отметить space только устаревших или a — всех, и
получить один пароль на всю партию, как при обычном экспорте.
Инструмент сам запоминает, для какого набора сервисов последний раз
выдавался config каждому пользователю (полным экспортом или через
«обновить конфиг»), и сравнивает с тем, что должно быть сейчас — отсюда и
берётся статус «устарел». Полный экспорт (сценарий 1, шаги 8-9) тоже
обновляет этот статус (и заодно перевыпускает ключ, с подтверждением
строкой) — используйте c/«Обновить конфиги», когда переиздание ключа не
нужно.
Сценарий 2: добавили новый сервис/хост, поменялся адрес или порт
- Новый сервис на существующем хосте: Хосты и сервисы → выбрать хост →
enter→n. - Новый хост: Хосты и сервисы →
n, затем добавить ему сервисы. - Хост сменил адрес, сервис — порт, нужно поправить описание, или
переименовать:
eна нужной записи. Переименование хоста или сервиса автоматически обновляет ссылки на него во всех группах, которые его используют — группы не «отваливаются» молча и не теряют доступ из-за простого переименования.
Любое из этих изменений сразу обновляет permitopen= в authorized_keys
всех активных пользователей всех групп, ссылающихся на этот сервис, —
доступ появляется немедленно, без каких-либо действий на стороне
пользователя. Их клиентский конфиг (~/.ssh/config) при этом не
обновляется автоматически — их локальный файл начинает отставать от
реального доступа (инструмент это заметит и покажет как «конфиг устарел»,
см. выше); чтобы прислать актуальный конфиг — Обновить конфиги или c
(см. сценарий 1а).
Группы → выбрать группу → enter — то же дерево «хост → сервисы», там
же можно снять/добавить сервисы группе (не создавая и не удаляя сами
хосты/сервисы в каталоге).
Удаление хоста из каталога, сервиса на хосте или целой группы (d в
соответствующем списке) — все три действия деструктивны (мгновенно
отбирают доступ у всех затронутых пользователей) и требуют набрать
случайную строку подтверждения: экран покажет, что именно удаляется,
сколько пользователей это коснётся, и в каких группах используется
(для хоста/сервиса). Удаление хоста снимает с групп все его сервисы разом;
удаление одного сервиса снимает только его, остальные сервисы того же
хоста в группах остаются.
Сценарий 3: сотрудник уволился
- Пользователи → выбрать пользователя →
l(заблокировать) → набрать строку подтверждения, которую покажет экран →enter.
Блокировка — это одновременно: блокирует пароль аккаунта, устанавливает
немедленный срок истечения аккаунта (chage -E 1) и комментирует его ключ в
authorized_keys — три независимых механизма, чтобы блокировка не зависела
от одного из них. Статус в списке сменится на locked. Это обратимо.
Если сотрудник вернулся — u (разблокировать) на том же пользователе:
снимает блокировку аккаунта и восстанавливает его ключ в authorized_keys
с текущими правами групп. Разблокировка не деструктивна — подтверждения не
требует, срабатывает сразу.
Полное удаление аккаунта (d) — необратимо (userdel -r, домашняя папка
стирается) и тоже требует подтверждения строкой (экран явно предупредит,
что это необратимо и что для временного отключения лучше использовать
блокировку). Используйте удаление только для окончательного оффбординга, не
для временной блокировки.
Сценарий 4: проверить, кто сейчас подключён / посмотреть историю
Аудит / кто в сети показывает:
- «Сейчас в сети» — список активных SSH-сессий (по процессам
sshd: user [priv], а не поwho, потому что форвардинг-сессии без интерактивного терминала не создают обычных login-записей); - «Последние события» — журнал подключений/отключений, который в фоне
собирает
ssh-access-tui-audit.serviceизjournalctl, независимо от ротации системного журнала.
r — обновить оба списка. Если журнал подключений пуст, хотя пользователи
явно заходили — проверьте, что фоновый сервис запущен:
systemctl status ssh-access-tui-audit.service.
Сценарий 5: перенос на новый хост / хост умер
См. подробности в ARCHITECTURE.md.
Коротко: состояние (каталог хостов/сервисов, группы, пользователи,
публичные ключи, статусы) — git-репозиторий, бэкапится часовым таймером в
удалённый git. На новом хосте: поднять ssh-access-tui, влить state.yaml
из бэкапа, создать системные Linux-аккаунты для активных пользователей,
выпустить им новые ключи через Экспорт архивов (старые приватные ключи
специально нигде не хранятся — это не баг, см. архитектурный документ).
Что не делает эта версия (нужно руками)
- Не удаляет
.7zизexport_dirпосле доставки — сделайте это сами, когда получатель подтвердил, что распаковал архив (это касается и архивов от «обновить конфиг», хоть они и не содержат ключ). - Не обновляет клиентский
~/.ssh/configпользователя автоматически при появлении нового сервиса/хоста в его группе — это ручной шаг («Обновить конфиги», сценарий 1а), хоть инструмент и отслеживает, кому именно он нужен (главное меню и предупреждение при выходе). Права доступа на сервере при этом обновляются немедленно и без участия администратора (см. сценарий 2). - Не поддерживает одновременную работу нескольких администраторов — рассчитан на одного за раз (см. «Конкурентность» в ARCHITECTURE.md).