Seni: менеджер входа
Красивый вход на Wayland без GNOME и без «голой» сессии под гретером. Демон на Rust отвечает за безопасность, интерфейс на Vala выглядит как остальная система.
Зачем нужен Seni
Менеджер входа это первое, что видит пользователь, и одна из самых чувствительных частей системы: он работает с паролями и от имени root запускает сеанс. Для Atomic Niri нужен был вход, который:
- красиво выглядит и работает на Wayland;
- не требует GNOME: GDM слишком тесно связан с GNOME Shell;
- не запускает ради картинки входа отдельную «голую» сессию niri, как это делает связка greetd и regreet;
- подключён к PAM, а не изобретает свою проверку паролей;
- не тревожит gnome-keyring в сессии гретера и нативно работает с niri.
Готового гретера, который подошёл бы по всем этим критериям, в природе не нашлось. Поэтому появился Seni: архитектура GDM, перенесённая на наш стек.
Почему Seni. «Сени» в русской избе это помещение у входа, через которое входят в дом. Для менеджера входа название подходит идеально: Seni это вход в систему.
Стек
Демон на Rust
Работает от root, написан на Rust (tokio и zbus). Там, где ошибка в коде значит повышение привилегий, нужна безопасность памяти.
Гретер на Vala
Интерфейс на Vala, GTK4 и libadwaita, нативный для GTK. Выглядит так же, как остальная система и панель Niti.
cage
Гретер запускается внутри cage: минимальный композитор Wayland для одного окна. Никакой лишней сессии рабочего стола.
PAM и D-Bus
Проверка пароля идёт через штатный PAM. Демон и гретер говорят по D-Bus, контракт описан в одном файле для обеих сторон.
Исходный код: Seni, лицензия GPL-2.0 или новее. Перенесённые из GDM приёмы сохраняют указание авторства в шапках файлов.
Как проходит вход
- Загрузкаsystemd запускает
seni.service, демон следит за рабочими местами через logind и ждёт графическое место (seat). - ГретерНа каждом графическом месте демон запускает
cage seni-greeterот отдельного пользователя_greeter. Упавший гретер запускается заново. - Проверка пароляГретер передаёт пароль демону по D-Bus, а демон проверяет его через PAM. Пароль не попадает в аргументы процессов.
- СессияПосле успеха демон открывает сессию PAM, сбрасывает привилегии до выбранного пользователя и запускает niri.
Безопасность
Принцип проекта: безопасность через PAM важнее всего остального. Любая новая поверхность проверки пароля обязана идти через PAM, а не в обход и не самодельно.
- Rust в привилегированной части. Демон работает от root, и ошибки памяти там были бы опасны. Rust устраняет их целыми классами.
- Только штатный PAM. Демон сам не хранит и не сравнивает пароли. Проверку выполняет стек PAM системы (в ALT это
pam_tcb), а привязка к PAM написана вручную на несколько десятков строк без тяжёлых зависимостей. - Пароль не светится. Пароль передаётся через каналы, а не через аргументы командной строки, где его видно в
/proc. Строка с паролем затирается в памяти при освобождении. - Гретер без прав. Интерфейс входа работает от пользователя
_greeter, а не от root. Привилегированную часть выполняет только демон. - Один вход, один PAM-дескриптор. Проверка пароля и открытие сессии идут одним вызовом PAM, а не в долгоживущем демоне и не во втором дескрипторе.
- Защита от перебора. В образе включён
pam_faillock: после 10 неудачных попыток за 15 минут учётная запись блокируется на 5 минут. Это относится ко входу, разблокировке экрана, sudo и su. Root не блокируется. - Проверки в CI. Тесты на Rust, сквозная проверка D-Bus от запроса до завершения проверки пароля и статический поиск опасных шаблонов в коде на Vala.
Защита от перебора и счётчик попыток относятся ко всему образу, а не только к Seni: это системная политика PAM. Описание в документации образа: «Ограничение попыток пароля».
Что умеет
Быстрый вход
Для последнего вошедшего пользователя сразу показывается поле пароля, «Другой пользователь» это маленькая ссылка. Запоминаются и тема, и последний пользователь.
Выбор сессии
Шестерёнка в углу открывает выбор сессии. Сейчас одна, niri, но место уже готово под другие, например игровую.
Питание
Выключить и перезагрузить прямо с экрана входа.
Тот же вид, что у Niti
Часы и значки состояния в стиле панели Niti, обои с размытием и цвета, подхваченные из палитры рабочего стола.
Несколько мониторов и мест
Гретер показывается на всех мониторах. Для нескольких рабочих мест (multi-seat) запускается отдельный гретер на каждое.
Автовход
Для киоска или Live ISO можно включить автоматический вход: строка имя boot в /etc/seni/autologin входит один раз за загрузку. Root не подходит никогда.
Экран блокировки
К Seni относится и экран блокировки seni-lockscreen. Он использует протокол ext-session-lock-v1 и работает внутри уже запущенной сессии niri, как swaylock или hyprlock. Закрывает все мониторы и запрашивает пароль.
- Пароль проверяет вспомогательная программа
seni-unlock-helperчерез отдельный PAM-сервисseni-unlock. Новая сессия при этом не открывается. - Помощник проверяет только вашу собственную учётную запись и запускается с правами группы
chkpwd(так в ALT принято для блокировщиков), а не от root. - Сам ничего не запускает: подключается снаружи, по сочетанию клавиш (например
Super+L) или через swayidle перед сном и по таймеру бездействия.
Настройка
| Файл | Что в нём |
|---|---|
/etc/seni/greeter.json | Обои, размытие и его сила, цветовая схема |
/etc/seni/autologin | Учётные записи с автовходом. Строка имя boot входит при загрузке |
/etc/seni/colors.css | Цвета гретера. Создаётся автоматически из палитры рабочего стола при старте демона |
Настройки гретера планируется вынести в отдельную страницу Tuner.
Чего пока нет
- Вход пользователей из доменов (SSSD, IPA): демон читает список локальных пользователей, ручного ввода имени нет. Поддержка в планах.
- Настройки гретера пока только в файле, без графического интерфейса.
Для разработчиков
Seni собирается в контейнере: Rust-демон через cargo, гретер и экран блокировки через meson. Гретер можно проверить без реального железа: cage умеет работать без экрана (WLR_BACKENDS=headless), а скриншот снимает grim.

