SSSD или приключения Linux в домене Windows (MS AD)
Для лиги лени: не все так просто и легко
Примечание: пост отличается особо мразотным и нечитаемым оформлением. Даже на уровне меня.
Часть 1. Немного теории или как работает Microsoft Windows Active Directory Domain Services (MS AD DS)
Часть 2. К практике. Подготовка
Часть 3. К практике. Начинаем медленно вводить. В домен
Часть 4. Но зачем это все, или возврат к теории
Часть 5. Лось Пользователь, просто пользователь
Часть 1. Немного теории или как работает Microsoft Windows Active Directory Domain Services (MS AD DS) и почему так.
Если пропустить все подпункты про открытые закрытые сертификаты, структуру хранения и репликации базы данных, роли, схемы, доверие, расширение схемы, атрибуты и так далее, вплоть до LDS, Extensible Storage Engine (ESE) и Joint Engine Technology (JET), то, для целей статьи, можно сократить описание до следующего:
В базе данных AD хранятся учетные записи и необратимо (или обратимо) зашифрованные пароли от учетных записей:
1. Пользователей
2. Компьютеров – членов домена. Мозгом домена являются контроллеры домена, Мегамозгом – носители ролей, Гипермегамозгом – носитель роли PDC.
И там же, в базе, хранятся все остальные сущности.
При добавлении компьютера в домен на нем магией Kerberos (или NTLM) для учетной записи SYSTEMOFTHISCOMPUTERNAME создается логин, пароль и дальше уже по учебнику.
Централизованная архитектура, вот это все.
Растет это все из принципа «все централизовано, все под контролем».
В противоположность этому, Linux вырастал из концепции «тут есть только я», то есть никакой централизации «из коробки», и есть только один root. Как следствие, в Linux из коробки управление пользователями и правами весьма отличается от Windows. Впрочем, для большей части задач этого достаточно, особенно если права пользователя в исполняемом приложении не те же самые, что права пользователя Linux.
Однако в некоторых сценариях возникает необходимость централизованного управления не только права внутри приложений, но и правами в самой ОС, и тут на помощь приходят SSSD, Winbind, realmd.
Раньше был Identity management for Unix/NIS, но он закончился.ся.
За деньги были PowerBroker Identity Services, Centrify Server Suite, Quest Authentication Services.
В теории это можно сделать разными методами, хоть через управление сертификатами через Ansible или что угодно «прочее», хоть паролями по любой схеме.
На практике в организациях обычно есть ряд требований по сложности пароля, по не-хранению паролей в открытом виде, по регулярной смене пароля, по централизованной блокировке, итд.
Ansible в чистом виде эту задачу не решает, FreeIPA не то чтоб популярна, хотя можно и ее использовать, если вы любите боль (и унижение), да и смысла в замена MS AD нет, если только не совсем угнетаться. Потому что Windows Standard стоит около 1100 $ на 16 ядер, и около 6200$ на Datacenter, что для организации не так дорого. Если у вас работники не за еду работают, конечно.
То есть проще купить, да и глобально Microsoft не так пристально следит за лицензированием, как Broadcom. Можно сказать, что вообще не следит, учитывая работу доменного центра лицензирования, когда ты, фактически, даешь Microsoft честное слово, что у тебя не будет намного больше того количества, что ты лицензировал. Software Assurance это просто удобно. Но, конечно, никто не мешает делать «только Linux», хотя так чаще говорят те, кто цены на RHEL \ Oracle Linux не видел.
Часть 2. К практике. Подготовка
Я развернул домен Windows Server 2025, это делается так же просто и легко, методом далее далее готово. Мне бы снапшот сделать, перед установкой, ну да переживу. На 2 ядрах и 6 Гб оперативки Windows 2025 + AD как-то живет, но немного грустит.
Развернул рядом новый Debian 12 с длинным именем Linux-with-long-name-199 и .. и сразу уперся в мелкие проблемы, которые на Windows давно решены из коробки, в том числе:
Для работы нужен ntp, но инсталлятор Debian предлагает при установке установить Gnome, KDE, ssh, web – но не предлагает выбрать ntp клиент. Из коробки стоит systemd-timesyncd, что видно по
timedatectl status, но sssd не предлагает сконфигурировать службу времени для работы с контроллером домена, надо конфигурировать вручную. Или опять Ansible (предпочтительнее, но это не предмет данной статьи)
Но пока вручную, отредактируем
nano /etc/apt/sources.list
и
nano /etc/network/interfaces
Эмуляция легаси в Linux
Создам юзера AlexanderPushkin, приделаю к нему сертификат, зайду в него, чтобы профиль точно был, и положу в профиль текстовый файл.
/usr/sbin/useradd -m AlexanderPushkin
Обожаю дебиан, что там пути по умолчанию в версии 12 так и не поправили.
passwd AlexanderPushkin
chown -R AlexanderPushkin:AlexanderPushkin AlexanderPushkin/.ssh/
прописываем ключи, не забывая (я постоянно забываю, еще один повод это делать в Ansible)
НЕ в формате ---- BEGIN SSH2 PUBLIC KEY ----
а в формате ssh-rsa (ключ)
Как же раздражает после перерыва то, что по умолчанию -
echo $SHELL == /bin/sh
вместо /bin/bash
и что надо делать
chsh -s /bin/bash
А то не будет ничего из .bashrc, ни echo $HISTSIZE, ни echo $HISTFILESIZE, ни echo $HISTFILE
Бесит, что надо как-то так.
/usr/sbin/useradd -m -s /bin/bash AlexanderPushkinTheSecond
passwd AlexanderPushkinTheSecond
mkdir /home/AlexanderPushkinTheSecond/.ssh
touch /home/AlexanderPushkinTheSecond/.ssh/authorized_keys
chown -R AlexanderPushkinTheSecond:AlexanderPushkinTheSecond /home/AlexanderPushkinTheSecond/.ssh
Или что-то такое, поправьте меня, если вдруг чего спутал.
Часть 3. К практике. Начинаем медленно вводить. В домен.
У нас есть два пользователя, AlexanderPushkin и AlexanderPushkinTheSecond
Можем ли мы создать пользователей с такими именами в AD?
AlexanderPushkin. Длина имени 16 символов, создается без вопросов.
AlexanderPushkinTheSecond. Длина имени 25 символов, и это длиннее SAM-Account-Name, у которого длина 20 символов.
Из AlexanderPushkinTheSecond получился SAM-Account-Name AlexanderPushkinTheS
Сомнительно ,но окей.
Начинаем подготовку к вводу в домен самого Linux сервера.
В всяких инструкциях прописана тонна всяких пакетов, но никакой расшифровки к ним. Список включает, но не ограничивается:realmd sssd sssd-tools libnss-sss libpam-sss adcli
или
realmd sssd-tools samba-common-bin samba-libs krb5-user adcli
или
realmd sssd-tools sssd libnss-sss libpam-sss adcli packagekit
или
realmd sssd sssd-tools libnss-sss libpam-sss packagekit oddjob oddjob-mkhomedir krb5-user adcli
Такое впечатление, что авторы инструкций списывают руководство друг у друга, вообще не вдаваясь в детали, зачем нужен, и нужен ли, тот или иной пакет.
Описания пакетов сделаны в том же самом виде, что и в классике, например, цитата:
PackageKit allows performing simple software management tasks over a DBus interface e.g. refreshing the cache, updating, installing and removing software packages or searching for multimedia codecs and file handlers.
Напомнило
«СЕПУЛЬКИ — важный элемент цивилизации ардритов (см.) с планеты Энтеропия (см.). См. СЕПУЛЬКАРИИ».
«СЕПУЛЬКАРИИ — устройства для сепуления (см.)».
Я пойду другим путем, вообще ничего ставить не буду!
Найти детальное описание «что нужно сейчас и почему», это подвиг сложнее, чем накормить кота таблеткой.
realmd как интерфейс к sssd понятен. sssd-tools – уже не так понятен. krb5-user понятно, но его перечисляют не везде.
Подготовительные работы
В первую очередь необходимо вручную заменить thishostname на hostname.mydomain.domain
или, в моем случае,
hostname Linux-with-long-name-199.win2025.mydomain
Затем поправить /etc/hosts , и наконец сделать
apt install realmd
И проверить что вышло
Делаю realm discover и получаю bash: realm: command not found
КАК ЭТО ВОТ ТАК ? Проклятый Debian, почему там пути то не прописали.
/usr/sbin/realm discover работает, с сообщением realm: No default realm discovered
realm discover win2025.mydomain –verbose выдает realm: No such realm found
Почему?
потому что я не настраивал DNS, а в /etc/resolv.conf прописался DHCP сервер еще с момента установки.
dig @192.168.122.250 win2025.mydomain – работает, но в целом работа службы DNS в Linux, или в Debian, в случае если первый сервер сказал «ну я даже и не знаю», без попытки спросить второй сервер в списке тоже с непривычки может вызывать ряд проблем.
Если все настроить правильно, то команда
/usr/sbin/realm discover win2025.mydomain
Должна вернуть список пакетов:
win2025.mydomain
type: Kerberos
realm-name: WIN2025.MYDOMAIN
domain-name: win2025.mydomain
configured: no
server-software: active-directory
client-software: sssd
required-package: sssd-tools
required-package: sssd
required-package: libnss-sss
required-package: libpam-sss
required-package: adcli
required-package: samba-common-bin
Значит,
apt install realmd sssd sssd-tools libnss-sss libpam-sss adcli samba-common-bin
Пакета krb5-user в списке нет, и это странновато.
Отредактируем /etc/realmd.conf
nano /etc/realmd.conf
И внесем туда
[active-directory]
os-name = Debian GNU/Linux/PikabuTest
os-version = 12.0 (Bookworm)/or Windows
computer-ou = ou=LinuxServer,DC= win2025,DC=example
Данный конфиг содержит ошибку, и знающий Linux читатель, конечно, ее сразу увидит.
Пробуем.
/usr/sbin/realm --verbose join win2025.mydomain -U Administrator
И пааалучаем воооот такую на воротник!
realm: Couldn't join realm: Necessary packages are not installed: sssd-tools sssd libnss-sss libpam-sss adcli
Эта же ошибка была в Ubuntu 16, сколько лет прошло.
Делаем
/usr/sbin/realm --verbose join win2025.mydomain -U Administrator --install=/
запускаем, получаем на воротник еще раз:
Failed to join the domain
realm: Couldn't join realm: Failed to join the domain
При этом, не смотря на прописанный в /etc/realmd.conf параметр для OU, учетная запись все равно создалась в OU по умолчанию, COMPUTERS в моем случае, да еще и с именем LINUX-WITH-LONG
15 символов для PC name, это лимиты Netbios, и не болейте.
DNS имя при этом правильное, linux-with-long-name-109.win2025. mydomain
И остальные параметры взяты из файла правильно. Только OU не тот.
При этом, если бы я, как нормальный человек, сделал отдельную учетную запись для ввода в домен с правом создания компьютеров только в этом OU, то получил бы и ошибку, и крики «да у нас все настроено правильно», со стороны «средней» Linux команды.
К счастью, на текущем месте работу у нас вменяемая и команда CI\CD, и команда Linux, и команда windows.
Точнее, это одна команда со специализациями внутри команды.
Давайте разбираться.
В примере выше я написал:
computer-ou = ou=LinuxServer,DC= win2025,DC=example
Это, конечно, неправильно -
computer-ou = ou=LinuxServer,DC= win2025,DC= mydomain
В конфиге я это исправил (а в тексте – нет), но зато в конфиге я сделал другую ошибку. В читаемом тексте это так сразу и не видно, но там
computer-ou = ou=LinuxServer,DC=(пробел)win2025,DC= mydomain
Окей,
realm leave ad.example.com -U 'AD.EXAMPLE.COM\user' то есть
realm leave win2025. mydomain -U ' win2025. mydomain\Administrator'
Напоминаю, что учетную запись администратора домена для таких задач в рабочей среде использовать нельзя, необходимо создать отдельную учетную запись и делегировать ей права на создание и удаление записей в выделенной OU. Исключения: МТС и Аэрофлот, там все равно делают что угодно, кроме безопасности.
Но с точки зрения Linux – она не в домене, хотя УЗ сервера и создалась. Поэтому просто удалю созданную УЗ в домене, поправлю /etc/realmd.conf, создам УЗ в с правом создания УЗ типа компьютер в этой OU (как надо было с самого начала) и попробую еще раз.
делегирование сложности не составляет, даже ссылку не буду приводить, сделал один раз из GUI, с результатом:
They have the following permissions: Full Control
For the following object types: Computer
Пометка. Я всего один раз видел как ЭТО переведено, и навсегда отказался иметь дело с русифицированным Windows.
Снова делаю
/usr/sbin/realm --verbose join
Иииии вижу
Found well known computer container at: CN=Computers, DC=win2025,DC= mydomain
и, очевидно, получаю опять на воротник!
Insufficient permissions to join the domain
realm: Couldn't join realm: Insufficient permissions to join the domain
Параметр OU (Organizational Unit или specified subtree в терминах RH) можно указать и в командной строке:
--computer-ou="ou=Linux Computers,dc=domain,dc=com", и я так и попробую, но хотелось бы разобраться, что не так.
/usr/sbin/realm --verbose join win2025.mydomain -U LinuxAdmin --install=/ --computer-ou=" ou=LinuxServer,DC=win2025,DC= mydomain
Calculated computer account: CN=LINUX-WITH-LONG,OU=LinuxServer,DC=win2025,DC=mydomain
И все заработало, вот только что это – ВСЕ ?
Попробую для начала удалить это все штатно:
/usr/sbin/realm --verbose leave
И Linux 5 минут висит на операции:
Sending NetLogon ping to domain controller
и еще 5 минут на операции:
Couldn't perform discovery search: Can't contact LDAP server
Received NetLogon info from:dc1.win2025.mydomain
И в итоге:
Process was terminated with signal: 13
Successfully unenrolled machine from realm
Но запись в AD осталась. Вот такой успешный успех.
Удалил из AD руками, что еще сделать остается.
Исправляю ошибку в конфиге выше
Еще одна не замеченная ошибка. В каком-то примере (вот в этом - realmd) настройка в /etc/realmd.conf приведена как:
[active-directory]
default-client = sssd
и вот в этой статье (Подключение Debian GNU/Linux 12 (Bookworm) к домену Active Directory с помощью SSSD и настройка PAM для доменной аутентификации и авторизации в SSHD) схоже.
У RH в то же время эта настройка приведена как
[ad.example.com]
а в статье Подключаемся к Active Directory с помощью realmd – как
[example.org]
Надо было не читать статьи по верхам, а читать документацию. Читать Debian Manpages REALMD.CONF(5) если быть точнее.
Почему так? Потому что надо было не читать статьи по верхам, а читать документацию. Читать Debian Manpages REALMD.CONF(5) если быть точнее.
Опция [active-directory]
These options should go in an [active-directory] section:
default-client
use-ldaps
os-name
os-version
Опция [domain.example.com]
For example for the domain.example.com domain the section would be called [domain.example.com]
computer-ou
computer-name
user-principal
automatic-join
automatic-id-mapping
manage-system
И в таком виде оно работает
[active-directory]
os-name = Debian GNU/Linux/PikabuTest
os-version = 12.0 (Bookworm)/or Windows[win2025.mydomain]
computer-ou = OU=LinuxServer,DC=win2025,DC=mydomain
Часть 4. Но зачем это все, или возврат к теории
Для чего надо вводить компьютер в домен?
С точки зрения домена Windows – чтобы управлять объектом «компьютер» через Desired State Configuration (DSC), и (или) через Group Policy.
С точки зрения управления пользователями – чтобы иметь единую базу конфигураций пользователей, и использовать хотя бы систему account, global, domain local – AGDLP.
Но тут мы пропустим пре-авторизацию в AD(Kerberos Pre-Authentication – или просто pre-authentication по другой статье), и перейдем к вопросу «как и зачем».
Что нам нужно? Авторизовать ПОЛЬЗОВАТЕЛЯ, а точнее аутентифицировать пользователя, получить перечисление его участия в группах AD\LDAP, и по этому списку авторизовать, то есть выдать ему нужные права на конечном сервере или сервисе. Классическое Authentication, authorization, and accounting (AAA).
И еще, для целей безопасности, нужно вовремя отзывать Ticket-Granting Tickets. И немного знать не только про Golden Ticket и Silver Ticket ,но и про privilege::debug.
И знающие люди тут же напомнят, что, хотя срок жизни TGT – 1 час плюс минус, но срок жизни Ticket-Granting Service (TGS) – 10 часов.
Поэтому все эти авторизации для сервера это хорошо, а как закрывать сессии у отозванных пользователей? Для Windows можно настроить GPO на автоматический выход, можно проверить список сессий и лишние закрыть, а для Linux системы придется держать отдельный склад костылей для проверки всех серверов и не закрытых пользовательских сессий.
Но это все в следующей части, которую, я надеюсь, кто-то уже написал. Шуйский, Курбский, вы когда закончите с etcd, может уже сами что-то напишете?
Но, к делам.
Часть 5. Лось Пользователь, просто пользователь
Напоминаю, что у нас были два локальных пользователя: AlexanderPushkin и AlexanderPushkinTheSecond
Вместо них у нас появляется два доменных пользователя:
AlexanderPushkin@win2025.mydomain и AlexanderPushkinTheSecond@win2025.mydomain
Инструкция говорит про:
Configure the /etc/krb5.conf file to use the Active Directory realm.
Set the Samba configuration file, /etc/samba/smb.conf, to point to the Windows Kerberos realm.
Какая-то явно старая инструкция, с строками
Make sure that the Services for Unix package is installed on the Windows server.
Unix package уже давно не существует. Инструкция от RH 6, текущая версия IBM RH – 10.
Когда же мы, наконец, дойдем до статьи Using Active Directory to Authenticate Linux Users, где в три раза короче написано то же, что и в других статьях, и проверим что там в
/etc/sssd/sssd.conf
в том числе по умолчанию -
fallback_homedir = /home/%u@%d
И попробуем.
/usr/sbin/realm list – окей, результаты есть.
/usr/bin/getent passwd AlexanderPushkin - – окей, результаты есть.
/usr/bin/getent passwd AlexanderPushkin@win2025.mydomain – не окей, результатов нет. Вообще ничего нет.
/usr/bin/getent passwd administrator@win2025.mydomain - не окей, результатов тоже нет.
Почему - остается только гадать. Нет вывода отладки.
Одни и другие пишут, что ldap_id_mapping = True
другие, что ldap_id_mapping = false
Но при этом, если попытаться залогиниться как AlexanderPushkinTheSecond@win2025.mydomain, то в логе контроллера AD проскочит запрос с event ID 4768 - A Kerberos authentication ticket (TGT) was requested для LINUX-WITH-LONG$
Можно конечно сделать на контроллере домена
nltest /dbflag:0x2080ffff
И посмотреть в отладку, хотя это и не случай отлова Zerologon для CVE-2020-1472.
делать я так, конечно, не буду. И так на написание заметки потрачено больше стандартного получаса.
/usr/bin/id AlexanderPushkinTheSecond – результаты есть
/usr/bin/id AlexanderPushkinTheSecond@win2025. mydomain – результаты есть, и даже список групп есть.
/usr/bin/id Administrator@win2025.mydomain – результаты есть, и даже список групп есть.
Как это так вообще работает ? Кто ни разу не входил, тому getent passwd не положен, так чтоли?
Так и есть. Цитата
Используя команды getent passwd и getent group нельзя увидеть доменных пользователей и группы. Этот функционал отключен по умолчанию, для того чтобы сократить нагрузку на серверы.
Документация к Альт линукс.
После первого входа getent passwd начинает работать и что-то показывать, но.
Поскольку я не прописывал pam-auth-update --enable mkhomedir , то и домашняя директория не создалась
В /etc/sssd/sssd.conf прописан fallback_homedir = /home/%u@%d , но автоматом все равно ничего не сделалось.
Зато я могу спокойно читать файлы из
/home/AlexanderPushkin и /home/AlexanderPushkinTheSecond
Но из /home/user не могу. Очень, очень странное поведение, как по мне.
Заключение
Дальше надо перечитывать и пробовать сделать все по статье Разграничение прав доступа к Linux-системе и её сервисам через доменные группы безопасности с помощью SSSD и PAM
Но я хотел сказать совсем другое.
Сделать авторизацию пользователей через AD и SSSD можно, и кто-то делает. Однако, если делать «в лоб» и ничего не проверять, то можно получить проблемы с безопасностью больше, чем было «до введения авторизации».
Отдельно надо отметить проблемы с авторизацией не в ssh, а внутри самих сервисов, то есть придется переписать «все вообще», особенно если у вас по каким-то легаси причинам много завязано на доменных или локальных пользователей.
Отдельным подвидом развлечения в данном случае будут зависимости сервисов самой ОС и сервисов, разворачиваемых для ОС.
Все что выше, теоретически и практически, можно и нужно автоматизировать через тот же Ansible. Команды понятны, скрипты ясны.
Automating the Process of Joining Linux Systems to an AD Domain using Ansible and SSSD
riponbanik/ansible-role-domain-join
Ansible Playbook to Join Ubuntu/Debian to Active Directory Using Realmd
Плюсы: Система, в целом, скорее работает, чем совсем не работает. Тем более в совсем простых сценариях.
Минусы: Для первичной настройки и описания надо потратить пару дней, потом еще пару дней на проверку. И все равно в чуть более сложных сценариях будет глюки. Особенно, если надо обязательный Kerberos, и никакого NTLM, если везде LDAPS, или если уровень вложенности групп чуть больше чем 1 юзер – 1 группа, или если прописаны сценарии ограничения входа на уровне AD по времени и списку серверов, итд, итп.
Документация есть, но стандартные сценарии описывают «как делать», не описывая «почему надо так, и как не надо, и что будет, если делать не как надо». Стандартные сценарии очень скупо описывают отладку «что может пойти не так».
И это решение, с централизованным управлением пользователями, не решает задач безопасности, то есть отключение в AD «типа вредоносного пользователя» не приводит к мгновенному выходу «везде». В Windows, впрочем, тоже.
Литература
Active Directory Domain Services overview
What is Active Directory? The Ultimate AD Tutorial
Configuring Microsoft Entra ID to provision users into an LDAP directory for Linux authentication
Как настроить SSH-ключи в Debian 11
How to Set Up SSH Keys on Debian 11
[Article] NTLM vs KERBEROS
Подключаемся к Active Directory с помощью realmd
Как ввести Debian в домен Windows (Active Directory) с помощью realmd, SSSD.
Debian man REALMD.CONF
Подключение Debian GNU/Linux 12 (Bookworm) к домену Active Directory с помощью SSSD и настройка PAM для доменной аутентификации и авторизации в SSHD
Разграничение прав доступа к Linux-системе и её сервисам через доменные группы безопасности с помощью SSSD и PAM
Restrict the set of groups the user is a member of with SSSD
Reddit: Realmd/SSSD on Ubuntu - Configuring Auth to AD, Running into AD groups issue
Reddit: SSSD: realmd vs adcli
Reddit: What is it called when an AD account gets "signed out" everywhere and the user has to sign back in again?
RH8 Chapter 1. Connecting RHEL systems directly to AD using SSSD
RH7 3.4. Discovering and Joining Identity Domains - Joining a Domain
RH7 3.5. Removing a System from an Identity Domain
RH7 3.9. Additional Configuration for the Active Directory Domain Entry
RH7 7.4. Additional Configuration for Identity and Authentication Providers
RH6 13.2.14. Configuring Domains: Active Directory as an LDAP Provider (Alternative)
Using Active Directory to Authenticate Linux Users
RedOS 2.9.20.6 Сравнение функций Winbind и SSSD
Astra Сравнение winbind и sssd
Документация к Альт линукс.