👤 Управление локальными пользователями (демон)
📌 Описание
UserService даёт управление локальными Linux-аккаунтами ноды: список всех аккаунтов (включая root), создание и удаление, блокировка/разблокировка, смена логин-шелла, управление дополнительными группами (sudo, docker, ...) и разворачивание SSH-публичного ключа в ~/.ssh/authorized_keys аккаунта. Это API за вкладкой «Users» на странице ноды платформы — отдельная фича на всю машину, без области видимости по приложению, в отличие от необязательного app_id у файлового менеджера.
Эта фича работает только по SSH-ключам по замыслу: демон никогда не работает с Linux-паролем. Свежесозданный аккаунт стартует без рабочего пароля (умолчание самого useradd) — вход становится возможен только после разворачивания ключа.
🎯 Сценарии использования
- 🖥️ Вкладка «Users» в UI платформы листает аккаунты ноды и позволяет оператору создать, заблокировать или удалить аккаунт.
- 🔑 Организация раздаёт участнику команды публичный ключ на общий аккаунт; повторная отправка того же ключа ничего не меняет, а не дублирует строку.
- 🔧 Скрипт или CLI-пользователь вызывает тот же REST напрямую с токеном, как и остальной API демона.
🏗️ Техническое решение
- Область видимости: все аккаунты машины, включая root — без сужения в стиле
app_id, поскольку это администрирование всей машины. - Доступ: каждый метод требует root-контекст — то же правило, что и у
FileService. - Листинг:
/etc/passwd,/etc/shadowи/etc/groupразбираются напрямую, независимо от собственного разбора файлового менеджера;lockedберётся из хэша в shadow с префиксом!,groupsсодержит только дополнительные членства. - Создание/удаление: реальную работу делают
useradd/userdel(корректный/etc/shadow, скелетон-файлы, NSS); удаление жёстко отказывает на uid 0 и любом uid ниже 1000, без обхода. - Блокировка:
usermod -L/-U— приUsePAM yesэто реально блокирует вход по ключу для заблокированного аккаунта на большинстве дистрибутивов, а не косметический флаг. - Шелл: обязан быть абсолютным путём, уже перечисленным в
/etc/shells. - Группы:
SetUserGroupsвсегда заменяет весь набор дополнительных групп целиком, никогда не частичное добавление/удаление. - Authorized keys: идемпотентное добавление (повторный фингерпринт возвращает существующую запись), удаление по фингерпринту, строки-опции (
command="...",...) остаются нетронутыми, а не разбираются.
🔗 Связанные задачи
DMN-100 в ROADMAP.md добавляет UserService; флаг возможностей users включает вкладку «Users» на платформе.