Настройка парольной политики windows

Салимжанов Р.Д

Настройка парольной политики в Windows 10 важна для обеспечения безопасности вашего устройства и данных. Включение и соблюдение парольных политик помогают защитить ваш компьютер от несанкционированного доступа и предотвратить утечку конфиденциальных данных.

Для настройки парольной политики в Windows 10, можно использовать инструменты локальной групповой политики или через Windows PowerShell.

Чтобы настроить парольную политику через локальную групповую политику, выполните следующие шаги:

Нажмите Win + R, чтобы открыть окно «Выполнить», введите gpedit.msc и нажмите Enter.

В локальной групповой политике перейдите в «Конфигурация компьютера», «Настройки Windows», «Параметры безопасности», «Политика паролей».

В этом разделе мы можем настроить различные параметры парольной политики, такие как минимальная длина пароля, требования к сложности пароля, максимальный период действия пароля и другие.

Давайте немного поиграемся и выставим параметры.

Минимальная длина пароля:

Число уникальных паролей:

Сложность пароля:

Если вдруг, кто-либо не понимает какой-либо из параметров window прекрасным образом предоставил кнопочку “Объяснение”, где о каждом из них можно прочитать.

Запускаем PowerShell Windows от имени Администратора.

Далее прописываем команду net accounts, она используется для просмотра и конфигурирования политик учетных записей в домене. С помощью этой команды можно просмотреть текущие настройки политик учетных записей, такие как минимальная и максимальная длина пароля, время протухания пароля и другие параметры.

А далее пользуемся командами для настройки парольной политике:

— minpwlen: Этот параметр определяет минимальную длину пароля, которая должна быть установлена для пользователей. Например, net accounts /minpwlen:8 устанавливает минимальную длину пароля равной 8 символам.

— maxpwage: Этот параметр определяет максимальный возраст пароля, после которого пользователь должен его изменить. Например, net accounts /maxpwage:90 устанавливает максимальный возраст пароля в 90 дней.

— minpwage: Этот параметр определяет минимальный возраст пароля, после которого пользователь может его изменить. Например, net accounts /minpwage:1 устанавливает минимальный возраст пароля в 1 день.

— uniquepw: Этот параметр определяет, можно ли использовать предыдущие пароли при изменении пароля. Значение yes означает, что предыдущие пароли запрещены, а no — что позволяется использовать предыдущие пароли. Например, net accounts /uniquepw:yes запрещает использование предыдущих паролей.

Пример роботы net accounts /minpwlen:8

Ну вроде все, здесь все очень легко. Точно также можно настроить политику паролей на сервере Windows 19.

В целом, настройка парольной политики в Windows способствует обеспечению безопасности вашего устройства и данных и является ��ажным элементом защиты в мире цифровых технологий.

1) Пароль не отвечает требованиям политики — как исправить? // [электронный ресурс]. URL: https://remontka.pro/password-doesnt-meet-requirements/ (дата обращения 24.07.2024).

3) Настройка AD GP: Тонкая настройка политики паролей в домене Active Directory // [электронный ресурс]. URL: https://www.youtube.com/watch?v=zQeliHLUdQI (дата обращения 24.07.2024).

Парольная политика в домене Active Directory задает базовые требования безопасности к паролям учетных записей пользователей такие как сложность, длину пароля, частоту смены пароля и т.д. Надежная политика паролей AD позволяет снизить возможность подбора или перехвата паролей пользователей.

Содержание:

  • Настройка политики паролей в Default Domain Policy
  • Основные параметры политики паролей в домене
  • Управление параметрами политики паролей AD с помощью PowerShell
  • Несколько парольных политик в домене Active Directory

Настройка политики паролей в Default Domain Policy

Настройки политика паролей пользователей в домене AD по умолчанию задаются через групповую политику Default Domain Policy. Вы можете просмотреть и изменить настройки парольной политики в домене с помощью консоли управления консоль управления доменными GPO

  1. Откройте консоль
    gpmc.msc
    и выберите Default Domain Policy, которая назначена на корень домена;
  2. Щелкните правой кнопкой по Default Domain Policy и выберите Edit;
    политика паролей пользователей active directory в Default Domain Policy

  3. Разверните Конфигурация компьютера -> Политики -> Конфигурация Windows -> Параметры безопасности -> Политики учетных записей -> Политика паролей (Computer configuration -> Policies -> Windows Settings -> Security Settings -> Account Policies -> Password Policy
  4. В этом разделе есть шесть параметров политики паролей (описаны ниже);
  5. Чтобы изменить настройки параметра, дважды щелкните по ней. Чтобы включить политику, отметьте галку Define this policy settings и укажите необходимую настройку (в примере на скриншоте я задал минимальную длину пароля пользователя 8 символов). Сохраните изменения;
    изменить настройки политики паролей в домене active directory из консоли управления gpo

  6. Новые настройки парольной политики применяться ко всем пользователям домена после обновления настроек GPO на контролере домена с FSMO ролью PDC Emulator.

Основные параметры политики паролей в домене

Всего доступно шесть параметров политики паролей:

  • Вести журнал паролей (Enforce password history) – задать количество старых паролей, которые хранятся в AD. Пользователь не сможет повторно использовать старый пароль (однако администратор домена или пользователь, которому делегированы права на сброс пароля в AD, может вручную задать для аккаунта старый пароль);
  • Максимальный срок действия пароля (Maximum password age) – срок действия пароля в днях. После истечения срока действия пароля Windows потребует у пользователя сменить его. Обеспечивает регулярность смены пароля пользователями;
  • Минимальный срок жизни пароля (Minimum password age) – как часто пользователи могут менять пароль. Этот параметр не позволит пользователю несколько раз подряд сменить пароль, чтобы вернуться к старому паролю, перезатерев пароли в журнале Password History. Как правило тут стоит оставить 1 день, чтобы пользователь мог самостоятельно сменить пароль в случае его компрометации;
  • Минимальная длина пароля (Minimum password length) – не рекомендуется делать пароль короче, чем 8 символов (если указать тут 0 – значит пароль не требуется);
  • Пароль должен отвечать требование сложности (Password must meet complexity requirements) – при включении этой политики пользователю запрещено использовать имя своей учетной записи в пароле (не более чем два символа подряд из
    username
    или
    Firstname
    ). Также в пароле должны использоваться 3 типа символов из следующего списка: цифры (0 – 9), символы в верхнем регистре, символы в нижнем регистре, спец символы ($, #, % и т.д.).

    Чтобы исключить использование пользователями простых паролей (из словаря популярных паролей) рекомендуется периодически выполнять аудит паролей в домене.

  • Хранить пароли, использую обратимое шифрование (Store passwords using reversible encryption) – пароли пользователей в базе AD хранятся в зашифрованном виде, но иногда нужно предоставить доступ некоторым приложениям к паролю. При включении этой политики пароли хранятся в менее защищенной виде (по сути, в открытом виде), что небезопасно (можно получить доступ к базе паролей при компрометации DC). При включении этой опции нужно дополнительно защищать пароли привилегированных пользователей на удаленных площадках с помощью внедрения Read-Only контроллеров домена (RODC).

Если пользователь попытается задать пароль, которые не соответствует политике паролей в домене, Windows выдаст ошибку:

Не удается обновить пароль. Введенный пароль не обеспечивает требований домена к длине пароля, его сложности или истории обновления.
Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.

Не удается обновить пароль. Введенный пароль не обеспечивает требований домена к длине пароля, его сложности или истории обновления

Обычно вместе с политикой паролей нужно настроить параметры блокировки пользователей при неправильном введении пароля. Эти настройки находятся в разделе GPO: Политика блокировки учетной записи (Account Lockout Password):

  • Пороговое значение блокировки (Account Lockout Threshold) – через сколько попыток набрать неверный пароль учетная запись пользователя будет заблокирована;
  • Продолжительность блокировки учетной записи (Account Lockout Duration) – длительность блокировки учетной записи, в течении которой вход в домен будет невозможен;
  • Время до сброса счетчика блокировки (Reset account lockout counter after) – через сколько минут счетчик неверных паролей (Account Lockout Threshold) будет сброшен.

Если учетные записи блокируются слишком часто, вы можете найти компьютер/сервер источник блокировки так.

Настройки парольных политик домена Active Directory по-умолчанию перечислены в таблице:

Политика Значение по-умолчанию
Enforce password history 24 пароля
Maximum password age 42 дня
Minimum password age 1 день
Minimum password length 7
Password must meet complexity requirements Включено
Store passwords using reversible encryption Отключено
Account lockout duration Не определено
Account lockout threshold 0
Reset account lockout counter after Не определено

Управление параметрами политики паролей AD с помощью PowerShell

Для просмотра настроек и изменения конфигурации политики паролей в AD можно использовать командлеты PowerShell из модуля Active Directory:

Вывести настройки дефолтной политики паролей:

Get-ADDefaultDomainPasswordPolicy

ComplexityEnabled : True
DistinguishedName : DC=winitpro,DC=ru
LockoutDuration : 00:30:00
LockoutObservationWindow : 00:30:00
LockoutThreshold : 0
MaxPasswordAge : 42.00:00:00
MinPasswordAge : 1.00:00:00
MinPasswordLength : 7
objectClass : {domainDNS}
objectGuid : 
PasswordHistoryCount : 24
ReversibleEncryptionEnabled : False

Get-ADDefaultDomainPasswordPolicy

Или с помощью команды:
net accounts

Команда net account вывести настройки политики паролей на компьютере

Также вы можете узнать текущие настройки политики паролей AD на любом компьютере в отчете результирующей политики, сгенерированном с помощью консольной утилиты gpresult.

Вывести информацию о том, когда пользователь менял пароль последний раз, и когда истекает его пароль:

net user aivanov /domain

Изменить параметры политики паролей AD:

Set-ADDefaultDomainPasswordPolicy -Identity winitpro.ru -MinPasswordLength 14 -LockoutThreshold 10

Несколько парольных политик в домене Active Directory

С помощью групповых политик на домен можно назначить только одну политику, которая будет действовать на всех пользователей без исключения. Даже если вы создадите новую GPO с другими парольными настройками и примените ее к OU с пользователями, эти настройки фактически не применяться.

Начиная с версии Active Directory в Windows Server 2008 с помощью гранулированных политик паролей Fine-Grained Password Policies (FGPP) можно применять индивидуальный параметры политики паролей для конкретных пользователей или групп. Например, вы хотите, чтобы пользователи из группы Server-Admins использовали пароли с минимальной длиной 15 символов.

  1. Откройте консоль Active Directory Administrative Center (
    dsac.exe
    );
  2. Перейдите в раздел System -> Password Settings Container и создайте новый объект PSO (Password Settings Object);
    Создать объект политики паролей в AD

  3. В открывшемся окне укажите название политики паролей и ее приоритет. Включите и настройте параметры парольной паролей, которые вы хотите применить. В разделе Directly Applies to нужно добавить группы или пользователей, для которых должны применяться ваши особые настройки политики паролей.
    PSO - назначить особые настройки полтитики паролей для определенных пользователей или групп

Чтобы проверить, применяются ли к конкретному пользователю особая политика паролей, выполните команду:

Get-ADUserResultantPasswordPolicy -Identity aivanov

Get-ADUserResultantPasswordPolicy

Команда выведет результирующие настройки политики паролей, которые дейсвтуиют на пользователя.


Estimated reading: 3 minutes


1291 views

Using password policy can enhance password’s security. It requires users to set password length, password age, password history, etc. Via password policy, you can set a more complicated password that’s hard to be guessed or cracked.

In this article, we will guide you to Set Password Policy on Windows server 2019.

Step 1: Press “Win” + “R” key to open “Run” window. Type in: secpol.msc then click “OK”.

Step 2: After you open “Local Security Policy”, select them in order: “Security Settings” > “Account Policies” > “Password Policy”.

Step 3: In the right pane, double click any policy and change the setting according to your needs.

Explanation of Setting Each Password Policy

Password Must Meet Complexity Requirements

Requirements as below:

1. More than two contiguous characters from user name cannot be contained in password.

2. Be at least six characters in length and three of following four types of character need to be included in password.

• English uppercase characters (A through Z)

• English lowercase characters (a through z)

• Base 10 digits (0 through 9)

• Non-alphabetic characters (for example, !, $, #, %)

Minimum Password Length

The longer the password, the safer it will be. A password should at least contain the minimum number of characters for a user account.

Minimum Password Age

This security setting determines the period of time (in days) that a password must be used before the user can change it. For example, if you set 10 days, then your password can be changed after 10 days. Besides, password can be changed anytime if the minimum password age is set to be 0.

Maximum Password Age

This security setting determines the period of time (in days) that a password can be used before the system requires the user to change it. For example, if you set 90 days, your password will expire in 90 days then system will require you to change it. But the password will not expire if the maximum password age is set to 0.

Enforce Password History

This security setting determines the number of unique new passwords that have to be associated with a user account before an old password can be reused. It can ensure the old passwords are not reused continually. For example, if you keep 9 passwords remembered, then you need to change new passwords nine times before an old password can be reused.

Store Passwords Using Reversible Encryption

This security setting determines whether the operating system stores passwords using reversible encryption. If this policy is enabled, some bad guys may easily crack the password and access users’ PCs. It’s suggested to disable it unless application requirements are more important than the protection of password information.

Conclusion

So we have guided you through the steps set Password Policy on Windows server 2019 this will help increase security on your VPS.

Введение

В этом модуле мы обсудим, что такое групповые политики и как они позволяют экономить время при выполнении задач администрирования большой ИТ-инфраструктуры.

Мы сравним техническую реализацию политик MS AD с политиками FreeIPA и ALD Pro, выполним настройку и отладку политик с использованием параметров, доступных из коробки, а также посмотрим, как создаются дополнительные параметры, с помощью которых можно организовать централизованное управление настройками любых корпоративных приложений.

После изучения материалов этого модуля вы больше никогда не будете «администрировать ногами» то, что можно настроить централизованно через групповые политики.

Концепция групповых политик

Как известно, уникальные продукты никому не нужны, а у всех востребованных решений быстро появляются аналоги, поэтому, создавая политики, разработчики FreeIPA и ALD Pro ориентировались в первую очередь на передовой опыт Microsoft.

Для новых администраторов слово «политика» может показаться странным, т.к. обычно оно ассоциируется с чем-то серьезным про менеджмент на уровне государства, а в английском языке это слово означает просто «правила», например, «Правила поведения учащихся» у них называются «Школьной политикой» (англ. School policies).

Таким образом, «политики» в Windows — это правила, в соответствии с которыми отдельный компьютер выполняет настройку рабочей среды, а «групповыми» они называются потому, что мы можем группировать эти правила в так называемые объекты. Согласитесь, если бы технология называлась «сгруппированные правила», то было бы на порядок проще, хотя и не так красиво.

В домене Active Directory объекты групповой политики можно назначить на домены, сайты и структурные подразделения, настраивая типовым образом окружение для сотен и даже тысяч пользователей и компьютеров сразу. Это позволяет многократно снижать расходы на администрирование ИТ-инфраструктуры, чем и объясняется популярность групповых политик.

В настоящий момент сложно себе представить предприятие, где было бы более тысячи компьютеров и не применялись бы групповые политики. Поэтому навыки управления групповыми политиками являются обязательным минимумом для администратора домена уровня Senior.

Политики паролей

Пароль представляет собой набор символов, который должен быть известен только самому пользователю и проверяющей стороне, поэтому, если пользователь может предъявить доказательство того, что пароль ему известен, это является подтверждением аутентичности пользователя, что он именно тот, за кого себя выдает.

Пароли являются самым простым, но при этом не самым безопасным способом аутентификации, так как их можно подобрать или перехватить, а если не устанавливать дополнительных ограничений по длине и сложности, то каждый двадцатый сотрудник в организации окажется счастливчиком, который угадает комбинацию из Топ-100, типа, 123456, password или qwerty.

Совокупность требований к паролям называют также политиками паролей, и чем строже эти требования, тем сложнее злоумышленнику подобрать пароль и воспользоваться результатами успешной атаки, но вместе с тем сложнее и пользователям работать в таком домене. Поэтому для разных категорий пользователей следует устанавливать разные требования, обеспечивающие баланс между удобством и безопасностью. И в этом вопросе главное — достичь компромисса с ИБ, поскольку, как известно, если жена хочет на море, а муж — в горы, то все едут загорать, но главе семейства разрешают взять с собой лыжи.

Изменить пароль можно по протоколу KPASSWD (464/TCP), через расширенную операцию LDAP+StartTLS (389/TCP) и просто записью нового значения в атрибут userPassword, опять же, по протоколу LDAP. Однако вне зависимости от того, какой способ будет выбран, на сервер передается именно сам пароль, а не его хеш. Это позволяет проверить длину пароля, сложность и другие параметры, после чего сгенерировать и сохранить совместимые хеши.

Политики паролей Windows

Раньше в домене Active Directory можно было задать только одну политику паролей через объект групповой политики Default Domain Policy. Да, вы можете создать несколько объектов и в каждом из них определить параметры из секции Password Policy, но ко всем пользователям в домене все равно будут применяться только те требования, которые определены в Default Domain Policy («Костыль?» — спросите вы. Не, ну в продуктах Microsoft такого не может быть!).

../_images/aldpro_mod6_image4.png

рис. 273 Политика паролей по умолчанию (Default Domain Policy)

Начиная с Windows Server 2008, в MS AD появились так называемые детальные политики паролей (Fine-Grained Password Policy, FGPPs), которые настраиваются в Центре администрирования Active Directory (Active Directory Administrative Center) путем создания контейнера настроек пароля (Password Settings Container). Каждый контейнер может быть назначен конкретным пользователям и группам, переопределяя их требования к паролям.

Следует обратить внимание также на атрибут Precedence, который определяет приоритет данной политики паролей. Если на пользователя AD действуют несколько политик, то к нему будет применена политика с меньшим значением приоритета.

../_images/aldpro_mod6_image5.png

рис. 274 Детальная политика паролей (Fine-Grained Password Policy, FGPPs)

Политики паролей FreeIPA

В службе каталога FreeIPA политики паролей устроены очень похожим образом: есть глобальная политика по умолчанию и можно создавать дополнительные политики для отдельных групп пользователей. Учитывая то, что пользователь может входить сразу в несколько групп, алгоритм проверки выглядит следующим образом:

  • Из контейнера «cn=cosTemplates,cn=accounts» отбираются шаблоны, под действие которых попадает текущий пользователь в соответствии с его участием в группах.

    В этих записях содержится минимальное количество информации, а расширенные наборы параметров представлены в контейнере «cn=kerberos» и связаны с шаблонами ссылками через значение атрибута krbPwdPolicyReference.

  • Если на пользователя не распространяется действие ни одной политики, ему будет назначена глобальная политика (global_policy) по умолчанию, см. рис. 275

  • Если пользователь попадает под действие сразу нескольких политик, то параметры политик не суммируются, а выбирается одна из них, приоритет которой будет иметь наименьшее значение, см. табл. 20, что аналогично действию параметра Precedence в политиках паролей Windows.

../_images/aldpro_mod6_image6.png

рис. 275 Запись глобальной политики паролей в LDAP-каталоге

табл. 20 Выбор политики в зависимости от приоритета

Параметр

Политика для группы А(приоритет 0)

Политика для группы В(приоритет 1)

Результат (используются параметры для группы А, приоритет 0)

Максимальный срок действия пароля

60 дней

90 дней

60 дней

Минимальная длина пароля

10 символов

0 символов (без ограничений)

10 символов

Проверки паролей ограничены возможностями MIT Kerberos, поэтому они поддерживают тот же самый набор параметров (см. табл. 21).

табл. 21 Параметры политик паролей

Параметр глобальной политики

Значение по умолчанию

Максимальный срок действия задает период в количестве секунд, в течение которого система не будет требовать смены пароля

krbMaxPwdLife = 7776000

Пароль активен 90 дней, после чего пользователю будет предложено сменить его.

Минимальный срок действия задает период в секундах, в течение которого система будет запрещать повторную смену пароля

krbMinPwdLife = 3600

После смены пароля пользователь должен подождать 1 час перед повторной сменой.

Размер журнала определяет количество предыдущих паролей, которые нельзя использовать повторно

krbPwdHistoryLength = 0

Запрет на повторное использование паролей не налагается.

Классы символов – это параметр, который определяет требование по сложности пароля, указывая сколько разных классов символов должно быть использовано в пароле: цифры; буквы нижнего регистра; буквы верхнего регистра; символы UTF-8; все остальные символы, не вошедшие ни в одну из предыдущих групп, например, ! « # $ % и т.д.

При использовании одного и того же символа более двух раз подряд сложность пароля будет занижена на один балл. Например, если сложность пароля «Secret1pwd» будет оценена в три балла (большие буквы + маленькие буквы + цифры), то для пароля «Secret111pwd» сложность снизится до двух баллов (минус один балл за повторы символа «1»).

krbPwdMinDiffChars = 0

Требований по сложности пароля по умолчанию нет.

Интересный факт, что при подсчете повторов последний символ в пароле не учитывается, поэтому если повторяющиеся символы будут идти в конце строки, то нужно, чтобы их было не меньше четырех «Secretpwd1111», иначе штраф налагаться не будет.

Минимальная длина задает минимально допустимое количество символов в пароле.

krbPwdMinLength = 8

Пользователь не может использовать пароль короче 8 символов.

Максимальное количество ошибок определяет, сколько раз пользователь может неправильно ввести пароль, прежде чем его учетная запись будет временно заблокирована. Блокировка выполняется только на текущем контроллере, на другие сервера эта информация не передается.

krbPwdMaxFailure = 6

Пользователь будет временно заблокирован после 7 неверно введенных паролей подряд.

Срок блокировки указан в параметре krbPwdLockoutDuration.

Интервал сброса ошибок задает период в секундах, по истечении которого счетчик неудачных попыток входа будет сброшен.

krbPwdFailureCountInterval = 60

Если пользователь выждет 1 минуту после 6 неудачных попыток введения пароля, то счетчик неудачных попыток обнулится.

Длительность блокировки задает период в секундах, в течение которого пользователь не сможет выполнить аутентификацию в домене. Блокировка накладывается после превышения количества разрешенных неудачных попыток входа. Блокировка выполняется только на текущем контроллере, на другие сервера эта информация не передается.

krbPwdLockoutDuration = 600

Временно заблокированный пользователь не сможет осуществить вход в систему в течение последующих 10 минут.

Следствием интеграции с MIT Kerberos является возможность использования таких атрибутов, как krbPrincipalExpiration и krbLastSuccessfulAuth. Например, с помощью команды ipa user-mod вы можете установить срок действия учетной записи, после которого пользователю станет недоступна Kerberos-аутентификация:

admin@dc-1:~$ ipa user-mod alexander.kuznetsov \
--principal-expiration='20330725115110Z'

Где срок действия учетной записи задается в формате временной метки GeneralizedTime:

  • 2033 – год;

  • 07 – месяц;

  • 25 – день месяца;

  • 115110 – часы, минуты, секунды;

  • Z – часовой пояс по нулевому (Zero) меридиану.

Примечание

Стоит заметить, что по соображениям повышения производительности работы домена фиксация даты последнего входа по умолчанию отключена и этот атрибут исключен из репликации.

Однако, если у вас достаточно вычислительных ресурсов и хорошие каналы связи, то вы можете включить эти функции изменением конфигурации сервера. Для этого потребуется посмотреть текущие настройки и установить новое значение параметра ipaconfigstring, исключив из него значение «KDC:Disable Last Success»:

admin@dc-1:~$ ipa config-show | grep паролей
  Возможности подключаемого модуля паролей: AllowNThash, KDC:Disable Last Success
admin@dc-1:~$ ipa config-mod --ipaconfigstring='AllowNThash'
  Максимальная длина имени пользователя: 32
  Максимальная длина имени хоста: 64
  Основа домашних каталогов: /home
  Оболочка по умолчанию: /bin/bash
  Группа пользователей по умолчанию: ipausers
  Почтовый домен по умолчанию: ald.company.lan
  Ограничение времени поиска: 5
  Ограничение размера поиска: 500
  Поля поиска пользователей: uid,givenname,sn,telephonenumber,ou,title
  Поля поиска групп: cn,description
  Включить режим миграции: FALSE
  Основа субъекта сертификата: O=ALD.COMPANY.LAN
  Уведомление об окончании действия пароля (в днях): 4
  Возможности подключаемого модуля паролей: AllowNThash
  Порядок применения списка пользователей SELinux: guest_u:s0$xguest_u:s0$user_u:s0$staff_u:s0-s0:c0.c1023$sysadm_u:s0-s0:c0.c1023$unconfined_u:s0-s0:c0.c1023
  Пользователь SELinux по умолчанию: unconfined_u:s0-s0:c0.c1023
  Типы PAC по умолчанию: MS-PAC, nfs:NONE
  Главные IPA-серверы: dc-1.ald.company.lan
  Главный IPA-сервер с поддержкой PKINIT: dc-1.ald.company.lan
  DNS-серверы IPA: dc-1.ald.company.lan
admin@dc-1:~$ sudo ipactl restart
[sudo] пароль для admin:
Restarting Directory Service
Restarting krb5kdc Service
Restarting kadmin Service
Restarting named Service
Restarting httpd Service
Restarting ipa-custodia Service
Restarting smb Service
Restarting winbind Service
Restarting ipa-otpd Service
Restarting ipa-dnskeysyncd Service
ipa: INFO: The ipactl command was successful
admin@dc-1:~$ kinit admin
Password for admin@ALD.COMPANY.LAN:
admin@dc-1:~$ ipa user-show admin --all --raw | grep krbLastSuccessful
  krbLastSuccessfulAuth: 20241009095204Z

Настройка политики паролей

Требования глобальной политики довольно лояльны, поэтому для группы администраторов их целесообразно сделать строже. Рассмотрим два способа создания политики: через портал управления и через командную строку.

Откройте страницу и нажмите кнопку . В поле «Наименование группы пользователей» выберите admins, установите наименьший «Приоритет», равный 0, и нажмите кнопку Сохранить. Далее вам станет доступна страница управления политикой, где вы можете задать необходимые настройки, как на нижеприведенной иллюстрации.

../_images/aldpro_mod6_image8.png

рис. 276 Создание новой политики паролей

Политику паролей можно создать из командной строки с помощью команды ipa pwpolicy-add:

admin@dc-1:~$ ipa pwpolicy-add admins \
--priority=0 --maxlife=45 --minlife=0 --history=12 \
--minclasses=5 --minlength=12 --maxfail=3 \
--failinterval=120 --lockouttime=1200
  Группа: admins
  Максимальный срок действия (в днях): 45
  Минимальный срок действия (в часах): 0
  Размер журнала : 12
  Классы символов: 5
  Минимальная длина: 12
  Приоритет: 0
  Максимальное количество ошибок: 3
  Интервал сброса ошибок: 120
  Длительность блокировки: 1200

Где:

  • Ключ --maxlife=<число> — максимальный срок действия в днях;

  • Ключ --minlife=<число> — минимальный срок действия в часах;

  • Ключ --history=<число> — размер журнала;

  • Ключ --minclasses=<число> —классы символов;

  • Ключ --minlength=<число> — минимальная длина;

  • Ключ --priority=<число> — приоритет политики;

  • Ключ --maxfail=<число> — максимальное количество ошибок;

  • Ключ --failinterval=<число> — интервал сброса ошибок в секундах;

  • Ключ --lockouttime=<число> — длительность блокировки в секундах.

Изменить параметры уже существующей политики можно командой ipa pwpolicy-mod. Увеличим интервал сброса ошибок для политики группы admins с 120 до 3600 секунд, но уменьшим длительность блокировки с 1200 до 300 секунд:

admin@dc-1:~$ ipa pwpolicy-mod admins --failinterval=3600 --lockouttime=300
  Группа: admins
  Максимальный срок действия (в днях): 45
  Минимальный срок действия (в часах): 0
  Размер журнала : 12
  Классы символов: 5
  Минимальная длина: 12
  Приоритет: 0
  Максимальное количество ошибок: 3
  Интервал сброса ошибок: 3600
  Длительность блокировки: 300

Обратите внимание, что изменение максимального срока действия пароля сразу же ни на что не повлияет, т.к. проверка выполняется по значению пользовательского атрибута krbPasswordExpiration, которое устанавливается в момент смены пароля. Текущее значение этого атрибута можно уточнить командой ipa user-show:

admin@dc-1:~$ ipa user-show admin --raw --all | grep krbPasswordExpiration
krbPasswordExpiration: 20240414095400Z

Таким образом, чтобы изменения в части срока действия паролей вступили в силу, пользователь должен хотя бы один раз сменить свой пароль, но при необходимости вы можете установить значение krbPasswordExpiration вручную с помощью команды ipa user-mod. Это удобно также в тех случаях, когда вам нужно сбросить пользователю пароль, но вы не хотите, чтобы система сразу же требовала смены пароля.

admin@dc-1:~$ ipa user-mod admin --password-expiration 20240301010101Z
----------------------------
Изменён пользователь "admin"
----------------------------
Имя учётной записи пользователя: admin
Фамилия: Administrator
Домашний каталог: /home/admin
Оболочка входа: /bin/bash
Псевдоним учётной записи: admin@ALD.COMPANY.LAN, root@ALD.COMPANY.LAN
Окончание действия пароля пользователя: 20240701010101Z
UID: 1902000000
ID группы: 1902000000
Учётная запись отключена: False
Link to department: ou=ald.company.lan,cn=orgunits,cn=accounts,dc=ald,dc=company,dc=lan
Link to head department: ald.company.lan
Пароль: True
Участник групп: trust admins, ald trust admin, admins, lpadmin
Роли: ALDPRO - Main Administrator
Доступные ключи Kerberos: True

Группы с автоматическим участием

Область применения HBAC-правил можно задать с помощью групп пользователей и групп хостов, но в некоторых случаях может быть удобнее использовать для этого структурные подразделения. В этом случае вы можете воспользоваться вспомогательными группами и правилами автоучастия (от англ. automember).

Привязка объектов к структурным подразделениям в ALD Pro осуществляется с помощью атрибута rbtadp, в котором хранится ссылка на целевое подразделение в формате полного уникального имени записи (от англ. Distinguished name, DN). Например, если у вас в корне домена есть структурное подразделение «Московский офис», то значение атрибута rbtadp всех дочерних объектов будет «ou=Московский офис,ou=ald.company.lan,cn=orgunits,cn=accounts,dc=ald,dc=company,dc=lan».

Если вам потребуется ограничить выборку только прямыми наследниками, вы можете поставить символ подстановки «^» в начало строки, что позволит вам исключить объекты из подразделений, расположенных ниже по иерархии организационной структуры.

Создадим группу пользователей и правило автоучастия из веб-интерфейса:

  1. Создайте группу пользователей. Для этого на странице нажмите кнопку , введите название группы «moscow-office-employees», выберите подразделение «Московский офис» и нажмите кнопку .

  2. Создайте правило автоучастия. Для этого потребуется воспользоваться интерфейсом FreeIPA https://dc-1.ald.company.lan/ipa/ui. Откройте страницу , нажмите кнопку , см. рис. 278. В диалоговом окне добавления правила выберите группу «moscow-office-employees» из списка и нажмите кнопку .

../_images/aldpro_mod6_image9.png

рис. 277 Переход к списку правил автоучастия для групп пользователей

../_images/aldpro_mod6_image10.png

рис. 278 Создание правила автоучастия для группы moscow-office-employees

  1. На странице редактирования добавьте критерий отбора по атрибуту rbtadp и значению «ou=Московский офис,ou=ald.company.lan,cn=orgunits,cn=accounts,dc=ald,dc=company,dc=lan», см. рис. 279. Не забудьте нажать кнопку «Сохранить».

../_images/aldpro_mod6_image11.png

рис. 279 Редактирование правила автоучастия для группы moscow-office-employees

Пересчет правил автоучастия происходит не мгновенно, но вы можете ускорить применение этих правил с помощью команды ipa automember-rebuild:

admin@dc-1:~$ ipa automember-rebuild --type=group
--------------------------------------------------------------------
Automember rebuild task finished. Processed (5) entries in 0 seconds
--------------------------------------------------------------------
admin@dc-1:~$ ipa group-show moscow-office-employees | grep "Пользователи"
Пользователи-участники: asidorov, ppetrov, iivanov, vsidorova

Если пользователи так и не появятся в списке участников группы, то необходимо проверить корректность фильтра. Обзор записей выполняется по полному вхождению, поэтому никаких лишних пробелов в середине строки быть не должно.

Тоже самое можно сделать из командной строки:

  1. Создать группу пользователей moscow-office-employees в подразделении «Московский офис»:

admin@dc-1:~$ ipa group-add moscow-office-employees
admin@dc-1:~$ ipa group-mod moscow-office-employees --setattr="rbtadp=ou=Московский офис,ou=ald.company.lan,cn=orgunits,cn=accounts,dc=ald,dc=company,dc=lan"
admin@dc-1:~$ ipa group-mod moscow-office-employees --desc='Группа, в которой будут все сотрудники московского офиса'
  1. Создать правило автоучастия и определить критерий автоучастия:

admin@dc-1:~$ ipa automember-add moscow-office-employees --type=group
admin@dc-1:~$ ipa automember-mod moscow-office-employees --type=group --desc='Правило автоучастия для наполнения группы сотрудников московского офиса'
admin@dc-1:~$ ipa automember-add-condition moscow-office-employees \
--type=group --key=rbtadp --inclusive-
regex='ou=Московский офис,ou=ald.company.lan,cn=orgunits,cn=accounts,dc=ald,dc=company,dc=lan'
  1. Принудительно обновить состав автоучастников (запускать команду нужно только 1 раз, в дальнейшем правила будут срабатывать автоматически изменении подразделения объекта):

admin@dc-1:~$ ipa automember-rebuild --type=group

Политики доступа к узлу (HBAC-правила)

Только представьте себе: новому сотруднику с задатками пентестера выдают ноутбук, блокнот, кружку и доменную учетную запись, а он вместо того, чтобы пойти за кофе, начинает сразу же ломиться на серверы по всем доступным протоколам. И если системный администратор не подумает об этом сценарии заранее, то пользователь прорвется на сервер, а далее останется уповать только на правильные настройки доступа к объектам файловой системы.

Чтобы предотвратить подобного рода атаки, можно ограничить доступ к серверам по определенным протоколам из пользовательского сегмента сети, но лучше полностью запретить обычным пользователям интерактивный вход на серверы.

Политика локального входа Windows

В домене Active Directory управлять правами локального входа в систему можно с помощью двух параметров групповых политик, которые находятся в разделе в подразделе
( и ):

  • Allow log on locally (Локальный вход в систему) — определяет список пользователей и групп, которым разрешен локальный вход в систему.

  • Deny log on locally (Запретить локальный вход) — определяет список пользователей и групп, которым запрещен локальный вход в систему. Если пользователь попадает под действие двух параметров сразу, то запрещающий параметр имеет больше приоритет, поэтому доступ будет заблокирован.

На контроллеры домена AD интерактивно могут заходить только пользователи шести административных групп, что определено параметрами объекта групповой политики Default Domain Controllers Policy, см. рис. 280.

../_images/aldpro_mod6_image12.png

рис. 280 Настройки параметра Allow log on locally в объекте групповой политики Default Domain Controllers Policy

Политики доступа к узлу FreeIPA

Для ограничения доступа к компьютерам в домене FreeIPA есть мощные правила управления доступом к хостам (от англ. host-based access control, HBAC), которые значительно превосходят по функциональности политики локального входа Windows. Они создают дополнительный слой авторизации, позволяя разрешить определенным пользователям использовать указанные службы на конкретных хостах.

Что такое «пользователи» и «хосты», обычно вопросов не вызывает, но понятие «служб» требует дополнительных пояснений. В контексте правил HBAC службами являются любые приложения, которые используют PAM-стек, и при этом не важно, являются ли эти приложения просто исполняемыми файлами или работают как демоны в фоновом режиме.

Как мы уже знаем, библиотека подключаемых модулей аутентификации (от англ. Pluggable Authentication Modules, PAM) обеспечивает унифицированный программный интерфейс для абстрагирования приложений (таких как login, sshd или sudo) от выполнения стандартных задач аутентификации.

Перечень необходимых модулей аутентификации для каждого приложения задается индивидуально с помощью конфигурационных файлов из директории /etc/pam.d, поэтому настройки могут быть изменены в любой момент, что не потребует повторной компиляции приложения. За обработку правил HBAC, например, отвечает модуль pam_sss.so, который является одной из клиентских библиотек службы sssd, обеспечивающей работу хоста в домене. Механизм работы правил HBAC отражен на рисунке рис. 281.

При подключении пользователя по ssh служба sshd обращается к библиотеке PAM, чтобы создать контекст безопасности для выполнения команд от имени этого пользователя. При вызове функции «pam_start» служба передает библиотеке свой идентификатор (PAM service name), который представляет собой простую строку, например, «sshd». Идентификатор службы обычно совпадает с именем исполняемого файла, но это не является обязательным условием, а некоторые приложения могут использовать даже несколько идентификаторов, например, утилита sudo может применять дополнительный идентификатор sudo-i. Идентификатор службы определяет имя файла из каталога pam.d, откуда библиотека PAM будет брать настройки стека модулей (например, для службы sshd настройки будут из файла /etc/pam.d/sshd).

Для вступления в силу изменений в настройках HBAC-правил вы можете воспользоваться на целевой машине командами sss_cache -E или sssctl cache-remove, входящие в пакет sssd-tools, чтобы очистить локальный кэш службы sssd. Пакет sssd-tools по умолчанию не установлен.

И, наверно, стоит заметить, что в разных дистрибутивах Linux приложения могут использовать разные идентификаторы, например, ssh и sshd, поэтому список служб нужно будет расширять в соответствии с тем, какие операционные системы с каким программным обеспечением используются в инфраструктуре вашего предприятия.

../_images/aldpro_mod6_image13.png

рис. 281 Механизм работы HBAC-правил

Еще один важный момент. В силу особенностей FreeIPA в правилах HBAC не получится использовать следующие группы:

  • группу пользователей ipausers, т.к. у нее нет POSIX-идентификатора, и поэтому на целевых хостах служба SSSD не отображает участие пользователей в этой группе;

  • группу хостов ipaservers, т.к. у нее нет класса mepManagedEntry и соответствующих зависимостей.

Самый простой способ обойти указанные проблемы – это создать вспомогательные группы posix-ipausers/posix-ipaservers и сделать группы ipausers/ipaservers их участниками. В этом случае можно использовать вспомогательные группы в политиках без ограничений.

Настройка политик доступа к узлу

Ограничиваем доступ к серверам

Как мы уже отметили, правила HBAC являются «разрешающими», т. е. «по умолчанию» доступ к службам на доменных компьютерах запрещен, и его нужно открывать с помощью правил. Однако при развертывании домена автоматически создается правило allow_all, которое разрешает доступ «всех ко всему», поэтому для управления авторизацией на уровне HBAC нам нужно сначала ограничить область применения этого правила, например, только группой администраторов.

Внести указанные настройки можно через веб-портал управления на странице , см. рис. 282, или через командную строку:

admin@dc-1:~$ kinit admin
admin@dc-1:~$ ipa hbacrule-show allow_all
admin@dc-1:~$ ipa hbacrule-mod allow_all --usercat=''
admin@dc-1:~$ ipa hbacrule-add-user allow_all --group admins
admin@dc-1:~$ ipa hbacrule-mod allow_all --desc='Разрешает администраторам доступ к любому хосту в домене'

Где:

  • hbacrule-mod — команда, с помощью которой можно модифицировать настройки существующей группы;

    • allow_all — имя правила, которые мы хотим модифицировать;

    • usercat (от англ. user category) — ключ, который позволяет изменить категорию для области применения в части пользователей. Может принимать значение „all“ или пустую строку „“;

  • hbacrule-add-user — команда, с помощью которой можно расширить область применения правила в части пользователей;

    • allow_all — имя правила, которое мы хотим модифицировать;

    • group — ключ, который позволяет добавить группу пользователей в область применения HBAC-правила;

    • admins — имя группы, которая будет добавлена в область применения правила;

  • hbacrule-show — команда, с помощью которой можно получить информацию о существующем HBAC-правиле;

    • allow_all — имя правила, по которому мы хотим получить информацию;

../_images/aldpro_mod6_image14.png

рис. 282 Настройка HBAC-правила allow_all.

Примечание

Если из-за неправильной настройки HBAC-правил доступ к хостам будет все же заблокирован, вы сможете подключиться к порталу управления с любого другого компьютера, который не находится в домене, чтобы исправить ошибку. Доступ к порталу управления не регулируется через механизм HBAC-правил.

Если ограничить область действия правила allow_all группой администраторов, то для остальных сотрудников компании нужно будет создать правило allow_computers, которое предоставит им право входа на обычные компьютеры в домене.

Сделаем все из командной строки:

admin@dc-1:~$ ipa hostgroup-add computers # создание группы компьютеров
admin@dc-1:~$ ipa hostgroup-mod computers --desc='Группа, в которой будут все обычные компьютеры домена' # описание
admin@dc-1:~$ ipa hostgroup-add-member computers --hosts pc-1 # включение в группу хоста pc-1
admin@dc-1:~$ ipa hbacrule-del allow_computers # удаление созданного ранее HBAC-правила
admin@dc-1:~$ ipa hbacrule-add allow_computers # создание HBAC-правила
admin@dc-1:~$ ipa hbacrule-mod allow_computers --desc='Разрешает всем пользователям доступ к обычным компьютерам в домене' # описание
admin@dc-1:~$ ipa hbacrule-mod allow_computers --usercat=all # установить область применения на всех пользователей
admin@dc-1:~$ ipa hbacrule-mod allow_computers --servicecat=all # установить область применения на все службы
admin@dc-1:~$ ipa hbacrule-add-host allow_computers --hostgroup computers # назначить правило на группу хостов

Где:

  • Команда ipa hbacrule-add — создает HBAC-правила;

  • Команда ipa hbacrule-mod — модифицирует правила, ключ --desc позволяет задать описание;

  • Команда ipa hbacrule-add-host — команда позволяет определить область применения правила;

  • Ключ --hostgroups — позволяет указать группу хостов.

Убедимся, что пользователь iivanov в данный момент имеет право входить на компьютер pc-1.

  1. Войдем пользователем iivanov на компьютер pc-1 в режиме рабочего стола.

  2. После успешного входа сменим сессию на пользователя admin и проверим журнал /var/log/auth.log:

admin@pc-1:~$ sudo grep -i iivanov /var/log/auth.log | tail
. . .
Feb 2 12:12:55 pc-1 fly-dm[29087]: :0[29087]: pam_unix(fly-dm:auth): authentication failure;
logname= uid=0 euid=0 tty=/dev/tty7 ruser= rhost= user=iivanov@ald.company.lan
Feb 2 12:12:55 pc-1 fly-dm[29087]: :0[29087]: pam_sss(fly-dm:auth): authentication success;
logname= uid=0 euid=0 tty=/dev/tty7 ruser= rhost= user=iivanov@ald.company.lan
Feb 2 12:12:55 pc-1 fly-dm[29087]: :0[29087]: pam_sss(fly-dm:account): Access denied for user
iivanov@ald.company.lan: 6 (Доступ запрещен)
. . .
Feb 2 12:43:12 pc-1 fly-dm[29087]: :0[29087]: pam_unix(fly-dm:auth): authentication failure;
logname= uid=0 euid=0 tty=/dev/tty7 ruser= rhost= user=iivanov@ald.company.lan
Feb 2 12:43:12 pc-1 fly-dm[29087]: :0[29087]: pam_sss(fly-dm:auth): authentication success;
logname= uid=0 euid=0 tty=/dev/tty7 ruser= rhost= user=iivanov@ald.company.lan
Feb 2 12:43:12 pc-1 fly-dm[29087]: :0[29087]: pam_kiosk2(fly-dm:session): No
iivanov@ald.company.lan profile found, trying common profile
Feb 2 12:43:12 pc-1 fly-dm[29087]: :0[29087]: pam_unix(fly-dm:session): session opened for user
iivanov@ald.company.lan by (uid=0)
. . .

Из журнала видно, что при попытке входа пользователем iivanov до создания правила computers_allow эта учётная запись не прошла проверку в модуле pam_sss подсистемы аутентификации pam. Более того, по журналу мы видим, что доступ требовался службе с идентификатором fly-dm.

Гранулированный доступ к службам

Для тонкой настройки HBAC-правил необходимо тщательно анализировать типовые сценарии работы пользователей в части используемых служб. Например, для подключения по RDP потребуются fly-wm и xrdp-sesman, см. табл. 22:

табл. 22 Службы, необходимые для типовых сценариев работы

Сценарий работы пользователя

К каким идентификаторам служб следует предоставить доступ

Локальный вход в систему

fly-dm

Удаленный доступ к менеджеру окон по протоколу RDP

fly-wm, xrdp-sesman

Удаленное администрирование по протоколу SSH

sshd, sudo

Чтобы понять, к какой службе требуется предоставить доступ, проще всего выполнить необходимое действие на целевой системе и посмотреть, какие сообщения об ошибках появятся в журнале /var/log/auth.log. На приведенном ниже примере видно, что пользователю не хватает прав на запуск sshd:

root@pc-1:~# tail -f /var/log/auth.log
...
Mar 15 15:25:22 client 4 sshd[30424]: pam_sss(sshd:account): Access denied
for user alexander.kuznetsov: 6 (Permission denied)
...

После развертывания домена в системе уже есть список наиболее распространенных служб, но какие-то службы нам все равно потребуется добавить вручную. Давайте создадим «xrdp-sesman». Сделать это можно через веб-интерфейс на странице , см. рис. 283, или из командной строки:

admin@dc-1:~$ kinit admin
admin@dc-1:~$ ipa hbacsvc-add 'xrdp-sesman' --desc='Доступ по RDP'
../_images/aldpro_mod6_image15.png

рис. 283 Добавление служб HBAC в интерфейсе портала управления ALD Pro

Допустим, нам нужно предоставить возможность разработчикам из группы dev-users удаленно подключаться к своим компьютерам из группы dev-computers через SSH/RDP и выполнять отдельные команды из-под sudo. Для этого откройте страницу и нажмите кнопку . Введите имя правила «allow_developers» и нажмите кнопку . Настройте область применения правила: группа пользователей «dev-users», группа хостов «dev-computers», службы fly-dm, fly-wm, xrdp-sesman, sshd и sudo. Тоже самое можно сделать из командной строки:

admin@dc-1:~$ kinit admin
admin@dc-1:~$ ipa hbacrule-add allow_developers --desc='Доступ для разработчиков'
admin@dc-1:~$ ipa hbacrule-add-user allow_developers --groups dev-users
admin@dc-1:~$ ipa hbacrule-add-host allow_developers --hostgroups dev-computers
admin@dc-1:~$ ipa hbacrule-add-service allow_developers --hbacsvcs fly-dm
admin@dc-1:~$ ipa hbacrule-add-service allow_developers --hbacsvcs fly-wm
admin@dc-1:~$ ipa hbacrule-add-service allow_developers --hbacsvcs xrdp-sesman
admin@dc-1:~$ ipa hbacrule-add-service allow_developers --hbacsvcs sshd
admin@dc-1:~$ ipa hbacrule-add-service allow_developers --hbacsvcs sudo

Проверка HBAC-правил

Когда у вас в домене два-три правила, их довольно легко проверить напрямую, подключаясь к целевым хостам под тестовыми учетными записями. Но в реальной инфраструктуре потребуется управлять десятками правил, и упростить их отладку поможет команда ipa hbactest, которая работает как RSOP в Windows, моделируя применение правил по тому же алгоритму, который будет использовать служба SSSD.

Вы можете выполнить команду на любом контроллере домена и для любого сочетания пользователь-хост-сервис, чтобы получить ответ о том, есть ли в домене правило, которое соответствует этим критериям. Например, давайте проверим, что iivanov имеет доступ к службе sudo на хосте pc-1:

admin@dc-1:~$ ipa hbactest --user=iivanov --host=pc-1 --service=sudo
-------------------------
Доступ предоставлен: True
-------------------------
Соответствующие правила: allow_computers
Несоответствующие правила: allow_all
Несоответствующие правила: allow_computers_fly
Несоответствующие правила: allow_systemd-user

Выполним проверку конкретного правила allow_computers_fly с помощью ключа --rules, сможет ли пользователь ppetrov выполнить вход на компьютер pc-1, для чего ему нужна служба fly-dm:

admin@dc-1:~$ ipa hbactest --user=ppetrov --host=pc-1 --service=fly-dm --rules allow_computers_fly
-------------------------
Доступ предоставлен: True
-------------------------
 Соответствующие правила: allow_computers_fly

Политики повышения привилегий (SUDO-правила)

Хорошо известно, что безопасники плохого не посоветуют, но и хорошего не разрешат, но для установки программного обеспечения и выполнения других задач администрирования сотрудникам все же необходимы привилегии суперпользователя.

Для этих целей можно, конечно, использовать привилегированную учетную запись, но из соображений безопасности рекомендуют все же работать из-под обычной учетной записи и повышать привилегии только при выполнении отдельных команд. Еще более востребован указанный подход, когда часть административных прав нужно делегировать обычным пользователям, например, чтобы разрешить им перезапуск служб.

Запуск от имени другого пользователя в Windows

В операционной системе Windows запустить приложение от имени другого пользователя проще всего, если кликнуть по файлу правой кнопкой мыши, удерживая Shift, и выбрать в контекстном меню . Того же эффекта можно достичь утилитой runas.exe и командлетом Start-Process с параметром -Verb RunAs. Но во всех этих случаях мы получаем функциональность, аналогичную возможностям утилиты su, поэтому нам потребуется передать пользователю пароль от привилегированной учетной записи.

Совсем недавно в Microsoft объявили о релизе утилиты sudo для Windows, которая в отличие от runas поддерживает запуск программ из-под администратора с применением механизма UAC (User Account Control) для верификации запроса, т. е. без запроса пароля. Превратится ли она в продвинутый способ выполнения команд с повышенными привилегиями — будем посмотреть.

Политики повышения привилегий FreeIPA

Возможности Linux по повышению привилегий значительно шире. Кроме утилиты su и управляющих стики-битов с незапамятных времен существовала утилита sudo, которая имеет очень богатые настройки и позволяет логировать неудачные попытки аутентификации.

Например, вызовом следующей команды обычный пользователь может установить приложение htop, если ему разрешено запускать утилиту apt через sudo:

iivanov@dc-1:~$ sudo apt install htop

Правила SUDO можно определить не только в локальном файле /etc/sudoers, но и централизованно через службу каталога, создавая дополнительный слой авторизации, с помощью которого можно разрешить определенным пользователям на конкретных хостах выполнять отдельные команды с повышенными привилегиями.

В то время, как правила HBAC реализованы на уровне PAM-стека, правила SUDO проверяются непосредственно внутри утилиты sudo. Но обратите внимание, что утилита sudo в начале своей работы запускает PAM-контекст, поэтому, для того чтобы пользователь смог воспользоваться своими SUDO-правилами, ему нужно предоставить доступ в том числе к HBAC-службе sudo.

Мы уже рассматривали подробно утилиту sudo, ее правила и лучшие практики их использования в Модуль 10. Система аутентификации PAM и управление правами SUDO курса Часть 1. Astra Linux . Поэтому не будем подробно останавливаться на этом и сразу перейдем к особенностям работы правил SUDO в домене.

Список источников правил утилита sudo получает через библиотеку службы имен (Name Service Switch, NSS), настройки которой находятся в файле /etc/nsswitch.conf. Как мы знаем, в операционных системах Linux через этот механизм настраиваются источники для получения информации о пользователях, группах, DNS-записях и многом другом. Основные вызовы NSS реализованы в библиотеке libc, а та уже, в свою очередь, выполняет обращение к необходимым бэкендам, как показано на рис. рис. 284.

../_images/aldpro_mod6_image16.png

рис. 284 Архитектура диспетчера службы имен (Name Service Switch, NSS)

После установки freeipa-client в файле /etc/nsswitch.conf можно найти строку с настройкой базы данных /etc/sudoers. По умолчанию правила сначала берутся из локального файла, а затем через модуль sss, который отвечает за взаимодействие с LDAP-каталогом через службу SSSD.

admin@dc-1:~$ cat /etc/nsswitch.conf | grep sudoers
sudoers: files sss

Поддержка каталогов появилась в sudo c выходом модуля ldap для nss в 2004 году. Источником правил для модуля служили записи из DN «ou=sudoers,{basedn}=имя,{basedn}=домена,{basedn}=организации».

Модуль sudo работал с примитивной схемой хранения данных, которая повторяла синтаксис локального файла sudoers, игнорируя доступную в каталоге нормализацию данных, например, в части пользователей, групп и хостов. Поэтому при реализации поддержки правил SUDO разработчики FreeIPA создали новую схему, лишенную указанных недостатков. Информация о правилах SUDO во FreeIPA хранится в DN «cn=sudorules,cn=sudo,{basedn}=имя,{basedn}=домена,{basedn}=организации», и служба SSSD берет данные напрямую из этой ветки каталога.

Однако для обеспечения совместимости со старым модулем ldap служба каталога FreeIPA с помощью плагина Compat автоматически конвертирует настройки правил в старый формат, как показано на рисунке рис. 285. Например, если для правила в cn=sudorules установить ipaEnabledFlag=FALSE, то соответствующая запись в ou=sudoers будет автоматически удалена, но
стоит вернуть атрибуту значение TRUE, и запись будет создана повторно.

../_images/aldpro_mod6_image17.png

рис. 285 Два источника правил SUDO для разных клиентов

Служба SSSD кэширует правила SUDO, что дает пользователям возможность повышать свои привилегии, даже если они не подключены к домену прямо сейчас. По умолчанию время кэширования составляет 5400 секунд, и для немедленного применения правил на клиентской машине можно выполнить удаление кэша, например, командой sudo sssctl cache-remove.

Настройка политики повышения привилегий

Создание правил SUDO

Давайте предоставим пользователям право на остановку и перезапуск служб с помощью утилиты systemctl на компьютерах, где они смогут выполнить интерактивный вход в систему.

Учитывая, что пользователи и хосты уже есть в домене, настройку правил следует начать с создания команды. Сделать это можно, например, через портал управления ALD Pro на странице , см. рис. 286, или из командной строки:

admin@dc-1:~$ kinit admin
admin@dc-1:~$ ipa sudocmd-add '/usr/bin/systemctl' --desc='Запуск systemctl'

Где:

  • Команда ipa sudocmd-add – создает в системе новую команду SUDO.

    • Параметр /usr/bin/systemctl – полный путь к утилите. Название команды может содержать разрешенные параметры вызова.

    • Ключ --desc – позволяет задать описание команды.

../_images/aldpro_mod6_image18.png

рис. 286 Создание новой команды SUDO

Внимание

В названии команды можно использовать символы «a-z, A-Z, 0-9, -_./~» и пробелы (если только не в начале и конце строки).

Таким образом вы можете определить не только путь к утилите, но и параметры, с которыми вы разрешаете ее запускать. Например, можно разрешить только перезапуск службы sssd, если указать название команды как /usr/bin/systemctl restart sssd.service.
В тоже время интерфейс ALD Pro версии 2.4.0 не позволяет использовать символ «=» в названии правил SUDO. Если вам вдруг понадобятся такие команды, вы всегда сможете их создать через командную строку или веб-интерфейс FreeIPA.

После того, как команда готова, нужно создать правило SUDO и назначить с помощью этого правила команду на пользователей и компьютеры из веб-интерфейса, см. рис. 287, или из командной строки:

admin@dc-1:~$ ipa sudorule-add 'systemctl'
admin@dc-1:~$ ipa sudorule-mod 'systemctl' --usercat=all
admin@dc-1:~$ ipa sudorule-mod 'systemctl' --hostcat=all
admin@dc-1:~$ ipa sudorule-add-allow-command 'systemctl' --sudocmds='/usr/bin/systemctl'

Где:

  • Команда ipa sudorule-add — создает правило SUDO;

  • Команда ipa sudorule-mod — изменяет правило SUDO;

    • Ключ --usercat — задает категорию пользователей, которой разрешено использование данного правила.

    • Ключ --hostcat — задает категорию хостов, на которых разрешено использование данного правила.

  • Команда ipa sudorule-add-allow-command — добавляет команду в правило SUDO.

../_images/aldpro_mod6_image20.png

рис. 287 Создание правила SUDO

Пройдем по основным параметрам правила:

  • Раздел Основные:

    • Порядок sudo (необязательный параметр) – целое число, которое определяет очередность выполнения правил. Чем больше значение, тем позже обрабатывается правило, а значит оно может переопределить те правила, которые стоят перед ним.

      Если список команд содержит несколько значений, они обрабатываются в указанном порядке.

      Если у правила одновременно заданы и разрешающие, и запрещающие команды, то сначала обрабатываются разрешающие.

    • Описание – необязательный комментарий к правилу.

    • Состояние – переключатель определяет, включено правило или нет.

    Обязательно сохранить изменения до перехода к следующей вкладке, иначе изменения будут утеряны.

  • Вкладка Параметры:

    С помощью параметров можно изменить поведение утилиты для ее тонкой настройки. Ниже приведено несколько наиболее востребованных параметров:

    • authenticate – с помощью этого флага можно обязать пользователей вводить пароль при выполнении команды через sudo. Параметр включен по умолчанию, и для отмены требования по вводу пароля его следует отключить, для чего нужно поставить восклицательный знак перед названием параметра «!authenticate».

    • passwd_tries – задает количество попыток ввода пароля, прежде чем sudo завершит работу и зарегистрирует ошибку. Задается в виде переменной, по умолчанию passwd_tries=3.

    • timestamp_timeout – задает количество минут, которое должно пройти перед тем, как sudo повторно запросит пароль. Если установить таймаут равным 0, то утилита будет запрашивать пароль всегда, если установить отрицательное значение, таймаут будет отключен и введенный ранее пароль будет храниться бессрочно. По умолчанию таймаут составляет 15 минут.

    Информацию по остальным параметрам можно найти в man sudoers. Значения по умолчанию, с которыми утилита sudo была скомпилирована, можно узнать, вызвав команду sudo с ключом -V под суперпользователем, например, sudo sudo -V.

Внимание

Обратите внимание, что интерфейсе ALD Pro во вкладке «Параметры» не позволяет использовать символ «=». Если вам понадобится установить параметр, например, passwd_tries=2, вы всегда сможете его создать через веб-интерфейс FreeIPA.

Пользователи, компьютеры и команды назначаются так же, как для правил HBAC. На вкладке «Запуск от имени» вы можете указать пользователей и группы, от имени которых пользователь сможет запускать указанные команды, используя ключи -u и -g. Для того чтобы разрешить действовать от суперпользователя, следует оставить эту вкладку незаполненной.

Внимание

Обратите внимание, что в интерфейсе ALD Pro в версиях 2.2.0 и 2.3.0 в настройках правила не получится задать значение «любая команда». Если вы захотите не ограничивать пользователя списком команд, воспользуйтесь командой
ipa sudorule-mod 'Имя_правила' --cmdcat=all или веб-интерфейсом FreeIPA.

Проверка правил SUDO

Результирующий набор правил SUDO, который фактически применяется для конкретного пользователя на конкретном хосту, можно получить вызовом на целевой машине команды sudo с ключами -l (строчная L) и -U:

admin@dc-1:~$ sudo -l -U admin
Matching Defaults entries for admin on dc-1:
    env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,

secure_path=/usr/lib/parsec/bin\:/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User admin may run the following commands on dc-1:
    (ALL : ALL) ALL
    (root) ALL

В отладке правил вам также поможет журнал утилиты sudo, для включения которого потребуется создать файл /etc/sudo.conf (по умолчанию файла не существует) со следующим содержимым:

Debug sudo /var/log/sudo_debug.log all@debug
Debug sudoers.so /var/log/sudo_debug.log all@debug

В файле sudo_debug.log будет представлена информация о пользователе и среде окружения в момент запуска команды sudo:

sudo[22259] settings: debug_flags=all@debug
sudo[22259] settings: run_shell=true
sudo[22259] settings: progname=sudo
sudo[22259] settings: network_addrs=192.0.2.1/255.255.255.0
fe80::250:56ff:feb9:7d6/ffff:ffff:ffff:ffff::
sudo[22259] user_info: user=user_name
sudo[22259] user_info: pid=22259
sudo[22259] user_info: ppid=22172
sudo[22259] user_info: pgid=22259
sudo[22259] user_info: tcpgid=22259
sudo[22259] user_info: sid=22172
sudo[22259] user_info: uid=10000
sudo[22259] user_info: euid=0
sudo[22259] user_info: gid=554801393
sudo[22259] user_info: egid=554801393
sudo[22259] user_info:
groups=498,6004,6005,7001,106501,554800513,554801107,554801108,554801393,554801503,554802131,554802244,554807670
sudo[22259] user_info: cwd=/
sudo[22259] user_info: tty=/dev/pts/1
sudo[22259] user_info: host=client
sudo[22259] user_info: lines=31
sudo[22259] user_info: cols=237

С помощью этой информации можно получить ответы на ряд вопросов:

  • Какой источник информации использовался для извлечения правил SUDO:

sudo[22259] <- sudo_parseln @ ./fileops.c:178 := sudoers: files sss
  • Со следующей строки включается в работу плагин SSSD:

sudo[22259] <- sudo_sss_open @ ./sssd.c:305 := 0
  • Как много правил было получено от службы SSSD:

sudo[22259] Received 3 rule(s)
  • Подошли эти правила или нет:

sudo[22259] sssd/ldap sudoHost 'ALL' ... MATCH!
sudo[22259] <- user_in_group @ ./pwutil.c:1010 := false

Вы можете также включить повышенный уровень логирования в настройках /etc/sssd/sssd.conf и перезапустить службу.

[domain/domain_name]
debug_level = 8
...
[sudo]
debug_level = 8

При использовании утилиты sudo будет создан файл журнала /var/log/sssd/sssd_domain_name.log, с помощью которого можно будет получить информацию по ряду вопросов:

  • Как много правил было получено от службы SSSD:

[sdap_sudo_refresh_load_done] (0x0400): Received 4-rules rules
  • Какие правила служба SSSD загрузила с сервера:

[sssd[be[LDAP.PB]]] [sysdb_save_sudorule] (0x0400): Adding sudo rule demo-name
  • Находились ли подошедшие правила в кэше:

[sdap_sudo_refresh_load_done] (0x0400): Sudoers is successfully stored in cache
  • Какой фильтр был использован для загрузки правил с сервера:

[sdap_get_generic_ext_step] (0x0400): calling ldap_search_ext with
[(&(objectClass=sudoRole)(|(!(sudoHost=*))(sudoHost=ALL)(sudoHost=client.example.com)(sudoHost=client)(sudoHost=192.0.2.1)(sudoHost=192.0.2.0/24)(sudoHost=2620:52:0:224e:21a:4aff:fe23:1394)(sudoHost=2620:52:0:224e::/64)(sudoHost=fe80::21a:4aff:fe23:1394)(sudoHost=fe80::/64)(sudoHost=+*)(|(sudoHost=*\\*)(sudoHost=*?*)(sudoHost=*\2A*)(sudoHost=*[*]*))))][dc=example,dc=com]

Используйте этот фильтр, чтобы выполнить поиск в базе LDAP-каталога напрямую:

admin@dc-1:~$ ldapsearch -x -D "cn=Directory Manager" -W \
 -H ldap://dc-1.ald.company.lan -b dc=ald,dc=company,dc=lan '(objectClass=sudoRole)'

Собеседник (Responder) службы SSSD регистрирует свои события в файле журнала /var/log/sssd/sssd_sudo.log, с помощью которого можно ответить на следующие вопросы:

  • Как много правил было получено от службы SSSD:

[sssd[sudo]] [sudosrv_get_sudorules_from_cache] (0x0400): Returning 4-rules rules for
[user@idm.example.com]
  • Какой фильтр был применен при поиске кэша SSSD:

[sudosrv_get_sudorules_query_cache] (0x0200): Searching sysdb with
[(&(objectClass=sudoRule)(|(sudoUser=ALL)(sudoUser=user)(sudoUser=#10001)(sudoUser=%group
-1)(sudoUser=%user)(sudoUser=+\*)))]

Для поиска извлечения правил из кэша используйте команду ldbsearch из состава пакета ldb-tools:

admin@dc-1:~$ ldbsearch -H /var/lib/sss/db/cache_ald.company.lan.ldb -b cn=sysdb '(&(objectClass=sudoRule))'

Групповые политики

Групповые политики Windows

Первые политики появились в Windows еще в 95-й версии, и создать их можно было с помощью редактора Poledit. Данная операционная система по умолчанию не предоставляла безопасного окружения (пользователи могли входить в систему без паролей, менять многие системные настройки и вообще ни в чем себе не отказывать), поэтому для устранения указанной проблемы и был создан этот дополнительный инструмент.

В дальнейшем технологию политик переняли в NT4, и окончательно она была переосмыслена в Windows 2000 для Active Directory. С тех пор технология поддерживается всеми операционными системами и за прошедшую четверть века нисколько не потеряла своей актуальности.

Локальные политики

Политики бывают локальными и доменными. Локальные политики появились еще в NT 4.0 и представляют собой просто папки с файлами, внутри которых описаны значения параметров:

  • Windows\System32\GroupPolicy\Machine — настройки компьютера;

  • Windows\System32\GroupPolicy\User — настройки пользователя;

  • Windows\System32\GroupPolicyUsers — настройки для конкретных пользователей и групп пользователей, если используются множественные локальные групповые политики (англ. Multiple Local Group Policy Objects, MLGPO). Данный механизм появился с Windows Vista.

Параметры хранятся в файлах Registry.pol (от англ. policy), максимальный размер этого файла c Windows 2012 увеличен до 100МБ, но это с большим запасом, т.к. до этого хватало и 64 Кб. Файлы Registry.pol содержат бинарные данные, но так как в них много строк unicode, в них можно «заглянуть» даже простым блокнотом.

Первые 4 байта (PReg) определяют сигнатуру, а следующие за ними 4 байта определяют версию. Версия увеличивается на единицу при каждом изменении GPO, и это значение необходимо для сверки данных, находящихся в LDAP-каталоге, локальном кэше и общей сетевой папке. После заголовка идет тело документа со значениями параметров, которые представляют собой просто разделы реестра Windows, которые необходимо доставить и установить на клиенте, поэтому файл называется реестром (англ. Registry). Например, это может быть параметр со ссылкой на файл для установки обоев рабочего стола.

Для построения пользовательского интерфейса редактор групповых политик использует так называемые административные шаблоны, которые представляют собой специальные XML-файлы *.admx. Если на компьютере установлены инструменты администрирования групповых политик, то эти файлы будут находиться в папке C:\Windows\PolicyDefinitions\, но для удобства централизованного доступа к административным шаблонам метафайлы можно скопировать в каталог SYSVOL по адресу: \win.company.lan\SYSVOL\win.company.lan\Policies\PolicyDefinitions. В этом случае интерфейс будет открываться чуть дольше, но зато одинаково на всех компьютерах.

Разработчики стороннего программного обеспечения могут создавать свои собственные административные шаблоны групповых политик для использования штатного механизма централизованного конфигурирования через изменение параметров реестра Windows. Например, так поступают разработчики MS Office, Adobe Reader, Google Chrome и др.

За применение групповых политик на серверах и рабочих станциях, начиная с Windows Vista, отвечает отдельная служба «Клиент групповых политик» (от англ.Group Policy Service Client, GPSVC), ранее эту задачу возлагали на WinLogon. Если клиентская служба групповой политики будет остановлена, то настройки применяться не будут, поэтому в целях безопасности права доступа по умолчанию настроены таким образом, что даже администратору запрещено ее останавливать, см. рис. 288. Текущие права доступа вы можете посмотреть командой sc.exe sdshow gpsvc.

../_images/aldpro_mod6_image21.png

рис. 288 Действия по управлению службой Group Policy Client, доступные администратору

Таким образом, локальная политика включает следующие компоненты: шаблон локальной групповой политики со значением параметров и административные шаблоны для их редактирования. Взаимосвязь компонентов показана на рис. рис. 289.

../_images/aldpro_mod6_image22.png

рис. 289 Компоненты локальной политики Windows

Доменные групповые политики

Групповые политики появились в Windows 2000 с выходом Active Directory и представляют собой множество правил для настройки рабочего окружения, которые группируются в так называемые объекты групповой политики (от англ. Group Policy Object, GPO), см. рис. 290.

../_images/aldpro_mod6_image23.png

рис. 290 Объект групповой политики Default Domain Policy

Как можно заметить, параметры представлены в двух секциях: настройки компьютера (англ. Computer Configuration) и настройки пользователя (англ. User Configuration), см. рис. 291.

../_images/aldpro_mod6_image24.png

рис. 291 Параметры пользователя и компьютера

Для локальных политик такое деление может показаться условным, поскольку параметры из обеих секций применяются в любом случае, и нужно только не забывать, что параметры компьютера могут переопределить значения аналогичных параметров из секции пользователя.

В случае доменных групповых политик вы должны понимать, что сотрудник может сесть за компьютер из другого структурного подразделения, и тогда пользователь и компьютер будут попадать в область действия разных GPO. Компьютер сначала отберет все GPO, в область действия которых попадает текущий пользователь, и применит параметры из секции пользователя. Затем он отберет все GPO, в область действия которых попадает текущий компьютер, и применит параметры из секции компьютера.

Каждый объект групповой политики включает в себя два компонента:

  • Контейнер групповой политики (Group Policy Container, GPC) — это запись в LDAP-каталоге, которая определяет имя объекта, версию (порядковый номер изменений), ссылку на шаблон групповой политики gPCFileSysPath на диске и т.д.

    Например, контейнер GPO «Default Domain Policy» в домене win.company.lan можно найти в записи, см. рис. 292:
    CN={31B2F340-...FB984F9},CN=Policies,CN=System,DC=win,DC=company,DC=local

  • Шаблон групповой политики (Group Policy Templates, GPT) — это папка на сетевом диске, в которой хранятся значения параметров по аналогии с папкой GroupPolicy локальных политик. Например, шаблон GPO «Default Domain Policy» в домене win.company.lan можно найти в \win.company.local\SYSVOL\win.company.local\Policies{31B2F340-...FB984F9}, см. рис. 292.

../_images/aldpro_mod6_image25.png

рис. 292 Контейнер групповой политики Default Domain Policy

Примечание

  • Default Domain Policy: {31B2F340-016D-11D2-945F-00C04FB984F9}

  • Default Domain Controller Policy: {6AC1786C-016F-11D2-945F-00C04FB984F9}

../_images/aldpro_mod6_image26.png

рис. 293 Шаблон групповой политики Default Domain Policy

При назначении объекта групповой политики на структурное подразделение в записи LDAP-каталога, соответствующей этому подразделению, создается атрибут gPLink, который является ссылкой на контейнер GPO, см. рис. 294.

Например, в свойствах домена win.company.lan есть gPLink со значением: [LDAP://CN={31B2F340-..B984F9},CN=Policies,CN=System,DC=win,DC=company,DC=lan;0]

../_images/aldpro_mod6_image27.png

рис. 294 Ссылка на контейнер объекта групповой политики Default Domain Policy

Таким образом, доменная групповая политика включает следующие компоненты: контейнер групповой политики, шаблон групповой политики, и административные шаблоны для редактирования параметров. Их взаимосвязь показана на рис. 295.

../_images/aldpro_mod6_image28.png

рис. 295 Компоненты доменной групповой политики Active Directory

Область действия групповых политик, назначенных на домен, сайт или структурное подразделение можно сузить с помощью WMI-фильтров (Windows Management Instrumentation), которые позволяют задать дополнительные условия отбора целевых объектов на SQL-подобном языке WQL (WMI Query Language). Обычно эта технология используется в ситуациях, когда пользователи и компьютеры находятся в общем списке, а не в выделенном подразделении. Этот механизм крайне удобен, если нужно применить политику в зависимости от версии ОС, ее сетевых настроек, наличия определенного установленного ПО и других условий.

Кроме WMI-фильтров область действия политик можно сужать еще и через права доступа. Загрузка параметров, назначенных на компьютер, осуществляется из-под учетной записи компьютера, а загрузка параметров, назначенных на пользователя, соответственно, из-под учетной записи пользователя. Поэтому, если у компьютера/пользователя не будет соответствующих прав на чтение GPO, то служба GPSVC не сможет получить параметры объекта, и они не будут применены в системе. Права доступа назначаются через делегирование с помощью списков доступа (англ. ACL, Access Control List).

Когда мы изменяем права доступа на вкладке делегирования или через фильтры безопасности (англ. security filter), консоль управления выставляет соответствующие ACL в LDAP-каталоге и на сетевом диске. Набор привилегий в каталоге и на диске разный, но это не мешает достигнуть необходимого результата. Администратор может делегировать не только права на чтение, но и права на редактирование GPO, что дает гибкость в вопросах администрирования.

В классической клиент-серверной архитектуре доставка изменений до клиента может быть организована тремя способами:

  • Метод опроса (англ. pull) — это когда клиент периодически опрашивает сервер о наличии каких-либо изменений. Эта модель основана на классическом подходе запрос/ответ (англ. request/response).

  • Метод проталкивания (англ. push) — это когда клиент и сервер меняются местами, и уже сервер связывается с клиентом, чтобы передать ему какие-либо изменения.

    В этом случае сервер должен знать IP-адрес клиента и иметь к нему доступ по сети, что невозможно при размещении клиентов за NAT-шлюзом.

  • Метод длинных опросов (англ. long poll) — это когда клиент подключается к серверу, после чего они продолжают удерживать соединение, чтобы у сервера была возможность оперативно передавать клиенту новые сообщения.

    Эта модель основана на веб-сокетах (англ. WebSocket), и ее используют, например, мессенджеры, такие как Telegram.

Учитывая, что в домене могут быть сотни серверов, а рабочие станции могут длительное время находиться в выключенном состоянии или вообще эксплуатироваться вне офиса, метод опроса видится наиболее экономичным способом доставки изменений до клиента. Поэтому в MS AD ответственность за извлечение информации о групповых политиках из домена возлагается на клиента, а точнее на его службу GPSVC, которая выполняет процедуру опроса с периодичностью один раз в 90 минут.

Однако во избежание большой нагрузки на контроллеры домена в начале рабочего дня, когда все сотрудники приходят в офис и включают свои рабочие станции, первое применение параметров групповой политики сразу после загрузки компьютера выполняется из кэша, а далее служба выбирает себе случайным образом момент времени для обновления параметров.

Информацию об участии пользователя/компьютера в организационной структуре, релевантные объекты групповой политики и их версии компьютер извлекает по LDAP-протоколу. Шаблоны групповой политики, в которых содержатся значения параметров, компьютер извлекает по SMB. Для отладки групповых политик администратор может отправить команду на принудительное обновление параметров групповой политики конкретному компьютеру через консоль GPMC или командлет Invoke-GPUpdate.

../_images/aldpro_mod6_image29.png

рис. 296 Протоколы, используемые технологией групповых политик для доставки информации до клиента

Механизм репликации

Домен AD представляет собой распределенную систему, работу которой могут обеспечивать десятки или даже сотни контроллеров домена. Для согласования изменений между серверами применяются две технологии репликации:

  • Репликация LDAP-каталога – используется для согласования изменений в контейнерах групповых политик. В этом случае применяются протоколы RPC (135/TCP) и SMTP (25/TCP).

  • Репликация папки SYSVOL – используется для согласования изменений в шаблонах групповых политик. В этом случае применяется протокол DFS-R (5722/TCP).

../_images/aldpro_mod6_image30.png

рис. 297 Протоколы, используемые для репликации групповых политик между контроллерами

Вопросы репликации между контроллерами важны для сопровождения ИТ-инфраструктуры, но в контексте групповых политик полезнее рассмотреть более подробно способы доставки групповых политик до клиента.

Механизмы наследования и суммирования параметров

Порядок суммирования параметров групповых политик иногда обозначают аббревиатурой LSDOU, так как сначала применяются локальные политики (L), затем политики сайта (S), домена (D) и в завершение политики организационных подразделений (OU). Таким образом, параметры, назначенные на организационные подразделения, всегда превалируют над параметрами локальных политик.

При назначении GPO на структурное подразделение в область его действия попадают пользователи и компьютеры всех нижестоящих подразделений. На схеме рис. 298 приведен пример, в соответствии с которым целевой компьютер попадает в область действия всех GPO, начиная с ГПО-1 и заканчивая ГПО-8.

../_images/aldpro_mod6_image31.png

рис. 298 Порядок наследования суммирования групповых политик

При этом, чем ближе GPO по иерархии к пользователю/компьютеру, тем позже будут применяться параметры этого объекта, поэтому они смогут переопределить ранее установленные значения. На приведенном ранее примере параметр ГПО-8 сможет переопределить значения, установленные параметром из ГПО-1.

Однако стандартный порядок наследования можно изменить, если поставить в настройках структурного подразделения флаг «Блокировать наследование» (англ. Block Inheritance). Это позволит отменить наследование GPO, назначенных на вышестоящие родительские подразделения. Например, на рисунке рис. 299 показан пример, в соответствии с которым целевой компьютер не попадает в область действия ГПО-1 и ГПО-2, т. к. на OU1 установлен запрет наследования.

../_images/aldpro_mod6_image32.png

рис. 299 Иллюстрация работы блокировки наследования GPO для структурного подразделения

Функция блокировки наследования удобна для отладки, и когда в рамках организационной структуры есть категории пользователей/компьютеров, на которые нужно назначить принципиально иные настройки. Например, в рамках московского офиса у вас может быть открытое пространство с совместно используемыми компьютерами, для которых проще будет задать настройки заново, чем переопределять общие настройки, назначенные в рамках офиса.

Обойти блокировку наследования можно с помощью флажка «Наследовать принудительно» (англ. enforced), который можно установить при назначении GPO на структурное подразделение. Более того, параметры объектов, отмеченных флажком Enforced, суммируются в отдельном цикле после суммирования параметров обычных GPO, поэтому они могут переопределить ранее установленные значения. Например, на рисунке :aldpro_mod6_image33 показан пример, в соответствии с которым целевой компьютер попадает в область действия ГПО-1, несмотря на то, что для OU1 установлен запрет наследования.

../_images/aldpro_mod6_image33.png

рис. 300 Иллюстрация работы флага принудительного наследования

Отладка групповых политик

Служба GPSVC применяет параметры групповых политик, но не отчитывается контроллерам о результатах выполнения, поэтому администратор не располагает сводной информацией о фактическом применении параметров на всех хостах в домене.

Более того, параметры на пользователя имеют значение только в контексте конкретного входа в операционную систему, а доставлять на конкретный компьютер все параметры, определенные для всех категорий пользователей, не только бесполезно, но и еще небезопасно.

Для настройки и отладки групповых политик в домене администратор располагает следующими инструментами:

  • Мастер моделирования групповой политики в GPMC — использует алгоритм службы GPSVC, чтобы спрогнозировать, какие параметры будут применены для конкретного пользователя на конкретном компьютере в заданных условиях (Resultant Set of Policy, RSOP). Отчет выводится в формате HTML-документа.

  • Утилита gpresult.exe — показывает фактический результат применения параметров групповой политики на конкретном компьютере. Результаты можно вывести в формате HTML-отчета.

  • Утилита gpupdate — позволяет форсировать применение параметров групповой политики, чтобы не дожидаться следующей итерации. Довольно часто используется с ключом /force, который позволяет повторно применить все параметры, даже если они не изменились с последнего применения.

Обычно сценарий настройки нового объекта выглядит следующим образом:

  • Администратор создает новый объект групповой политики и назначает его на выделенное подразделение, в котором обычно находится один тестовый компьютер или виртуальная машина.

  • Для проверки настроек администратор многократно выполняет в целевой системе команду gpupdate /force и сверяет полученный результат со своими ожиданиями.

  • После настройки объекта групповой политики администратор назначает его на целевое структурное подразделение.

Такие инструменты, как RSOP и GPResult, используются обычно для отладки, когда нужно понять, почему та или иная настройка фактически не применилась к конкретной категории пользователей или компьютеров.

Групповые политики ALD Pro

Разработчики службы каталога FreeIPA решили сосредоточиться в большей степени на задачах аутентификации и авторизации, поэтому в части политик предлагают ограниченный набор параметров, имеющих прямое отношение к вопросам безопасности.

Реализованы политики FreeIPA очень хорошо, но их ни разу недостаточно. Поэтому команда ALD Pro выполнила интеграцию продукта с системой конфигурирования SaltStack, что позволило обеспечить централизованное управление настройками любых операционных систем и приложений в стиле групповых политик Microsoft.

Локальные политики

В операционной системе ALSE есть очень удобный инструмент для управления локальной политикой безопасности fly-admin-smc, с помощью которого можно управлять локальными пользователями и группами, настроить основные параметры безопасности, мандатного доступа, аудита, отчуждаемых носителей, см. рис. 301.

Вместе с тем, следует понимать, что это приложение не ведет какую-то собственную базу настроек, а считывает информацию непосредственно из конфигурационных файлов системы, поэтому при изменении параметров с помощью сторонних систем конфигурирования у вас не будет возможности вернуть значения по умолчанию.

../_images/aldpro_mod6_image34.png

рис. 301 Управление локальной политикой безопасности ALSE

Система ALD Pro не предлагает какой-либо реализации локальных политик и не резервирует изменяемые конфигурационные файлы, поэтому для возможности вернуться к исходным значениям вы можете включить версионирование всей папки /etc/ с помощью обычного Git или более специализированного приложения etckeeper.

Доменные групповые политики

Групповые политики ALD Pro во многом похожи на групповые политики AD. Перечислим основные особенности:

  • Параметры группируются в объекты групповой политики (GPO). В рамках каждого GPO есть две секции параметров — одна для формирования окружения компьютеров и вторая для окружения пользователей, см. рис. 302.

  • Значения параметров (шаблоны GPO) хранятся в LDAP-каталоге и извлекаются по LDAP-протоколу, то есть обычные файлы и SMB-протокол не используются.

  • За извлечение параметров из LDAP-каталога, их суммирование и применение отвечает служба aldpro-salt-minion (до версии ALD Pro 2.4.0 salt-minion-standalone). Для взаимодействия с каталогом служба использует учетную запись компьютера из файла /etc/krb5.keytab.

  • Для применения параметров на рабочих станциях автономная служба aldpro-salt-minion использует Salt-скрипты, тексты которых хранятся также в LDAP-каталоге.

  • Объекты групповой политики назначаются на организационные подразделения, которые являются собственной доработкой продукта ALD Pro, т.к. в службе каталога FreeIPA этой возможности изначально нет.

  • Назначить GPO на сайт в настоящий момент невозможно. Для назначения GPO на домен используется корневое подразделение организационной структуры.

../_images/aldpro_mod6_image35.png

рис. 302 Параметры компьютеров объекта групповой политики ALD Pro

В основе механизма групповых политик ALD Pro лежит Salt — система управления конфигурациями и удаленного выполнения операций с открытым исходным кодом, написанная на языке Python. Система работает по модели «издатель — подписчик», см. рис. 303, поэтому базовыми компонентами архитектуры являются:

  • Мастер (издатель) — это сервер, выполняющий централизованное управление рабочими станциями.

  • Миньоны (подписчики) — это рабочие станции или серверы, выступающие в качестве клиентов по отношению к Мастеру и принимающие от Мастера команды на удаленное конфигурирование.

  • Шина данных — это система для передачи сообщений на базе ZeroMQ.

    Шина работает на Мастере и реализует модель длинных опросов (англ. long poll). Миньоны устанавливают с Шиной постоянное соединение по порту 4505/TCP (порт издателя, publisher) для получения заданий на конфигурирование от Мастера.

    Кроме постоянного соединения Миньоны периодически подключаются к Шине по порту 4506/TCP (порт сервера запросов, request server) для загрузки необходимых файлов и отправки отчетов о выполнении заданий.

../_images/aldpro_mod6_image36.png

рис. 303 Классическая архитектура Salt

Работа групповых политик в ALD Pro до версии 2.2.0

В продукте ALD Pro до версии 2.2.0 групповые политики использовали классическую архитектуру Salt: служба Salt-Minion рабочей станции подключалась к Salt-Master на контроллере домена, забирала справочник Pillar с результирующим набором параметров, загружала все необходимые salt-скрипты и применяла указанные параметры.

Описанная архитектура отлично подходит для управления инфраструктурой на сотни виртуальных машин с высокой сетевой связанностью, что подтверждается успешным использованием Salt в облаке LinkedIn (самое крупное внедрение продукта). Успешно применяют Salt и российские облачные провайдеры. Однако при использовании классического подхода Salt по управлению тысячами рабочих станций мы сталкиваемся с рядом сложностей:

  • Суммирование параметров групповых политик на стороне сервера для построения результирующего набора параметров требует слишком много ресурсов.

  • Аутентификация по ключу, которую использует Salt для установления соединения, требует ощутимо больше ресурсов. Это очень заметно в первые минуты после перезапуска службы Salt-Master.

  • Удержание нескольких тысяч сетевых соединений по модели long poll требует слишком много ресурсов.

Работа групповых политик в ALD Pro с версии 2.2.0

Для того чтобы достичь показателя в 10к рабочих станций на один контроллер домена, в части групповых политик мы отказались от использования Мастера и перешли к модели Standalone Minion. Весь программный код, отвечающий за наследование и суммирование параметров групповых политик, выполняется на стороне клиента, а к контроллеру он ходит только за обновлением данных, см. рис. 304.

Работа групповых политик в ALD Pro с версии 2.4.0

Кардинальных изменений работы ГП в версии 2.4.0 не произошло. Перечислим некоторые значимые моменты:

  • Появилась возможности влиять на порядок наследования через установку таких флажков, как «Блокировать наследование» (англ. Block Inheritance) и «Наследовать принудительно» (англ. Enforced).

  • Упрошен синтаксис команд cli для форсирования применения политик и получения настроек результирующей политики (pillar).

  • Переработаны скрипты коробочных параметров, повышена стабильность их работы.

  • При изменении доп. параметра групповой политики, новые настройки применяются к клиентам автоматически (версия всех политик в которых используется такой доп. параметр инкриментируется).

../_images/aldpro_mod6_image37.png

рис. 304 Компоненты доменной групповой политики ALD Pro

Скрипты групповых политик находятся в каталоге /srv/aldpro-salt/roots/states/policies/ (до версии 2.4 в каталоге /srv/salt/standalone/roots/states/policies/). В случае коробочных параметров они доставляются через установку и обновление deb-пакетов программного продукта, а в случае дополнительных параметров загружаются через LDAP.

admin@dc-1:~$ sudo tree -L 2 /srv/aldpro-salt/roots/states/policies/
/srv/aldpro-salt/roots/states/policies/
├── audit-policies
│   ├── files
│   └── init.sls
├── host-policies
│   ├── init.sls
│   ├── rbta_ldap_auth_fast
│   ├── rbta_ldap_crontab
│   ├── rbta_ldap_date_time_h
│   ...
│   ├── rbta_ldap_printers
│   ├── rbta_ldap_quotas
│   ├── rbta_ldap_security_policy
│   └── rbta_ldap_system_alternatives
├── sw-policies
│   ├── init.sls
│   └── README.md
├── update-policy.sls
└── user-policies
   ├── init.sls
   ├── rbta_ldap_autostart
   ├── rbta_ldap_date_time_u
   ...
   ├── rbta_ldap_power_management
   ├── rbta_ldap_quick_launch
   ├── rbta_ldap_start_menu
   └── rbta_ldap_windows_settings

Механизм групповых политик ALD Pro заимствует из MS AD также несколько очевидных способов повышения производительности:

  • Служба aldpro-salt-minion не обращается к контроллеру сразу после включения, а выбирает случайным образом момент времени в окне продолжительностью в один час, чтобы не создавать пиковую нагрузку в начале рабочего дня.

  • Параметры групповых политик извлекаются из LDAP-каталога только в том случае, если версия в локальном кэше не совпадает с версией GPO из каталога.

Механизм репликации

Информация по групповым политикам ALD Pro находится в LDAP-каталоге, поэтому реплицируется между контроллерами домена в штатном порядке в рамках установленной топологии.

Мы отказались от использования файлов, т.к. производительность современных серверов позволяет передавать всю необходимую информацию по LDAP-протоколу. Довольно долгое время файлы Registry.pol были не больше 64Кб, а записи размером до 100Кб хранить в каталоге считалось допустимым даже 20 лет назад.

Механизмы наследования и суммирования параметров

В части наследования и суммирования параметров система ALD Pro заимствует подходы, которые применяются в MS AD:

  • Простые параметры суммируются так же, как обычные параметры групповых политик AD, поэтому, чем ближе будет GPO по иерархии к пользователю/компьютеру, тем позже будут применяться параметры этого объекта, поэтому они смогут переопределить ранее установленные значения.

  • Составные параметры суммируются так же, как Предпочтения групповых политик (Group Policy Preferences), поэтому salt-скрипт через pillar получает таблицу атрибутов, где каждая строка соответствует набору атрибутов данного параметра из отдельно взятого объекта групповой политики. Скрипт должен будет самостоятельно удалить дубликаты строк, руководствуясь бизнес-логикой параметра групповой политики.

  • С версии 2.4 появилась возможность влиять на порядок наследования через установку таких флажков, как «Блокировать наследование» (англ. Block Inheritance) и «Наследовать принудительно» (англ. Enforced).

Однако есть некоторые отличия:

  • В соответствии с порядком наследования LSDOU в системе ALD Pro в настоящий момент можно назначать GPO только на домен и организационные подразделения, причем под доменом подразумевается корневое подразделение в иерархии. Локальных политик нет, и назначить GPO на сайт пока не представляется возможным.

  • Групповые политики ALD Pro не поддерживают технологии WMI-фильтров и не позволяют назначать права доступа на отдельные GPO, поэтому в настоящий момент сузить область действия GPO не представляется возможным.

Настройка групповой политики

Давайте с помощью групповых политик запретим локальным пользователям вход в систему.

В домене MS AD для управления паролями локальных пользователей используется специальное решение LAPS (Local Administrator Password Solution), а для ALD Pro его планируется разработать в 2025 году, поэтому, пока оно недоступно, заблокировать локальным пользователям вход будет намного проще, чем следить за их паролями вручную.

  1. Перейдем на страницу и создадим новый объект групповой политики, нажав соответствующую кнопку.

../_images/aldpro_mod6_image38.png

рис. 305 Страница «Групповые политики»

  1. До первого сохранения объекта нам доступна только вкладка Основное, где требуется задать имя объекта и описание. Введем следующие значения:

  • Имя: Блокировка локальных учетных записей

  • Описание: Политика запрещает локальным пользователям вход в систему

  • И нажмем кнопку

    ../_images/aldpro_mod6_image39.png

    рис. 306 Создание новой групповой политики

Теперь нам доступны для редактирования остальные вкладки:

  • Конфигурация политики – отображает список параметров, которые задействованы в этом объекте групповой политики. Вы можете удалить параметр или быстро перейти к его редактированию.

  • Параметры компьютеров – содержит параметры для настройки окружения компьютера.

  • Параметры пользователей – параметры для настройки окружения пользователя.

  • Подразделения – содержит список подразделений, на которые назначен объект групповой политики. На этой вкладке вы можете удалить назначение или назначить объект на дополнительные подразделения.

  1. На вкладке включим параметр из списка , установим значение «no», установим во «Включено» и нажмем кнопку

../_images/aldpro_mod6_image40.png

рис. 307 Настройка параметров компьютеров групповой политики

Примечание

Подробную справку о параметре групповой политики можно получить, если кликнуть по значку с символом вопроса, который расположен в правом верхнем углу карточки. Как вы можете заметить, значение «no» означает, что вход будет запрещен для всех категорий локальных пользователей, в том числе и по ssh.

../_images/aldpro_mod6_image41.png

рис. 308 Справка настроек параметров компьютеров групповой политики

Примечание

Чтобы закрыть справку и вернуться к форме редактирования, сделайте клик по значку в форме крестика, который расположен в правом верхнем углу карточки.

  1. Перейдем на вкладку и создадим новое назначение кнопкой .

    ../_images/aldpro_mod6_image42.png

    рис. 309 Назначение групповой политики на подразделение

    Так как мы хотим применить объект групповой политики на весь домен, то выберем корневое подразделение «ald.company.lan» и нажмем кнопку .

    Обратите внимание на поле «Приоритет групповой политики». Это значение позволяет определить порядок применения параметров, если на одно и тоже организационное подразделение назначено несколько объектов групповой политики.

    ../_images/aldpro_mod6_image43.png

    рис. 310 Выбор подразделения для групповой политики

  2. Файлы, которые используются для применения этого параметра, находятся в каталоге /srv/aldpro-salt/roots/states/policies/host-policies/rbta_ldap_security_policy.

    Скрипт init.sls заменяет содержимое файла /etc/parsec/parsec.conf шаблоном из файла local_login_policy/parsec.conf.j2, подставляя значение переменной login_policy.

    Чтобы не ждать обновления параметров, забежим немного вперед и выполним на компьютере следующие команды:

admin@dc-1:~$ sudo aldpro-gpupdate --gp
admin@dc-1:~$ cat /etc/parsec/parsec.conf
  1. Если мы теперь попытаемся выполнить вход в систему локальным администратором, то получим ошибку от системы Parsec.

    ../_images/aldpro_mod6_image44.png

    рис. 311 Предупреждение при входе в систему

    Если вы захотите вернуть как было, то нужно установить параметр all, обновить параметры политики и перезагрузить хост.

Механизм определения пользовательских сессий

Предлагаем немного подробнее рассмотреть реализацию механизма определения активных пользовательских сессий в ALD Pro при применении политики параметров пользователя. Обратите внимание, что параметры пользователя применяются в цикле индивидуально по отношению к каждой учетной записи, с помощью которой был выполнен интерактивный вход в операционную систему. Для операционных систем 1.8_x86-64 список сессий извлекается через интерфейс dbus (org.freedesktop.login1), а для всех остальных ОС с помощью классической утилиты users (см. модули aldpro_user.py и dbus.py).

Система не учитывает вход из-под sudo su, но не ограничивается только графическими сессиями, поэтому, если вам потребуется обогатить данные pillar параметрами другого пользователя, вы можете выполнить вход с помощью простой утилиты login:

admin@pc-1:~$ sudo login testuser

Давайте рассмотрим механизм определения сессий по шагам:

  1. Пользователь подключается к рабочей станции: графическое подключения Fly или консольное подключение Login.

  2. Запускаются модули PAM в зависимости от выбранного метода подключения: fly-dm (/etc/pam.d/fly-dm) или login (/etc/pam.d/login).

  3. Выше упомянутые PAM модули вызывают PAM модуль Session (/etc/pam.d/common-session). В нем содержится опция запуска внешнего скрипта salt-masterless-login:

    session optional pam_exec.so /usr/sbin/salt-masterless-login
    

PAM модуль передает переменную PAM_USER данному Python скрипту, который отделяет доменного пользователя от локального, сравнивая его с /etc/passwd. В случае, если пользователь доменный, то будет запущена следующая команда:

aldpro-salt-call \
--local \
-m \
/srv/aldpro-salt/roots/_modules/ \
state.single \
module.run \
aldpro_user.store_domain_user \
-c \
/srv/aldpro-salt/config \
queue=True

Примечание

В ванильной версии Salt для выполнения salt-функций на миньоне предназначена утилита salt-call. В продукте ALD Pro мы упаковываем salt-клиент в отдельное python окружение, поэтому для взаимодействия с нашей автономной службой aldpro-salt-minion вам следует использовать утилиту aldpro-salt-call.

  1. Команда, запущенная в предыдущем шаге вызывает функцию store_domain_user из модуля /srv/aldpro-salt/roots/_modules/aldpro_user.py, по окончанию работы которой, у нас формируется файл со списком пользовательских сессий /opt/rbta/aldpro-salt/minion/gp-user_sessions.json

    cat /opt/rbta/aldpro-salt/minion/gp-user_sessions.json
    {"admin": {"last_active": "2025-03-19 14:33:15.275652"}}
    

Файл gp-user_sessions.json регулярно очищается с помощью функции purge_inactive_sessions. Она удаляет все сессии, которые были неактивны последние 20 дней. Запускается раз в день. Посмотреть следующий запуск можно:

aldpro-salt-call schedule.show_next_fire_time purge_inactive_sessions
  1. На последнем этапе запускается модуль gp_sum.py (/srv/aldpro-salt/roots/_modules/gp_sum.py). Функция build_gp_pillars из модуля gp_sum.py с помощью dbus определяет все текущие сессии, далее сравнивает их со списком gp-user_sessions.json и в случае совпадения строит pillar для этого пользователя.

На рис. 312 представлены описанные шаги в виде схемы для удобства восприятия.

../_images/aldpro_mod6_image58.png

рис. 312 Механизм определения пользовательских сессий

Отладка групповых политик

Служба aldpro-salt-minion применяет параметры групповых политик по расписанию. Сразу после загрузки компьютера служба запускает отложенное задание, таймаут которого складывается из двух значений:

  • Постоянная часть в 30 минут — определяет минимальный интервал между последующими обновлениями параметров групповых политик.

  • Случайный разброс до 50 минут — позволяет снизить пиковую нагрузку в начале дня, когда все сотрудники разом включают свои компьютеры.

Таким образом, компьютер должен гарантированно обновить параметры групповых политик в течение 80 минут после загрузки. Приблизительное время очередного обновления по расписанию вы можете узнать командой:

admin@pc-1:~$ sudo aldpro-gpupdate --gp_timer
Таймер заданий ГП
local:
   ----------
   next_fire_time:
       2025-03-24T14:43:09
   result:
       True

Вывод этой команды учитывает только постоянную составляющую таймера next_fire_time, поэтому возможна ситуация, когда указанное время уже истекло, но применение политик еще не состоялось. Фактически команда будет запущена в момент времени splay, значение которого можно узнать с помощью функции schedule.job_status:

admin@pc-1:~$ sudo aldpro-salt-call schedule.job_status build_and_run_gp
local:
 ----------
 _last_run:
     2025-03-24T14:13:09
 _next_fire_time:
     2025-03-24T14:43:09
 _next_scheduled_fire_time:
     2025-03-24T11:06:27
 _seconds:
     1800
 _splay:
     2025-03-24T14:53:30
 args:
 enabled:
     True
 function:
     gp_sum.build_and_run_gp
 jid_include:
     True
 kwargs:
     ----------
 maxrunning:
     1
 minutes:
     30
 name:
     build_and_run_gp
 return_job:
     False
 run:
     True
 run_on_start:
     False
 splay:
     ----------
     end:
         3000
     start:
         300

Для выполнения отладки новых объектов групповых политик вы можете запускать принудительное обновление параметров командой:

admin@pc-1:~$ sudo aldpro-gpupdate --gp --verbose

Где:

  • –gp – форсированное применение групповых политик с очисткой кэша и формированием нового набора параметров результирующей политики (pillar).

  • –verbose – детальный вывод результата выполняемой команды.

Фактически «под капотом» при этом происходит вызов команды:

admin@pc-1:~$ aldpro-salt-call gp_sum.build_and_run_gp force=True verbose=True

Вызов этой команды дает тот же результат, что и gpupdate /force в Windows.

После форсированного применения всех параметров на рабочей станции будет сформирован pillar и загружены все необходимые sls-скрипты, поэтому у вас появится возможность форсировать применение отдельного параметра без полной очистки кэша.
Форсированное применение отдельных параметров существенно ускоряет написание скриптов дополнительных параметров, т.к. позволяет вносить изменения не через LDAP каталог, а напрямую в локальные копии init.sls из соответствующих папок в директории /srv/aldpro-salt/roots/states/policies/host-policies/

Для отладки конкретного параметра компьютера используйте функцию state.apply, которой нужно передать имя скрипта из каталога /srv/aldpro-salt/roots/states/policies/host-policies:

$ sudo aldpro-salt-call state.apply <имя_скрипта> force=True verbose=True

Например, чтобы принудительно обновить параметр «Настройки сервиса сетевого времени Chrony», за который отвечает salt-скрипт из каталога rbta_ldap_date_time_h, требуется выполнить следующую команду:

$ sudo aldpro-salt-call state.apply rbta_ldap_date_time_h force=True verbose=True
...
[INFO    ] Completed state [/etc/chrony/chrony.conf] at time 07:59:15.835203
(duration_in_ms=1.932)
...

И не забывайте про ключ --log-level, с помощью которого можно выбрать желаемый уровень детализации: all, garbage, trace, debug, profile, info, warning, error, critical, quiet (по умолчанию warning).

$ sudo aldpro-salt-call --log-level=debug state.apply rbta_ldap_date_time_h

Чтобы форсировать применение параметра пользователя, вам потребуется добавить в pillar дополнительный ключ user с идентификатором того пользователя, для которого вы хотите применить этот параметр. Напомним, что каталог с политиками пользователей находится здесь /srv/aldpro-salt/roots/states/policies/user-policies. Например, если параметр с идентификатором rbta_ldap_env_vars_u нужно применить для пользователя admin, то команда будет выглядеть следующим образом:

sudo aldpro-salt-call state.apply rbta_ldap_env_vars_u pillar="{'user':'admin'}"

Примечание

Команда выше применит параметры указанному пользователю только в том случае, если pillar сформирован с участием пользователя. Например, вы создали групповую политику, назначили на нужное подразделение, но при этом служба aldpro-salt-minion его еще не применила, то команда не отработает, так как pillar не содержит информацию для пользователя. Для ускорения процесса обновления pillar можно форсировать применение политик с помощью команды aldpro-gpupdate.

Для вывода параметров результирующей политики компьютера применяется команда:

admin@pc-1:~$ sudo aldpro-gpupdate --gp_host_pillar
Просмотр pillar ГПO компьютера
local:
   ----------

Так как эту команду мы запустили на компьютере pc-1.ald.company.lan, то под капотом была
вызвана функция pillar.get следующим образом:

aldpro-salt-call pillar.get aldpro-hosts:pc-1.ald.company.lan

Точно такая же команда есть для просмотра данных pillar для конкретного пользователя:

aldpro-gpupdate --gp_user_pillar admin

Под капотом эта команда вызывает функцию pillar.get следующим образом:

aldpro-salt-call pillar.get aldpro-users:admin

Разработка дополнительных параметров

Создание дополнительного параметра

Для того чтобы в домене можно было организовать централизованное управление корпоративными приложениями, в системе ALD Pro реализована возможность создания дополнительных параметров групповых политик, которые решают ту же задачу, что и административные шаблоны Windows.

Давайте создадим дополнительный параметр групповых политик, с помощью которого можно будет централизованно управлять источниками программного обеспечения для пакетного менеджера apt.

Чтобы создать дополнительный параметр, нужно перейти на страницу
. Вы можете выбрать вкладку или в зависимости от того, хотите ли вы создать параметр для настройки окружения пользователя или компьютера. Будьте внимательны, т.к. перенести параметр из одного раздела в другой после его создания не получится.

На вкладке кликнем по узлу и нажмем кнопку

../_images/aldpro_mod6_image45.png

рис. 313 Доп. параметры групповых политик

До первого сохранения параметра нам будет доступна только вкладка . Заполним ее параметры:

  • Название параметра: Источники программного обеспечения

    Это имя параметра, под которым вы его хотите видеть при редактировании объектов групповых политик на портале управления.

  • Уникальный идентификатор: repo_source_list

    а полный его идентификатор rbta_ldap_custom_gp_host_repo_source_list, который будет использоваться в качестве имени папки на диске и в salt-скриптах.

  • Тип каталога: Параметр компьютерной групповой политики

    Определяет, относится ли данный параметр к настройкам компьютера или пользователя. Параметр недоступен для редактирования, его значение определяется автоматически в зависимости от того, с какой страницы вы перешли к созданию дополнительного параметра.

  • Тип параметра: Составной параметр

    Он позволяет указать способ хранения атрибутов:

    • Простой параметр — задает плоский список атрибутов. Например, для настройки межсетевого экрана может потребоваться задать уровень детализации журнала, и эта настройка подразумевает одно конкретное значение, поэтому она может быть реализована атрибутом «простого» параметра.

    • Составной параметр — задает таблицу атрибутов, где в каждой строке представлен типовой набор данных. Если продолжать пример с межсетевым экраном, то для настройки фильтрации может потребоваться разрешить входящие ssh-соединения, запретить исходящие smtp и т.п., поэтому такие настройки нужно реализовывать атрибутами «составного» параметра.

  • Папка параметра: Дополнительные параметры

    Указывает раздел каталога, в котором будет представлен этот параметр.

  • Назначение параметра (нужно вставить весь текст целиком):

Позволяет централизованно настраивать источники программного
обеспечения пакетного менеджера apt путем изменения
содержания файла /etc/apt/sources.list.d/repo_source.list

Атрибут "Источник" определяет строку в формате source.list:

deb <адрес_репозитория> <код_дистрибутива> <компонент1> <компонентN>

Где:

- deb - указывает на то, что репозиторий соответствует репозиторию бинарных файлов с предварительно скомпилированными пакетами. Для репозиториев с исходными кодами используют «deb-src».

- адрес репозитория - задает источник пакетов, у интернет-репозиториев адрес начинается с «http(s)://», адреса локальных репозиториев начинаются с «file:/». При добавлении репозитория с диска командой apt-cdrom add в файле появится строка «cdrom:[]/».

- код дистрибутива - дополняет адрес, уточняя необходимый релиз продукта, так как в одном репозитории могут находиться пакеты сразу для нескольких релизов.

- компонент - это группа пакетов, объединенная по условиям использования.

Условия использования компонентов следующие:

 - non-free - группа содержит пакеты, которые не соответствуют принципам свободного ПО, имеют патенты или другие юридические ограничения;

 - contrib - группа содержит пакеты, которые сами по себе соответствуют принципам свободного ПО, но зависят от пакетов из группы «non-free», т.е. не могут без них работать;

 - main - группа содержит пакеты свободного ПО, которые не зависят от пакетов из групп «contrib» и «non-free».
  • Обязательно нажмите кнопку .

На вкладке атрибутов нам нужно добавить один элемент:

  • Название атрибута: «Источник» Название, под которым вы хотите видеть этот атрибут на карточке параметра.

  • Уникальный идентификатор: «repo_source_item» Идентификатор атрибута, под которым значение атрибута будет доступно в пилларе для его использования из salt-скрипта.

  • Описание: «Строка источника для apt» Краткие комментарии, которые помогут упростить поддержку этого атрибута в будущем, когда потребуется внести какие-либо изменения. Данная информация недоступна при настройке групповой политики, поэтому, если вы хотите дать подсказку администратору о возможных значениях этого атрибута, внесите эту информацию в описание параметра.

Осталось только написать скрипт параметра, с помощью которого его значения будут применяться на рабочих станциях.

Скрипты Salt похожи на PHP, в них текст перемежается императивными инструкциями языка программирования, по результату выполнения которых получается итоговый документ. За императивную часть отвечают инструкции шаблонизатора Jinja2, а декларативная часть задается по правилам Salt в YAML-подобном синтаксисе.

Далее мы подробно ознакомимся с синтаксисом Jinja, а пока просто перенесем текст скрипта:

{% set id = 'rbta_ldap_custom_gp_host_repo_source_list' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% set filename = '/etc/apt/sources.list.d/repo_source.list' %}
{% set lines = [] %}

{% if gpo %}
    {%- for item in gpo %}
        {%- if item.repo_source_item.lower() != 'none' %}
            {%- do lines.append(item.repo_source_item) %}
        {%- endif %}
    {%- endfor %}
{% endif %}

{{ id }}:
    {%- if lines|length == 0 %}
        file.absent:
            - name: {{ filename }}
    {%- else %}
        file.managed:
            - name: {{ filename }}
            - user: root
            - group: root
            - mode: 644
            - contents:
            {%- for line in lines %}
                - {{ line }}
            {%- endfor %}
    {%- endif %}

Данный скрипт создает файл /etc/apt/sources.list.d/repo_source.list, настраивает права доступа и вносит в него указанные источники программного обеспечения.

Теперь вы можете создать объект групповой политики и с помощью этого параметра централизованно настраивать источники программного обеспечения.

Синтаксис скриптов

Императивные инструкции шаблонизатора Jinja
Скрипт «Hello world»

Создайте файл test.sls с простейшим Jinja-скриптом, чтобы проверить, как это работает:

$ mkdir ~/test_salt && cd ~/test_salt
$ echo '{% do salt.log.info("Hello world!") %}' > hello.sls

Где:

  • {% %} — синтаксис для вставки инструкции языка шаблонизатора Jinja;

  • do — оператор, который вызывает указанную функцию;

  • salt.log.info — имя вызываемой функции;

  • ("Hello world!") — параметр, передаваемый в функцию.

Выполните его с помощью утилиты aldpro-salt-call:

sudo aldpro-salt-call --local --file-root=. state.sls hello

Где:

  • aldpro-salt-call — утилита, которая используется для локального запуска функций Salt на Миньоне без участия Мастера;

  • ключ --local — исключает обращение к мастеру для получения настроек;

  • ключ --file-root — устанавливает текущую директорию «.» в качестве рабочего каталога;

  • параметр state.sls — указывает, что нужно вызывать функцию sls из модуля state;

  • параметр hello — задает имя скрипта (без расширения).

Результат вывода должен быть таким:

admin@dc-1:~/test_salt$ sudo aldpro-salt-call --local --file-root=. state.sls hello
[INFO    ] Loading fresh modules for state activity
[INFO    ] Fetching file from saltenv 'base', \*\* done \*\* 'hello.sls'
[INFO    ]  Hello world!
local:

Summary for local
-----------
Succeeded: 0
Failed: 0
-----------
Total states run:      0
Total run time:    0.000 ms

Максимально подробную информацию о выполнении команды можно получить в режиме
отладки. Для этого нужно добавить ключ --log-level=debug:

sudo aldpro-salt-call --log-level=debug --local --file-root=. state.sls hello

Чтобы вызвать salt-функцию из jinja-инструкций, нужно воспользоваться оператором do и
обращаться к модулю log через встроенный объект salt. Для выполнения salt-скрипта из
текстовой строки воспользуемся функцией template_str из модуля state:

admin@dc-1:~$ sudo aldpro-salt-call state.template_str '{% do salt.log.info("Привет, мир!") %}'
...
[INFO    ] Привет, мир!
...
Разметка Jinja

Инструкции языка Jinja внедряются с помощью фигурных скобок, см. табл. 23:

табл. 23 Выбор политики в зависимости от приоритета

Jinja

Аналог PHP

Комментарий

{% %}

<? ?>

Синтаксис для вставки инструкции языка шаблонизатора Jinja

{% print(…) %}

<? echo (…) ?>

Пример инструкции для вывода в документ по месту вызова значения выражения

{{ }}

<?= ?>

Краткий синтаксис для вывода в документ по месту вызова значения выражения

{# #}

<?/* */?>

Синтаксис для вставки комментариев средствами языка Jinja2

Для повышения читабельности кода управляющие структуры обычно оформляют отступами, но yaml-документы крайне чувствительны к пробелам, поэтому данный инструмент форматирования оказывается недоступен без применения специальных операторов подавления отступов, см. табл. 24. Чтобы убрать лишние пробелы и пустые строки вам нужно всего лишь поставить знак дефиса слева, справа или с обоих концов управляющего блока:

табл. 24 Специальные операторы подавления отступов

Jinja

Комментарий

{%-

Удаляет пробелы и пустые строки слева

-%}

Удаляет перенос текущей строки и переносит ее на предыдущую

{%- и -%}

Удаляет пробелы и пустые строки слева, в том числе перенос текущей строки, поэтому текст окажется в конце предыдущей строки

Работа с переменными

Переменные на языке Jinja задаются оператором set. Вам доступен широкий перечень типов данных: булевы, числовые, текстовые, списки, кортежи, словари:

{% set boolean_val = True %}
{% set int_val = 777 %}
{% set string_val = 'hello' %}
{% set list_val = ['h', 'e', 'l', 'l', 'o'] %}
{% set tuple_val = ('h', 'e', 'l', 'l', 'o') %}
{% set dict_val = {'b': True, 'i': 777, 's': 'hello'} %}

При работе с числовыми переменными доступны обычные математические операторы:

{% set a = 5 %}
{% set b = 10 %}
{% set a = a + b %}
{% set b = a - b %}
{% set a = a - b %}

Конкатенация строк возможна как специальным оператором «~», который предварительно конвертирует все значения в строки, так и обычным оператором сложения «+»:

{% set a = 5 %}
{% set b = 10 %}
{% set c = a ~ b %}
{% set d = 'World' %}
{% set e = 'Hello, ' + d %}

Для выполнения более сложных преобразований над переменными вам доступно множество функций, которые можно применять как методы через точку или в стиле конвейеров bash через символ вертикальной черты, за что их также называют фильтрами:

{% set a = 'Hello'.upper() %}
{% set b = 'world' | upper %}
Работа со строками

Строки являются объектами типа str, поэтому вам доступны все методы этого класса docs.python.org

Более того, вы можете работать со строками, как со списками, обращаясь к символам по их индексам:

admin@dc-1:~$ sudo aldpro-salt-call state.template_str '{% do salt.log.info("Привет, большой мир!"[0] ) %}'
...
[INFO    ] П
...

В квадратных скобках можно указывать три значения: индекс первого символа (включительно), индекс последнего символа (невключительно) и шаг, который позволяет включать в подстроку не все символы подряд, как по умолчанию (когда шаг=1), а,
например, только каждый второй (если шаг=2). Индекс можно задавать с конца строки, в этом случае нужно использовать отрицательные значения. Шаг может тоже иметь отрицательное значение, тогда символы в строке будут идти в обратном порядке. В качестве индекса можно подставлять результаты поиска подстроки с помощью функции find().

Приведем более сложные примеры работы со строками:

# Переменной "s" присвоена ссылка на строку текста
{% set s = "Привет, большой мир!" %}
# Переменной "f" присвоено значение "П"
{% set f = s[0] %}
# Переменной "f" присвоено значение "большой" с 8-го по 16-й символы
{% set f = s[8:16] %}
# Переменной "f" присвоено значение ", большой ", что соответствует фрагменту между указанными словами
{% set f = s[s.find("Привет")+6:s.find("мир")] %}
# Переменной "f" присвоено значение "Привет" с 0-го по 6-й символы
{% set f = s[:6] %}
# Переменной "f" присвоено значение "!", которое соответствует первому символу с конца
{% set f = s[-1] %}
# Переменной "f" присвоено значение исходной строки с обратнымпорядком символов
{% set f = s[::-1] %}
Работа со списками

Для работы с массивами предназначен тип данных list. Списки можно определить с помощью квадратных скобок, причем нумерация элементов будет начинаться с нуля. В работе со списками можно использовать те же приемы, что и в работе со строками:

# Присваиваем переменной "a" ссылку на список из трех элементов
{% set a = ["раз", "два", "три"] %}
# Присваиваем переменной "s" значение первого элемента с индексом 0, т.е. "раз"
{% set s = a[0] %}
# Присваиваем переменной "a2" ссылку на список из первых двух элементов исходного списка, т.е. ["раз", "два"]
{% set a2 = a[0:2] %}
# Присваиваем переменной "a2" ссылку на список из трех элементов исходного списка в обратном порядке
{% set a2 = a[::-1] %}

Чтобы узнать количество элементов в списке, можно воспользоваться фильтрами count или length. Добавить элемент в конец списка можно с помощью метода append(). Если нужно добавить элемент в конкретную позицию списка, используйте метод insert(). Удалить элемент по индексу можно методом pop(), а по значению — методом remove(). В программном коде Python можно заменять значение элемента напрямую по индексу (например, c[1]=»two»), но в Jinja это не работает, поэтому приходится использовать связку методов pop() и insert().

# Присваиваем переменной "a" ссылку на список из трех элементов
{% set a = ["раз", "два", "три"] %}
# Присваиваем переменной "c" значение, равное количеству элементов в списке "a"
{% set c = a | count }
# Добавляем в список "a" еще один элемент
{% do a.append("четыре") %}
# Добавляем в список "a" еще два элемента
{% do a.extend(["пять", "я иду искать"]) %}
# Присваиваем переменной "b" ссылку на список из двух элементов
{% set b = ["кто не спрятался", "я не виноват"] %}
# Присваиваем переменной "c" ссылку на новый список, состоящий из элементов массивов "a" и "b"
{% set c = a + b %}
# Удаляем из списка "c" элемент c индексом 1, под которым сейчас находится значение "два"
{% do c.pop(1) %}
# Вставляем в список "c" новый элемент "two" под индексом 1
{% do c.insert(1, "two") %}
# Удаляем из списка "c" элемент с значением "я иду искать"
{% do c.remove("я иду искать") %}

Полный перечень методов см. docs.python.org

Есть так же еще один способ замены элемента с помощью связки фильтров map и replace, но данный способ следует использовать с осторожностью, понимая его ограничения.

{% set a = ["раз", "два", "три"] %}
{% set a = a | map("replace", "три", "иду искать") | list %}
Работа со словарями

Для работы с ассоциативными массивами, у которых есть ключ и значение, предназначен тип данных dict. Словари можно определить с помощью фигурных скобок, доступ к объектам словаря выполняется не по индексу, а по имени ключа, которое можно указывать в квадратных скобках, через точку как свойство объекта, в качестве параметра безопасной функции get.

# Переменной "user" присвоена ссылка на словарь
{% set user = {"login": "localadmin", "uid": 1000, "gid": 1000} %}
# Переменной "login" присвоено значение ключа "login" из словаря "user", т.е. "localadmin"
{% set login = user["login"] %}
# Переменной "uid" присвоено значение ключа "uid" из словаря "user", т.е. 1000
{% set uid = user.uid %}
# Безопаснее всего использовать метод get, который позволяет определить так же значение по умолчанию
{% set gid = user.get("uid", -1) %}

Узнать количество элементов в списке, можно с помощью фильтров count или length. Чтобы получить список всех ключей, можно воспользоваться методом keys(), чтобы получить список значений — методом values().

# Переменной "user" присвоена ссылка на словарь
{% set user = {"login": "admin", "uid": 1000, "gid": 1000} %}
# Присваиваем переменной "c"  значение, равное количеству элементов в словаре "user"
{% set c = user | count %}
# Присваиваем переменной "k" ссылку на объект dict_keys, который содержит список всех ключей словаря
{% set k = user.keys() %}
# Присваиваем переменной "v" ссылку на объект dict_values, который содержит список всех значений словаря
{% set v = user.values() %}
# Присваиваем переменной "i" ссылку на объект dict_items, который содержит список кортежей из ключей словаря
{% set i = user.items() %}
# Обновляем в словаре "a" значение ключа "uid", присваиваем ему значение 500
{% do a.update({"uid":500}) %}
Ветвления и циклы

Если выполнение набора команд должно зависеть от некоторого условия, то ветвление можно задать с помощью операторов if/elif/else/endif:

{% if ram >= 2048 %}
  {% set ram_requirement_success = True %}
{% else %}
  {% set ram_requirement_success = False %}
{% endif %}

Для упрощения кода условные конструкции записывать в одну jinja-инструкцию (inline if). В этом случае программный код примет вид:

{% set ram_requirement_success = True if ram >= 2048 else False %}

Переменным можно так же присваивать результаты логических операций напрямую. Тот же самый код можно записать следующим образом:

{% set ram_requirement_success = (ram >= 2048) %}

Циклы for являются аналогом конструкций типа foreach других языков программирования и предназначены для выполнения заданного набора инструкций применительно к каждому элементу из списка:

{% set users = ['ivanov', 'petrov', 'kuznetsov'] %}
{% for user in users %}
  {% do salt.log.info(user.upper()) %}
{% endfor %}

Если вам нужно будет обработать данные словаря, воспользуйтесь методом items(), чтобы получить список его элементов:

{% set users = {'u1':'ivanov', 'u2':'petrov', 'u3':'kuznetsov'} %}
{% for id, user in users.items() %}
  {% do salt.log.info(user.upper()) %}
{% endfor %}

Так как циклы Jinja работают только со списками, то для эмуляции обычных циклов со счетчиком вам нужно воспользоваться функцией range([min], max). Если передать этой функции один параметр, то будет сгенерирован список с указанным количеством элементов, нумерация которых будет начинаться с нуля. Если передать два числа, то нумерация элементов будет в указанном диапазоне.

{% do salt.log.info('Обратный отсчет') %}
{% for i in range(0, 10) %}
  {% do salt.log.info(10 - i) %}
{% endfor %}

При работе с циклами важно помнить, что переменные, объявленные с помощью {% set %}, существуют только в рамках текущей интерации цикла. При переходе к следующей итерации они пересоздаются заново и не сохраняют изменения.

{% set boolean_val = False %}

{% for item in ['a', 'b', 'c'] %}
  {% if item == 'b' %}
    {% set boolean_val = True %}
  {% endif %}
{% endfor %}

{% do salt.log.info(boolean_val) %}

В примере выше boolean_val был изменён в итерации на True, при выходе из цикла он сбросился в False, нам это покажет модуль log.

Для решения проблемы нужно использовать объект namespace(), который создает глобальный контейнер. Значение в namespace() не сбрасывается при переходе к новой итерации. В примере ниже значение ns.boolean_val будет равен True.

{% set ns = namespace(boolean_val=False) %}

{% for item in ['a', 'b', 'c'] %}
  {% if item == 'b' %}
    {% set ns.boolean_val = True %}
  {% endif %}
{% endfor %}

{% do salt.log.info(ns.boolean_val) %}
Вывод значений переменных на экран

Работая с salt-скриптами у вас нет возможности использовать отладчик, поэтому для получения дополнительной информации о работе своего программного кода используйте функцию info из метода log, чтобы вывести на экран значения отдельных переменных:

{% set net = "10.0.1.0/24" %}
{% set net_parts = net.split("/") %}

# Покажет список ['10.0.1.0', '24']
{% do salt.log.info(net_parts) %}
{% set ip = net_parts[0] %}

# Покажет значение '10.0.1.0'
{% do salt.log.info(ip) %}
{% set mask = net_parts[1] %}

# Покажет значение '24'
{% do salt.log.info(mask) %}
Быстрая проверка работы salt-функций

Работу функций salt можно проверить напрямую с помощью утилиты aldpro-salt-call. Например, если вы хотите понять, будет ли функция get_str из модуля random использовать другие классы символов, если ей задать только параметр lowercase, вы можете выполнить следующую команду:

admin@dc-1:~$ sudo aldpro-salt-call random.get_str length=20 lowercase=True
local:
    Z8Wta..yO|1Hq<>zf4$;

Работу программного кода jinja можно проверить с помощью функции template_str из модуля state. В следующем примере показано, как можно быстро проверить работу функции pop и append для работы со списками. Для вывода отладочной информации на экран используйте оператор do, с помощью которого можно вызвать функцию info из модуля log.

admin@dc-1:~$ sudo aldpro-salt-call state.template_str '{% set myList = ["one","two","three"] %}{% set temp = myList.pop(1) %}{% set temp = myList.append("two") %}{% do salt.log.info(myList) %}'
[INFO    ] Loading fresh modules for state activity
[INFO    ] ['one', 'three', 'two']
local:
Summary for local----------
Succeeded: 0
Failed:
0----------
Total states run:
0
Total run time:  0.000 ms
Информация о целевой системе (grains)

Разрабатывая скрипты Jinja вы можете опираться на информацию о целевом хосте, на котором этот скрипт будет применен. Данная информация доступна в словаре grains (зерна), тут вы найдете информацию об операционной системе, памяти, дисках, настройках сетевых интерфейсов и многом другом. Например, используя ключ nodename, можно получить имя хоста:

{% set node = salt['grains.get']('nodename') %}

Актуальное содержание словаря grains для конкретного хоста можно посмотреть утилитой aldpro-salt-call с помощью команды sudo aldpro-salt-call grains.items:

admin@dc-1:~$ sudo aldpro-salt-call grains.items
local:
    ----------
    aldpro_dc_list:
        - dc-1.ald.company.lan
    aldpro_machine_type:
        dc
    astra_version:
        ----------
        distr:
            smolensk
        version:
            1.7.6
    basedn:
        dc=ald,dc=company,dc=lan
    biosreleasedate:
        12/01/2006
    biosversion:
        VirtualBox
    chasis_type:
        ----------
        chasis:
            Other
        is_notebook:
            False
 ...

Выполним запрос grains.items на pc-1:

admin@dc-1:~$ sudo aldpro-salt-call grains.items
local:
   ----------
   . . .
   dns
       ----------
       domain
       ip4_nameservers
           - 10.0.1.11
       ip6_nameservers
       nameservers
           - 10.0.1.11
       options
       search
            - ald.company.lan
       sortlist
   domain
       ald.company.lan
   efi
       **False**
   efi-secure-boot:
       **False**
   fqdn
       pc-1.ald.company.lan
   fqdn_ip4
        - 10.0.1.51
 . . .
   mem_total
       **1978**
   nodename:
       pc-1.ald.company.lan
   num_cpus:
       **2**
   num_gpus
       **1**
   os:
       AstraLinux
   os_family
       Debian
 . . .
Параметры групповых политик в pillar

Скрипт получает значения параметров групповых политик через справочник pillar. Служба Salt-Minion-Standalone извлекает данные из LDAP-каталога с учетом наследования, выполняет суммирование и предоставляет результирующий словарь.

Содержание словаря pillar можно посмотреть с миньона утилитой aldpro-salt-call (данная команда является условным аналогом GPResult в MS AD) с помощью команды

sudo aldpro-salt-call pillar.items

Содержимое справочника определено в файле /srv/aldpro-salt/roots/pillar/top.sls

base:
  '*':
    - fonts
    - policy_pillar_path
    - aldpro_audit
    - aldpro_gpo
    - aldpro_po
    - aldpro_user

Поясним ключи этого yaml-документа:

  • На первом уровне находятся ключи, которые определяют среду окружения. В файле описана только одна среда base, которая является средой окружения по умолчанию.

  • На втором уровне находятся ключи, которые таргетируют миньоны. В файле задана только одна цель с помощью символа подстановки «звездочка», под которую попадают миньоны с любым именем.

  • На третьем уровне указаны включаемые sls-файлы, в которых содержатся непосредственно кэшированные значения параметров.

Механизм кэширования данных pillar довольно сложный, поэтому есть сразу несколько файлов, в которых находятся данные параметров компьютера:

  • /opt/rbta/aldpro-salt/minion/gp-host,user_settings.json — параметры компьютера/пользователя из всех объектов групповых политик, которые назначены на текущий компьютер и всех пользователей, которые выполнили интерактивный вход в операционную систему этого компьютера

  • /opt/rbta/aldpro-salt/minion/gp-host,user_pillar.json — результат суммирования параметров компьютера/пользователей в формате json

  • /srv/aldpro-salt/roots/pillar/aldpro_gpo,user.sls — экспорт результатов суммирования параметров компьютера/пользователей в соответствующие sls-файлы словаря pillar

Если вы захотите изменить параметры компьютера на лету без внесения изменений в LDAP-каталог, это можно сделать в файле aldpro_{gpo,user}.sls. Вместе с тем, учитывайте, что эти изменения будут автоматически удалены при очередном применении групповых политик c обновлением кэша.

Если же вам нужно проверить, будет ли применена конкретная политика на хосте, вы можете применить состояние с параметром test=True. Если по результатам выполнения команды вы увидите сообщение «No changes needed to be made», значит система уже получила pillar с заданной ГП:

  # aldpro-salt-call state.apply rbta_ldap_env_vars_h test=True
...
        ID: /etc/bash.bashrc
   Function: file.blockreplace
     Result: True
    Comment: No changes needed to be made
...

Более подробную информацию о модулях pillar можно найти в документации по проекту: docs.saltproject.io

Декларативные описания Salt

Декларативная часть скрипта описывает в YAML-формате желаемую конфигурацию компьютера. В структуре документа указано, какие методы нужно вызывать для конфигурирования системы и с какими параметрами. В качестве примера создадим файл software.sls со скриптом, который описывает состояние, после применения которого в системе должен стать доступен диспетчер задач htop.

Создадим файл vim software.sls со следующим содержимым:

software_htop: # Имя состояния
  pkg.installed: # Вызов метода installed модуля salt.states.pkg
    - pkgs: # Аргументы метода installed
      - htop: # Значение аргумента pkgs

Скрипт можно выполнить с помощью команды aldpro-salt-call:

sudo aldpro-salt-call --local --file-root=. state.sls software

Рассмотрим параметры команды подробнее:

  • –file-root=. — устанавливает рабочую директорию, в которой будет выполняться поиск *.sls файлов

  • state.sls — указывает, что следует использовать функцию sls из модуля state, которая выполняет sls-скрипт

  • software — указывает имя sls-файла без расширения

По результатам выполнения команды видно, что установка прошла успешно и htop готов к работе:

...
[INFO    ] Loading fresh modules for state activity
[INFO ] Completed state [software_htop] at time 11:39:24.930751 (duration_in_ms=3955.279)
local:
----------
           ID: software_htop
     Function: pkg.installed
       Result: True
      Comment: The following packages were installed/updated: htop
      Started: 11:39:20.975472
     Duration: 3955.279 ms
      Changes:
               ----------
               htop:
                   ----------
                   new:
                        2.2.0-1
                   old:

 Summary for local
 ------------
 Succeeded: 1 (changed=1)
 Failed:    0
 ------------
 Total states run:     1
 Total run time: 3.955 s

Язык YAML, также как и JSON, является языком разметки, который позволяет описывать иерархические структуры данных. Первые три строки в приведенном примере задают пару ключ-значение, между которыми стоит знак двоеточия. Ключи могут состоять из одного и более слов, причем заключать их в кавычки необязательно. В качестве значений поддерживаются как скалярные типы данных (int, float, boolean, string), так и вложенные словари, что позволяет создавать древовидные структуры данных.

Второй и последующий уровни дерева должны обозначаться отступами с помощью двух и более пробелов, использовать символы табуляции вместо пробелов недопустимо. Если требуется прокомментировать какой-то фрагмент документа, то слева от комментария нужно поставить символ решетки.

На первом уровне структуры данных должен быть указан ключ с именем состояния, в нашем случае это software_htop. Имя выбирается произвольно, но в одном документе эти имена не должны повторяться. В предыдущих релизах ALD Pro идентификаторы состояний не должны были повторяться в пределах всех скриптов групповых политик. В актуальных версиях продукта данное ограничение снято, но мы все равно рекомендуем в идентификаторах состояний в качестве префикса использовать значение идентификатора параметра групповой политики.

На втором уровне структуры данных указывается функция, которую нужно вызвать. В нашем случае это функция installed из модуля pkg (искать по имени salt.states.pkg), который является модулем состояния, т. е. его методы приводят систему к заданному состоянию, описывая желаемый конечный результат, а не то, какие действия нужно выполнить. Существуют также модули исполнения, которые выполняют в системе конкретные действия, ранее мы уже показывали пример с использованием метода run модуля cmd для выполнения bash-команды.

В следующих строках определено, что функции нужно передать аргумент pkgs с значением htop. Обратите внимание, что аргумент и его значение являются элементами списков, поэтому в начале этих строк стоит символ дефиса.

Рекомендации к salt-скриптам

Для применения групповых политик у каждого параметра есть свой собственный скрипт, который представляет собой программный код на языке шаблонизатора Jinja. После рендеринга шаблона должен получаться yaml-документ, описывающий некоторую формулу Salt. Каждая формула может описывать один и более состояний Salt (стейтов), а каждое состояние, в свою очередь, определяет вызов одной и более функций из модулей Salt, выполнение которых, собственно, и вносит изменения на целевом хосте. В этом документе приведен ряд рекомендаций, которые помогут сделать ваши скрипты значительно лучше. Для пояснения рекомендаций мы приводим много примеров из проекта aldpro-group-policy-importer, поэтому настоятельно рекомендуем ознакомиться с файлами из этого проекта и использовать их в качестве дополнительного материала.

Ранее служба Salt-Minion выполняла скрипты дополнительных параметров всегда, т.е. вне зависимости от того, назначен этот параметр или нет. Именно поэтому в скрипте дополнительного параметра repo_source_list у нас есть проверка:

{% set id = 'rbta_ldap_custom_gp_host_repo_source_list' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
...
{% if gpo %}
...
{% endif %}

С версии 2.2.0 архитектура ALD Pro в части работы групповых политик изменилась. Теперь скрипты выполняются только в том случае, если на компьютер или пользователя назначен соответствующий параметр, поэтому делать эту проверку уже необязательно, и ее оставляют для обеспечения со старыми версиями.

Идентификаторы состояний должны включать идентификатор параметра групповой политики

В предыдущих версиях продукта скрипты групповых политик объединялись в одно общее дерево состояний, поэтому разработчикам нужно было вручную обеспечивать уникальность всех используемых идентификаторов состояний, иначе могла возникать ошибка «found conflicting ID „имя_идентификатора“». Указанную ошибку было довольно трудно отловить, т.к. содержимое yaml-документов может определяться динамически с
помощью управляющих конструкций jinja в зависимости от параметров pillar, которые определяет пользователь при настройке параметров групповых политик. Данная проблема решалась путем добавления к идентификаторам состояний дополнительного префикса. В роли такого префикса выступал идентификатор самого параметра, уникальность которого гарантировалось уже самой системой по умолчанию. Начиная с версии 2.4.0, каждый параметр групповой политики выполняется по отдельности, поэтому скрипты могут содержать повторяющиеся идентификаторы, но этого рекомендуется все равно избегать. Например, если идентификатор параметра называется «rbta_ldap_custom_gp_host_sec_ssh», то у состояния, которое обеспечивает перезапуск службы, идентификатор может иметь значение «rbta_ldap_custom_gp_host_sec_ssh_restart_ssh», а чтобы уменьшить вероятность опечаток, значение идентификатора рекомендовалось формировать через подстановку значения переменной.

Пример скрипта

В следующем примере вы можете увидеть, что в первой строке идентификатор параметра записывается в переменную id, значение которой далее используется в строках 15 и 26 для формирования уникальных идентификаторов состояний.

{% set id = 'rbta_ldap_custom_gp_host_sec_ssh' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% if gpo %}

   {%- macro getvalid(value, available) -%}
       {{- value if value!='' and value.lower() in available|lower else available[0] -}}
   {%- endmacro %}

   {%- set permit_root_login = getvalid(gpo['permit_root_login'], ['no','yes','without-password','forced-commands-only']) %}
   {%- set client_alive_interval = gpo['client_alive_interval']|int(15) %}
   {%- set client_alive_count_max = gpo['client_alive_count_max']|int(1) %}
   {%- set protocol = gpo['protocol']|int(2) %}

{{ id }}:
       ini.options_present:
           - name: '/etc/ssh/sshd_config'
           - separator: ' '
           - strict: False
           - sections:
               PermitRootLogin: '{{ permit_root_login }}'
               ClientAliveInterval: '{{ client_alive_interval }}'
               ClientAliveCountMax: '{{ client_alive_count_max }}'
               Protocol: '{{ protocol }}'

{{ id }}_restart_ssh:
           service.running:
               - name: ssh
               - restart: True
               - watch:
                  - file: /etc/ssh/sshd_config

{% endif %}

После шаблонизации в формуле должно оставаться как минимум одно состояние

Управляющие конструкции Jinja позволяют динамически управлять содержанием salt формул, но эти конструкции следует использовать таким образом, чтобы после работы шаблонизатора в salt-формуле оставалось как минимум одно состояние, иначе это сильно затруднит отладку групповых политик. Даже если jinja-код определит, что никаких изменений вносить не требуется, он должен оставить в формуле хотя бы одно состояние, которое будет информировать системного администратора о результатах применения
данного параметра групповой политики. Для того чтобы описать такое состояние вы можете использовать одну из функций модуля test, например, show_notification, nop, succeed_without_changes, fail_without_changes, succeed_with_changes или fail_with_changes.

Пример скрипта

В следующем примере вы можете увидеть, что в строках 39-43 описано состояние с использованием функции test.fail_without_changes, которое останется в salt-формуле, если скрипт будет запущен на операционной системе, которая не поддерживается.

{% set id = 'rbta_ldap_custom_gp_host_repo_source_list' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id, default=[]) %}

{% for item in gpo %}
{% do item.update({'os_type': item.get('os_type', '').lower() }) %}
{% endfor %}

{% set os_type = salt['grains.get']('os') | lower %}

{% set lines = gpo | selectattr('os_type', '==', os_type)
                   | selectattr('repo_source_item', 'string')
                   | map(attribute='repo_source_item')
                   | map('trim')
                   | select('!=', '')
                   | unique
                   | list
%}

{{ id }}:
   {%- if os_type in ['astra', 'debian', 'alt'] %}
       file.managed:
           - name: /etc/apt/sources.list.d/repo_source.list
           - contents: |
                   {%- for line in lines %}
                   {{ line }}
                   {%- endfor %}
   {%- elif os_type in ['red os', 'redhat'] %}
       file.managed:
           - name: /etc/apt/sources.list.d/repo_source.list
           - contents: |
                   {%- for line in lines %}
                       {%- set sublines = line.split('|') %}
                       [customs_{{ loop.index }}]
                       {%- for subline in sublines %}
                       {{ subline }}
                       {%- endfor %}
                   {% endfor %}
   {% else %}
       test.fail_without_changes:
           - name: "ОС не поддерживается!"
           - failhard: False
   {% endif %}

Скрипт нужно выполнять только если параметр групповой политики назначен на пользователя/компьютер

В предыдущих версиях продукта все скрипты групповых политик выполнялись вне зависимости от того, назначены они на пользователя/компьютер или нет. По этой причине от разработчиков дополнительных параметров требовалось, чтобы в скрипте выполнялась проверка на наличие соответствующих ключей в данных pillar, что обычно делали следующим образом:

Пример скрипта

В следующем примере используется ветвление {% if gpo %}, которое позволяет выполнить скрипт только в том случае, если соответствующий параметр назначен на компьютер.

{% set id = 'rbta_ldap_custom_gp_host_dyndns' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% if gpo %}

{% macro getvalid(value, available) -%}
{{- value if value!='' and value.lower() in available|lower else available[0] -}}
{%- endmacro %}

{% set domain = salt['grains.get']('domain') %}
{% set dyndns_update = getvalid(gpo['dyndns_update'], ['true', 'false'])|lower %}
{% set dyndns_update_ptr = getvalid(gpo['dyndns_update_ptr'], ['true','false'])|lower %}
{% set dyndns_refresh_interval = gpo['dyndns_refresh_interval'] if gpo['dyndns_refresh_interval'] != '' and gpo['dyndns_refresh_interval'] | int != 0 else '43200' %}
{% set dyndns_ttl = gpo['dyndns_ttl'] if gpo['dyndns_ttl'] != '' and gpo['dyndns_ttl']|int != 0 else '3600' %}

{{id}}_dyndns_update:
  ini.options_present:
    - name: /etc/sssd/sssd.conf
    - separator: '='
    - sections:
        domain/{{domain}}:
          dyndns_update: {{dyndns_update}}

{{id}}_dyndns_update_ptr:
  ini.options_present:
    - name: /etc/sssd/sssd.conf
    - separator: '='
     - sections:
        domain/{{domain}}:
          dyndns_update_ptr: {{dyndns_update_ptr}}

{{id}}_dyndns_refresh_interval:
  ini.options_present:
    - name: /etc/sssd/sssd.conf
    - separator: '='
    - sections:
        domain/{{domain}}:
          dyndns_refresh_interval: {{dyndns_refresh_interval}}

{{id}}_dyndns_ttl:
  ini.options_present:
    - name: /etc/sssd/sssd.conf
    - separator: '='
    - sections:
        domain/{{domain}}:
          dyndns_ttl: {{dyndns_ttl}}

{% endif %}

В последних релизах аналогичная проверка уже встроена в систему, поэтому вне зависимости от настроек групповых политик всегда будут выполняться только несколько избранных скриптов коробочных параметров. Например, всегда будет отрабатывать скрипт chrony, который по умолчанию выполняет настройку службы синхронизации времени в иерархии домена. Не смотря на то, что данная проверка теперь не является обязательной, ее рекомендуется оставлять для обеспечения обратной совместимости.

Скрипт должен гарантировать идемпотентность

Групповые политики применяются на компьютере каждый час, поэтому повторное выполнение скриптов не должно приводить к каким-либо ошибкам, а итоговый результат должен быть таким же, как и при первом запуске. Данное свойство называется идемпотентностью, и оно гарантируется при использовании функций из модулей состояния.

Пример скрипта

В следующем примере в строках 26-29 продемонстрировано использование функции из file.append из модуля состояния, которая не просто добавляет строку в файл каждый раз при ее вызове, а гарантирует, что эта строка будет добавлена, если ее еще нет в файле.

{% set id = 'rbta_ldap_custom_gp_host_sec_print' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% if gpo %}

   {%- macro getvalid(value, available) -%}
       {{- value if value!='' and value.lower() in available|lower else available[0] -}}
   {%- endmacro %}

   {%- set deny_print = getvalid(gpo['deny_print'], ['true', 'false'])| lower %}

   {%- set filename = '/etc/cups/cupsd.conf' %}

   {%- if deny_print=='true' %}

{{ id }}_AllowAll:
           file.blockreplace:
               - name: {{ filename }}
               - marker_start: '<Location />'
               - marker_end: '</Location>'
               - append_if_not_found: True
               - content: |
                   Order allow,deny
                   Allow from 127.0.0.1

{{ id }}_DefaultShared:
           file.append:
               - name: {{ filename }}
               - text: 'DefaultShared No'

   {%- else %}

{{ id }}_AllowAll:
           file.blockreplace:
               - name: {{ filename }}
               - marker_start: '<Location />'
               - marker_end: '</Location>'
               - append_if_not_found: True
               - content: |
                   Order allow,deny
                   Allow all

{{ id }}_DefaultShared:
           file.line:
               - name: {{ filename }}
               - mode: delete
               - match: 'DefaultShared'

   {%- endif %}


{% endif %}

Ресурсоемкие действия не следует выполнять повторно, если в них нет необходимости

Некоторые действия по конфигурированию целевой системы могут расходовать значительные вычислительные ресурсы, поэтому их выполнения следует избегать, если в этом нет необходимости и система уже находится в целевом состоянии. Например, если в системе уже включен мандатный контроль целостности, то при повторном выполнении скрипта включать его еще раз не требуется. Именно такую логику реализуют функции из модулей состояния, а при использовании функций выполнения, таких как cmd.run, для достижения похожего результата следует использовать такие директивы, как unless и onlyif.

Пример скрипта

В следующем примере в строке 14 продемонстрировано использования директивы unless, которая позволяет избежать повторной записи атрибута nsosversion в LDAP каталог, если его значение не изменилось.

{% set id = 'rbta_ldap_custom_gp_host_update_nsosversion' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% if gpo %}
{%- set host = salt['grains.get']('fqdn') %}
{%- set grains_key = gpo['grains_key'] if grains.get(gpo['grains_key']) else 'lsb_distrib_description' %}
{%- set nsosversion = salt['grains.get'](grains_key) %}
{{ id }}:
   cmd.run:
       - name: ipa host-mod '{{ host }}' --setattr=nsosversion='{{ nsosversion }}'
       - unless: ipa host-show '{{ host }}' --raw --all | grep 'nsosversion' | grep '{{ nsosversion }}'
{% endif %}

Связанные состояния нужно объединять в цепочки

В тех случаях, когда какие-то состояния нужно применять в строго определенной последовательности, их нужно объединять в цепочки с помощью директивы require, т.к. очередность состояний в sls-файле не дает полной гарантии, что их функции будут выполнены в том же порядке. После парсинга yaml-документов формируется низкоуровневая структура данных (low data), которая описывает вызов функций, и к этой структуре применяются различные оптимизации, которые повлиять на порядок выполнения функций.

Дополнительные возможности по формированию цепочек состояний могут предоставить такие директивы, как onchanges, watch, listen, prereq, onfail и use, которые позволяют выполнять функцию не просто после указанной зависимости, но еще и только в том случае, если эта зависимая функция возвращает определенное состояние. Кроме уже обозначенных возможностей есть еще директива order, с помощью которой можно также повлиять на последовательность выполнения состояний, но она существенно уступает по функциональным возможностям, т.к. позволяет поставить выполнение функции только в начало (order: 1) или конец (order:last) очереди, а назначать конкретные значения очередности выполнения крайне не рекомендуется.

В следующем примере в строках 26-31 продемонстрировано использование директивы watch, которая гарантирует, что служба ssh будет перезапущена только после выполнения тех состояний, которые затрагивают изменение файла /etc/ssh/sshd_config, и только в том случае, если файл будет действительно изменен.

{% set id = 'rbta_ldap_custom_gp_host_sec_ssh' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% if gpo %}

   {%- macro getvalid(value, available) -%}
       {{- value if value!='' and value.lower() in available|lower else available[0] -}}
   {%- endmacro %}

   {%- set permit_root_login = getvalid(gpo['permit_root_login'], ['no', 'yes','without-password','forced-commands-only']) %}
   {%- set client_alive_interval = gpo['client_alive_interval']|int(15) %}
   {%- set client_alive_count_max = gpo['client_alive_count_max']|int(1) %}
   {%- set protocol = gpo['protocol']|int(2) %}

{{ id }}:
       ini.options_present:
           - name: '/etc/ssh/sshd_config'
           - separator: ' '
           - strict: False
           - sections:
               PermitRootLogin: '{{ permit_root_login }}'
               ClientAliveInterval: '{{ client_alive_interval }}'
               ClientAliveCountMax: '{{ client_alive_count_max }}'
               Protocol: '{{ protocol }}'

{{ id }}_restart_ssh:
           service.running:
               - name: ssh
               - restart: True
               - watch:
                  - file: /etc/ssh/sshd_config

{% endif %}

Используйте возможности Salt на максимум

Штатные модули Salt предоставляют множество функций, с помощью которых можно в несколько строк и с гарантированно высоким качеством настроить практически все, что угодно, поэтому прежде чем начинать работу по созданию собственных модулей, расширяющих возможности Salt, следует тщательным образом изучить те возможности, которые доступны из коробки. По той же причине следует критически анализировать уже написанные скрипты на предмет того, можно ли их дополнительно улучшить.

Резюмируя, можно сказать, что разработка собственных моделей состояния оправдано только в самых редких случаях, когда эти функции будут задействованы как минимум в 3+ скриптах и предполагают реализацию очень сложной логики.

Пример скрипта

Мы уже приводили пример с параметром rbta_ldap_custom_gp_host_sec_ssh, но его скрипт отлично подойдет в том числе и для иллюстрации этого тезиса. В строках 15-24 продемонстрирована возможность настройки обычного конфигурационного файла с помощью модуля ini, когда в файле нет секций, а в качестве разделителя между ключом и значением используется символ пробела.

{% set id = 'rbta_ldap_custom_gp_host_sec_ssh' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}
{% if gpo %}

   {%- macro getvalid(value, available) -%}
       {{- value if value!='' and value.lower() in available|lower else available[0] -}}
   {%- endmacro %}

   {%- set permit_root_login = getvalid(gpo['permit_root_login'], ['no', 'yes','without-password','forced-commands-only']) %}
   {%- set client_alive_interval = gpo['client_alive_interval']|int(15) %}
   {%- set client_alive_count_max = gpo['client_alive_count_max']|int(1) %}
   {%- set protocol = gpo['protocol']|int(2) %}

{{ id }}:
       ini.options_present:
           - name: '/etc/ssh/sshd_config'
           - separator: ' '
           - strict: False
           - sections:
               PermitRootLogin: '{{ permit_root_login }}'
               ClientAliveInterval: '{{ client_alive_interval }}'
               ClientAliveCountMax: '{{ client_alive_count_max }}'
               Protocol: '{{ protocol }}'

{{ id }}_restart_ssh:
           service.running:
               - name: ssh
               - restart: True
               - watch:
                  - file: /etc/ssh/sshd_config

{% endif %}

Избегайте повторов

В скриптах групповых политик следует избегать следующих антипаттернов:

  • дублирования управляющих конструкций jinja;

  • впечатывания одних и тех же констант вручную;

  • повторного описания состояний с минимальными отличиями.

Если выбор будет между тем, чтобы повторить управляющую конструкцию jinja или описание состояния, то более желательно избежать дублирования управляющих конструкций, чтобы упростить чтение кода.

Проверяйте данные pillar

Данные pillar, поступающие от пользователей, должны быть проверены тщательным образом, чтобы исключать ошибки ввода или даже злонамеренные инъекции. Например:

  • Используйте метод get для безопасного извлечения параметров, чтобы исключить появление ошибок в тех случаях, когда параметр не определен. Используйте возможности метода по определению значения по умолчанию {%- set param = gpo.get(„param“, „default value“) -%}

  • Если метод get использовать невозможно, задействуйте фильтр default для установки значений по умолчанию. Например, {%- set param = gpo[„param“] | default(„installed“) -%}

  • Целочисленные значения:

    • Приводите целочисленные атрибуты к целым числам с помощью фильтра int. Например, {%- set param = gpo[„param“] | int(45) -%}

    • Ограничивайте целочисленные атрибуты допустимым диапазоном значений «сверху» с помощью фильтра min. Например, {%- set param = [100, param] | min -%}

    • Ограничивайте целочисленные атрибуты допустимым диапазоном значений «снизу» с помощью фильтра max. Например, {%- set param = [0, param] | max -%}

  • Строковые значения

    • Удаляйте лишние пробелы в начале и конце строки с помощью фильтра trim. Например, {%- set param = gpo[„param“] | trim -%}

    • Приводите строку к требуемому регистру символов с помощью фильтров lower и upper. Например, {%- set param = gpo[„param“] | lower -%}

Для более сложной обработки входных данных используйте макросы, например:

{%- macro getvalid(value, available) -%}
   {{- value if value!='' and value.lower() in available|lower else available[0] -}}
{%- endmacro %}
...
{%- set pkg_state = getvalid(item.pkg_state, ['installed', 'removed']) %}

Проверяйте неявные преобразования

Язык шаблонизации jinja предоставляет большие возможности, но вместе с тем несет и большие угрозы, т.к. требует тщательной проверки используемых синтаксических конструкций, в первую очередь в отношении неявного преобразования данных. Например, когда вы выполняете ветвление по значению переменной, в которой должен быть предположительно список элементов, вы должны понимать, что этот список неявно
преобразуется к переменной Boolean и от того, каким образом выполняется это преобразование, зависит работа вашего алгоритма.

Примечание

Пустые списки интерпретируются в Jinja как False, а списки, в которых есть какие-то значения, как True

{% if items %}
{# ветка, которая будет выполнена, когда в списке items есть элементы #}
{% else %}
{# когда список пуст #}
{% endif %}

Импорт дополнительных параметров

В разделе дополнительных источников информации приведена ссылка на архив с набором дополнительных параметров групповых политик из личного кабинета клиента.

В архиве находится в том числе скрипт policy.py, с помощью которого дополнительные параметры можно автоматически импортировать в домен. Скрипт написан на языке Python 3 и взаимодействует с контроллером домена через REST API.

Перед выполнением импорта следует определить параметры подключения к серверу через переменные окружения. Пароль можно передавать открытым текстом, но скрипт поддерживает в том числе и Kerberos-аутентификацию.

export ALDPRO_API_SERVER_URL='dc-1.ald.company.lan'
export ALDPRO_API_CA_PATH='/etc/ipa/ca.crt'
export ALDPRO_API_LOGIN='admin'
export ALDPRO_API_PASSWORD='Pa$$w0rd'

Для импорта всех параметров сразу можно использовать скрипт import.sh, который по цепочке вызовет остальные sh-скрипты, создающие объекты в каталоге.

admin@dc-1:~$ sh import.sh

Пример создания папки из скрипта import_folder_common.sh:

python3 policy.py folder add \
--host \
--parent-folder 'Дополнительные параметры' \
--folder-name 'Общие параметры'

Пример создания параметра import_parameter_common_firefox_policy.sh:

python3 policy.py parameter add \
--host \
--id 'rbta_ldap_custom_gp_host_firefox_policy' \
--name 'Политика браузера Firefox' \
--parent-folder 'Общие параметры' \
--description 'Позволяет централизованно настраивать параметры браузера Firefox путем изменения содержания файла /usr/lib/firefox/distribution/policies.json

Атрибут "Блокировать доступ к странице addons" устанавливает значение параметра BlockAboutAddons
- true - доступ заблокирован
- false - доступ предоставлен

Если значение не задано, то параметр будет отсутствовать в файле политики, по умолчанию доступ предоставляется.

Атрибут "Блокировать доступ к странице config" устанавливает значение параметра BlockAboutConfig
- true - доступ заблокирован
- false - доступ предоставлен

Атрибут "Список доменов для Kerberos-аутентификации" устанавливает значение параметра Authentication.SPNEGO, элементы списка разделяются запятыми, например:
- ald.company.lan, win.company.lan

Атрибут "Список доверенных сертификатов" устанавливает значение параметра Certificates.Install. Требуется указывать полный путь к файлу на локальном диске целевой машины, элементы списка разделяются запятыми, например:
- /etc/ipa/ca.crt, /etc/ssl/certs/ca-certificates.crt

Атрибут "Адрес домашней страницы" устанавливает значение параметра Homepage.URL, требуется указать полный URL адрес страницы, например
- https://dc-1.ald.company.lan

Если адрес домашней страницы задан, то дополнительно будут установлены параметры Homepage.Locked=true и Homepage.StartPage=homepage-locked' \
--attr 'Блокировать доступ к странице addons':block_about_addons:'' \
--attr 'Блокировать доступ к странице config':block_about_config:'' \
--attr 'Список доменов для Kerberos-аутентификации':authentication_spnego:'' \
--attr 'Список доверенных сертификатов':trusted_certificates:'' \
--attr 'Адрес домашней страницы':homepage_url:'' \
--script 'import_parameter_common_firefox_policy.sls' \
--script-comment 'Версия 1.0'

Управление и настройка ПО с помощью политик ALD Pro

Система ALD Pro позволяет централизовано устанавливать и настраивать программное обеспечение через «Политики ПО» и «Групповые политики». Если первые обеспечивают более удобное управление и простоту настройки, то вторые большую гибкость и сложность.

  • «Групповые политики» используются для приведения и поддержания в заданном состоянии настроек на доменных компьютерах. Групповые политики не предусматривают возможность установки и настройки ПО «из коробки». Однако, создавая дополнительные параметры групповых политик, мы ограничены только тем, какие модули и методы Salt мы можем использовать.

  • «Политики ПО» позволяют устанавливать программы только из deb-пакетов доступных в заранее подготовленных репозиториях. Настройка программы тут может выполняется через создание файлов из шаблонов с параметрами. Политики ПО позволяют устанавливать, обновлять и удалять (если ПО было установлено через политику) программы, создавать конфигурационные файлы. Однако, политики ПО не применимы для выполнения более сложных действий при конфигурировании ПО, например, запуск службы, создание символических ссылок, запуск программ. Для этих целей могут быть использованы дополнительные параметры групповых политик.

С одной стороны, управление ПО через «Групповые политики» отрывает почти безграничные возможности по установке ПО. Можно устанавливать программы хоть из пакетов, хоть из исходных кодов, хоть используя AppImage или устанавливать программы, работающие через Wine. Так же мы можем использовать возможности Salt для создания и изменения конфигурационных файлов приложения.

С другой стороны, создание дополнительных параметров групповых политик не тривиальная задача для среднестатистического администратора. Тут необходимо базовое знание Salt и умение писать bash скрипты, императивные шаблоны Jinja2 и декларативные состояния Salt. Это увеличивает порог входа для использования этого подхода. Однако этот порог может быть понижен, если будет подготовлена толковая инструкция по настройке такого дополнительного параметра ГП.

Кроме того, в ALD Pro разработали специальный инструмент командной строки policy.py – утилиту на Python, которая, используя специальные входные файлы определенного формата, автоматически создает в домене ALD Pro дополнительные параметры групповых политик. Администратору остается только создать групповую политику с необходимом дополнительным параметром, корректно задать значения для этого параметра и назначить её на целевые АРМ.

Минусом установки ПО как через «Политики ПО», так и через «Групповые политики» является отсутствии обратной связи со стороны целевого компьютера. Администратор может централизовано назначить установку, обновление, удаление или настройку ПО через интерфейс ALD Pro, но не сможет централизовано собрать данные о том, где настройки применились корректно, а где не применились или применились с ошибками.

Продемонстрируем в данном модуле возможности настройки ПО через групповые политики и дополнительные параметры.

В качестве примера «сложного» ПО, требующего дополнительных шагов для корректной работы, установим и настроим клиент RuBackup. Причем сделаем это с помощью дополнительных параметров групповых политик.

Для установки ПО через политики ПО, в качестве источников пакетов необходимо использовать дополнительную подсистему ALD Pro – сервер репозитория ПО, которая рассмотрена в Модуль 11. Дополнительные подсистемы и интеграции в разделе Подсистема «Репозиторий программного обеспечения», где мы с вами детальнее рассмотрим работу политики ПО, установим сервер репозитрия ПО и разольем Yandex браузер на клиентские рабочие станции. Установка пакетов через групповые политики может осуществляться из любого источника.

Управление через «Групповые политики»

Создание доп. параметров групповой политики для управления и настройки ПО

Для того чтобы в домене можно было организовать централизованное управление корпоративными приложениями, в системе ALD Pro реализована возможность создания дополнительных параметров групповых политик, которые решают ту же задачу, что и административные шаблоны Windows.

Создадим дополнительный параметр групповых политик, с помощью которого можно будет централизованно управлять источниками программного обеспечения для пакетного менеджера apt.

Создание доп. параметров групповых политик доступно в одноименном разделе портала управления . Вы можете выбрать вкладку или в зависимости от того, хотите ли вы создать параметр для настройки окружения пользователя или компьютера. Будьте внимательны, т. к. перенести параметр из одного раздела в другой после его создания не получится.

  1. Так как установка агента RuBackup это настройка общая для всего хоста, на вкладке кликнем по узлу и нажмем кнопку .

../_images/aldpro_mod6_image46.png

рис. 314 Создание нового дополнительного параметра

  1. До первого сохранения параметра нам будет доступна только вкладка . Заполним ее параметры:

  • Название параметра: .

    Это имя параметра, под которым вы его хотите видеть при редактировании объектов групповых политик на портале управления.

  • Уникальный идентификатор: .

    Полное значение идентификатора будет «rbta_ldap_custom_gp_host_manage_rubackup_client». Оно будет использоваться в качестве имени папки на диске и в salt-скриптах.

  • Тип каталога: .

    Определяет, относится ли данный параметр к настройкам компьютера или пользователя. Параметр недоступен для редактирования, его значение определяется автоматически в зависимости от того, с какой страницы вы перешли к созданию дополнительного параметра.

  • Тип параметра: .

Позволяет указать способ хранения атрибутов:
  • — задает плоский список атрибутов. Например, для настройки межсетевого экрана может потребоваться задать уровень детализации журнала, и эта настройка подразумевает одно конкретное значение, поэтому она может быть реализована атрибутом «простого» параметра.

  • — задает таблицу атрибутов, где в каждой строке представлен типовой набор данных. Если продолжать пример с межсетевым экраном, то для настройки фильтрации может потребоваться разрешить входящие ssh-соединения, запретить исходящие smtp и т.п., поэтому такие настройки нужно реализовывать атрибутами «составного» параметра.

  • Папка параметра: .

    Указывает раздел каталога, в котором будет представлен этот параметр.

  • Назначение параметра:

Позволяет централизованно управлять клиентом RuBackup: устанавливать, настраивать и удалять.
Атрибут "Требуемое действие" определяет тип требуемого действия над клиентом RuBackup и
может принимать значения:
install – для установки
remove – для удаления
Атрибут "Основной сервер RuBackup" определяет имя или ip адрес мастер-сервера RuBackup.
Используется в случае установки или перенастройки клиента.
  • оставьте по умолчанию.

    Тут задается информация о том, с какими версиями ОС совместим данный параметр.

Обязательно нажмите кнопку .

../_images/aldpro_mod6_image47.png

рис. 315 Вкладка «Основное» дополнительного параметра

  1. На вкладке «Атрибуты параметра» нам нужно добавить два элемента:

  1. «Требуемое действие»

  • : Требуемое действие.

    Название, под которым вы хотите видеть этот атрибут на карточке параметра.

  • : action.

    Идентификатор атрибута, под которым значение атрибута будет доступно в пилларе для его использования из salt-скрипта.

  • : Требуемое действие: install или remove.

    Краткие комментарии, которые помогут упростить поддержку этого атрибута в будущем, когда потребуется внести какие-либо изменения. Данная информация недоступна при настройке групповой политики, поэтому, если вы хотите дать подсказку администратору о возможных значениях этого атрибута, внесите эту информацию в описание параметра.

  • : отметьте галочкой.

    Атрибуты, отмеченные как , должны быть заполнены при применении параметра.

../_images/aldpro_mod6_image48.png

рис. 316 Вкладка «Атрибуты параметра» дополнительного параметра.

  1. «Основной сервер RuBackup».

  • : «Основной сервер RuBackup».

  • : «rubackup_master».

  • : «Имя или ip адрес мастер-сервера RuBackup».

  • : оставьте пустым.

../_images/aldpro_mod6_image49.png

рис. 317 Вкладка «Атрибуты параметра» дополнительного параметра

  1. На вкладке необходимо внести текст Salt-скрипта и заполнить обязательное поле комментарий, по которому можно будет идентифицировать его версии.

Нажмите кнопку и перенесите текст скрипта, приведённый ниже:

# Определение переменных из параметров задания автоматизации
{% set id = 'rbta_ldap_custom_gp_host_manage_rubackup_client' %}
{% set node = salt['grains.get']('nodename') %}
{% set gpo = salt['pillar.get']('aldpro-hosts:' + node + ':' + id) %}

{% if gpo %}
  {% set action = gpo['action'] %}
  {% set rubackup_master = gpo['rubackup_master'] %}

  # Установка
  {% if action.lower() == 'install' %}
    {% do salt.log.info("Установка клиента RuBackup") %}

    {{ id }}_install_rubackup_client:
      pkg.installed:
        - name: rubackup-common
        - name: rubackup-client

    {{ id }}_root_profile_configure:
      file.append:
        - name: /root/.bashrc
        - text:
          - "PATH=$PATH:/opt/rubackup/bin"
          - "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rubackup/lib"
          - "export PATH"
          - "export LD_LIBRARY_PATH"

    {{ id }}_configure_rubackup_client:
      {% if not salt[ 'file.file_exists' ]('/opt/rubackup/keys/master-key') %}
        cmd.run:
          - name: '/opt/rubackup/bin/rb_init --agree-with-eula --primary-fqdn "{{ rubackup_master }}" --client-iface eth0 --remote-replica --centr-recovery --local-backup-dir /rubackup-tmp --used-ip-version ipv4 --node client --monitoring'
          - require:
            - pkg: rubackup-client
     {% else %}
       file.keyvalue:
         - name: /opt/rubackup/etc/config.file
         - key: who-is-primary-server
         - value: {{ rubackup_master }}
         - separator: ' '
         - ignore_if_missing: True
     {% endif %}

   {{ id }}_start_rubackup_client_service:
     service.running:
       - name: rubackup_client
       - enable: true
       - require:
         - pkg: rubackup-client

   # Удаление
  {% elif action.lower() == 'remove' %}
    {% do salt.log.info("Удаление клиента RuBackup") %}

    {{ id }}_stop_rubackup_client:
      service.dead:
        - name: rubackup_client
        - enable: false

    {{ id }}_remove_rubackup_client:
      pkg.purged:
        - name: rubackup-client
        - name: rubackup-common

    {{ id }}_housekeeping_config_files1:
      file.line:
        - name: /root/.bashrc
        - mode: delete
        - match: 'PATH=\$PATH:/opt/rubackup/bin'
        - quiet: True

    {{ id }}_housekeeping_config_files2:
      file.line:
        - name: /root/.bashrc
        - mode: delete
        - match: 'LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/opt/rubackup/lib'
        - quiet: True

    {{ id }}_housekeeping_config_files3:
      file.line:
        - name: /root/.bashrc
        - mode: delete
        - match: 'export PATH'
        - quiet: True

    {{ id }}_housekeeping_config_files4:
      file.line:
        - name: /root/.bashrc
        - mode: delete
        - match: 'export LD_LIBRARY_PATH'
        - quiet: True

    {{ id }}_housekeeping_config_files5:
      file.absent:
        - name: /opt/rubackup/
  {% else %}
    {% do salt.log.info("Ошибка! Выбрано некорректное действие {{ action }}") %}
  {% endif %}
{% endif %}

Данный скрипт, в зависимости от типа выбранного действия, установит и настроит или удалит клиент RuBackup.

../_images/aldpro_mod6_image50.png

рис. 318 Вкладка «Конфигурация скрипта» дополнительного параметра

Создание, настройка и применение групповой политики.

Для применения доп. параметра ГП на доменных компьютерах необходимо создать и настроить групповую политику с этим параметром.

  1. Для создания групповой политики перейдите в раздел «Групповые политики» и нажмите соответствующую кнопку .

../_images/aldpro_mod6_image51.png

рис. 319 Создание новой групповой политики

  1. До первого сохранения объекта нам доступна только вкладка «Основное», где требуется задать имя объекта и описание. Введем следующие значения:

  • : Управление клиентом RuBackup

  • : Устанавливает, перенастраивает или удаляет клиент RuBackup

И нажмем кнопку .

../_images/aldpro_mod6_image52.png

рис. 320 Групповая политика вкладка «Основное»

Теперь нам доступны для редактирования остальные вкладки:

  • – отображает список параметров, которые задействованы в этом объекте групповой политики. Вы можете удалить параметр или быстро перейти к его редактированию.

  • – содержит параметры для настройки окружения компьютера.

  • – параметры для настройки окружения пользователя.

  • – содержит список подразделений, на которые назначен объект групповой политики. На этой вкладке вы можете удалить назначение или назначить объект на дополнительные подразделения.

  1. Включим параметр () и установим значение поля:

  • : install

  • : имя или ip адрес вашего сервера RuBackup

и нажмем кнопку .

../_images/aldpro_mod6_image53.png

рис. 321 Групповая политика вкладка «Параметры компьютеров»

Подробную справку о параметре групповой политики можно получить, если кликнуть по значку с символом вопроса, который расположен в правом верхнем углу карточки. Как вы можете заметить, это тот самый текст, который мы вводили в поле при создании доп. параметра ГП.

../_images/aldpro_mod6_image54.png

рис. 322 Вызов справки по групповой политке

Чтобы закрыть справку и вернуться к форме редактирования, сделайте клик по значку в форме крестика, который расположен в правом верхнем углу карточки.

  1. Перейдем на вкладку и добавим новое назначение кнопкой .

../_images/aldpro_mod6_image55.png

рис. 323 Групповая политика вкладка «Подразделения»

4.1. Так как мы хотим применить объект групповой политики на клиентские компьютеры, то выберем подразделение, например, и нажмем кнопку .

Обратите внимание на поле . Это значение позволяет определить порядок применения параметров, если на одно и то же организационное подразделение назначено несколько объектов групповой политики.

../_images/aldpro_mod6_image56.png

рис. 324 Групповая политика выбор подразделения

  1. В карточке компьютера из подразделения можно убедиться, что параметр ГП на него назначен и посмотреть значения его атрибутов.

../_images/aldpro_mod6_image57.png

рис. 325 Карточка компьютера

  1. Полный путь до файла скрипта, который используются для применения этого параметра:

/srv/aldpro-salt/roots/states/policies/host-policies/rbta_ldap_custom_gp_host_manage_rubackup_client/init.sls

Чтобы не ждать обновления параметров выполним на компьютере pc-1.ald.company.lan команду:

sudo aldpro-gpupdate --gp
systemctl status rubackup_client
admin@pc-1:~$ sudo aldpro-gpupdate --gp
Форсированное применение групповых политик
[INFO    ] Loading fresh modules for state activity
. . .
[INFO    ] Running state [run_rbta_ldap_custom_gp_host_manage_rubackup_client] at time 12:38:17.600170
[INFO    ] Executing state salt.state for [run_rbta_ldap_custom_gp_host_manage_rubackup_client]
[INFO    ] Loading fresh modules for state activity
[INFO    ] Установка клиента RuBackup
[INFO    ] Running state [rubackup-client] at time 12:38:22.952570
[INFO    ] Executing state pkg.installed for [rubackup-client]
[INFO    ] Executing command dpkg-query in directory '/root'
[INFO    ] Executing command apt-cache in directory '/root'
[INFO    ] Executing command apt-get in directory '/root'
[INFO    ] Executing command dpkg in directory '/root'
[INFO    ] Executing command systemd-run in directory '/root'
[INFO    ] Executing command dpkg-query in directory '/root'
[INFO    ] Made the following changes:
'rubackup-client' changed from 'absent' to '2.3.0.12-1'
'rubackup-common' changed from 'absent' to '2.3.0.12-1'
. . .
id__': 'rbta_ldap_custom_gp_host_manage_rubackup_client_configure_rubackup_client'}}}}
[INFO    ] Completed state [run_rbta_ldap_custom_gp_host_manage_rubackup_client] at time 12:40:12.964257 (duration_in_ms=115364.087)
. . .
admin@pc-1:~$ systemctl status rubackup_client
● rubackup_client.service - RuBackup client
  Loaded: loaded (/etc/systemd/system/rubackup_client.service; enabled; vendor preset: enabled)
  Active: active (running) since Sat 2024-12-28 12:40:10 MSK; 2min 7s ago
Main PID: 1897226 (rubackup_client)
   Tasks: 5 (limit: 2250)
  Memory: 46.4M
   CPU: 23.512s
  CGroup: /system.slice/rubackup_client.service
          └─1897226 /opt/rubackup/bin/rubackup_client start

Для удаления клиента RuBackup достаточно изменить значение атрибута на

LAPS — Управление паролями локальных администраторов

При установке операционной системы создается учетная запись как минимум одного локального администратора, с помощью которой на этом хосте можно получить права суперпользователя, поэтому жизненный цикл локальных учетных записей на компьютерах в домене требует повышенного внимания со стороны системных администраторов. Существуют разные подходы к решению этой задачи, например, в службе каталога ALD Pro уже был параметр групповой политики, с помощью которого можно было централизованно запретить локальным пользователям вход в операционную систему компьютеров ALSE, но теперь стало доступно еще и специализированное решение по управлению паролями локальных администраторов — Local Admins Password Solution или кратко, LAPS.

Механизм работы LAPS

Локальная учетная запись администратора может потребоваться в тех случаях, когда войти в операционную систему компьютера с помощью учетной записи из домена окажется невозможно. Вместе с тем, администрировать локальные учетные записи вручную представляется крайне сложной задачей, поэтому решение LAPS становится важным компонентом для обеспечения безопасности ИТ-инфраструктуры.

../_images/aldpro_mod6_image59.png

рис. 326 Архитектура LAPS

Решение LAPS и состоит из трех основных компонентов:

1. Каталог LDAP — хранит информацию о пароле локального администратора в защищенных атрибутах учетной записи компьютера, доступ к которым имеют только участники группы admins и сами компьютеры. Решение LAPS использует
следующие атрибуты:

  • Атрибут aldproLAPSPassword – хранит json-объект с информацией о пароле локального администратора, причем компьютер имеет право только на запись этого атрибута, а чтение ему недоступно. Объект json содержит следующие ключи:

    • name — имя локального администратора, которому был установлен пароль на данном компьютере;

    • pass — пароль, закодированный в base64;

    • time — время, когда этот пароль был установлен в системе в GMT;

    • error — необязательный ключ с текстом ошибки, которая возникла при изменении пароля.

  • Атрибут aldproLAPSPasswordExpirationTime – хранит срок действия пароля, по истечению которого пароль должен быть обновлен.

  • Атрибут aldproLAPSCurrentPasswordVersion – хранит случайное число длиной 16 символов, определяющее версию пароля. Это значение позволяет определить, что операционная система целевого хоста была восстановлена из резервной копии и нужно изменить пароль еще раз во внеочередном порядке, чтобы в каталоге было актуальное значение пароля.

  1. Параметр групповой политики — определяет набор настроек и содержит salt скрипт, реализующий логику LAPS. При каждом применении групповых политик скрипт параметра выполняет на компьютере следующие действия:

    1. Извлекает из учетной записи компьютера в домене значения атрибутов aldproLAPSPasswordExpirationTime и aldproLAPSCurrentPasswordVersion с информацией о пароле локального администратора, который был сохранен в LDAP-каталоге.

    2. Извлекает из локального файла /etc/shadow-aldpro-laps.ldif значения атрибутов admin_account_name, password_length, password_complexity и current_password_version с информацией о пароле локального администратора, который был изменен в операционной системе компьютера.

    3. Проверяет список условий, по любому из которых нужно обновлять пароль:

      • Если параметр групповой политики применяется в первый раз, и ранее пароль локального администратора еще не был установлен.

      • Если в настройках групповой политики изменилось имя локального пользователя, длина или сложность пароля.

      • Если срок действия пароля истек или больше допустимого значения, определенного текущими настройками политики.

      • Если не совпадает версия пароля в LDAP-каталоге и в локальном файле (операционная система компьютера или LDAP-каталог были восстановлены из резервной копии).

    4. Изменяет пароль локальному пользователю и снимает с него блокировку, если это требуется.

    5. Сохраняет информацию о новом пароле в LDAP-каталог и в локальный файл.

    6. Блокирует остальных локальных пользователей системы, если это требуется.

  2. Графический интерфейс — представляет из себя оконное приложение, которое позволяет найти информацию LAPS для конкретного компьютера по его полному доменному имени. Администратор может увидеть текущий пароль локального администратора, а также изменить срок действия этого пароля, если ему потребуется форсировать обновление пароля.

Установка решения

Решение распространяется в виде deb-пакета, который можно установить на любой компьютер в домене, будь то контроллер или рабочее место администратора:

sudo apt install ./aldpro-laps_1.0-1_amd64.deb

Для возможности использования решения после установки deb-пакета нужно будет расширить схему каталога и импортировать в домен дополнительный параметр групповой политики.

Импорт переменных окружения

Сначала откройте окно терминала и определите несколько переменных среды окружения в соответствии с параметрами вашего домена. Чтобы эти команды не сохранились в истории, добавьте символ пробела в начало каждой строки:

export SUFFIX='dc=ald,dc=company,dc=lan'
export ALDPRO_API_SERVER='dc-1.ald.company.lan'
export ALDPRO_API_CA_PATH='/etc/ipa/ca.crt'
export ALDPRO_API_LOGIN='admin'
export ALDPRO_API_PASSWORD='Pa$$w0rd'

Расширение схемы каталога

Теперь внесите изменения в схему каталога, для этого выполните следующую команду:

cat /opt/rbta/aldpro/aldpro-laps/schema/update.ldif | envsubst | ldapmodify -c -H ldaps://ALDPRO_API_SERVER -D 'cn=Directory Manager' -w $ALDPRO_API_PASSWORD
  • утилита cat считывает содержимое файла update.ldif и передает его в стандартный поток вывода;

  • утилита envsubst подставляет значения переменных из среды окружения (в файле используется переменная SUFFIX);

  • утилита ldapmodify вносит изменения в LDAP-каталог.

Проверить наличие изменений в схеме каталога можно командой:

ldapsearch -o ldif-wrap=no -H ldaps://$ALDPRO_API_SERVER -D 'cn=Directory Manager' -w $ALDPRO_API_PASSWORD -b 'cn=schema' + | grep LAPS
objectClasses: ( 1.3.6.1.4.1.52616.100.2.4.3000 NAME 'aldpro-laps' DESC 'Local administrator password object class' SUP top AUXILIARY MAY ( aldproLAPSPassword $ aldproLAPSPasswordExpirationTime $ aldproLAPSCurrentPasswordVersion ) X-ORIGIN ( 'ALD Pro' 'user defined' ) )
attributeTypes: ( 1.3.6.1.4.1.52616.100.2.3.3000 NAME 'aldproLAPSPassword' DESC 'Local administrator name, password and time in json format' SYNTAX    1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN ( 'ALD Pro' 'user defined' ) )
attributeTypes: ( 1.3.6.1.4.1.52616.100.2.3.3002 NAME 'aldproLAPSCurrentPasswordVersion' DESC 'Local administrator password version' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN ( 'ALD Pro' 'user defined' ) )
attributeTypes: ( 1.3.6.1.4.1.52616.100.2.3.3001 NAME 'aldproLAPSPasswordExpirationTime' DESC 'Local administrator password expiration time' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-ORIGIN ( 'ALD Pro' 'user defined' ) )

Изменения в схему вносятся через указанный в параметре ALDPRO_API_SERVER контроллер домена и реплицируются на все остальные серверы автоматически. Команду можно запускать на любом компьютере в домене неограниченное количество раз. При повторном выполнении команды вы будете просто получать предупреждение «Type or value exists» о том, что указанные в файле инструкции доступа aci уже находятся в каталоге.

Импорт дополнительного параметра групповой политики

Следующим действием импортируйте дополнительный параметр групповой политики следующей командой:

cd /opt/rbta/aldpro/aldpro-laps/policy/
sh import.sh

Скрипт создаст в дополнительных параметрах папку LAPS и загрузит в нее параметр «Пароли локальных администраторов».

Настройка политики LAPS в домене

Теперь вы можете создать объект групповой политики в домене и настроить его с использованием нового параметра.

../_images/aldpro_mod6_image60.png

рис. 327 Настройка параметра групповой политики LAPS

Параметр позволяет централизованно управлять паролями локальных администраторов путем внесения изменений в файл /etc/shadow с помощью salt-функции user.present. На сервере в LDAP-каталоге изменения сохраняются с помощью команды ipa host-mod из под учетной записи компьютера.

Атрибут «Имя локального администратора» определяет логин или числовой UID того пользователя, паролем которого нужно управлять. Для корректной работы параметра групповой политики значение является обязательным.

Атрибут «Блокировать остальных» позволяет указать, нужно ли блокировать вход по паролю для остальных локальных пользователей системы.

Допустимые значения:

  • Lock — параметр блокирует вход по паролю для остальных локальных пользователей системы, в файле /etc/shadow к паролям пользователей будет добавляться восклицательный знак. В качестве синонима Lock может использоваться значение True.

  • Unlock — параметр снимает блокировку входа по паролю со всех локальных пользователей системы, которым назначен пароль. Если у пользователя нет пароля (в качестве пароля записан восклицательный знак), то блокировка сниматься не будет, так как вход без пароля является небезопасным.

  • Ignore — параметр не затрагивает остальных пользователей системы. Это поведение определено по умолчанию, поэтому в качестве синонима можно использовать False, пустую строку или любое другое значение.

Атрибут «Срок действия пароля» позволяет задать период, по истечению которого пароль локального администратора на компьютере будет обновлен. Значение представляет собой целое число в диапазоне от 1 до 365, указывающее количество дней. Если значение не определено, по умолчанию устанавливается срок действия пароля в 30 дней.

Атрибут «Ограничить максимальный срок действия пароля» позволяет запретить установку значений, превышающих текущие настройки параметра групповой политики.

Допустимые значения:

  • True — пароль локального администратора будет автоматически обновлен, если в момент применения параметра групповой политики срок действия пароля в LDAP каталоге окажется больше того значения, которое должно быть установлено в соответствии с текущими настройками параметра групповой политики. Значение True используется по умолчанию.

  • False — администраторы вправе устанавливать вручную любой срок действия пароля LAPS, превышающий текущую дату и время, и это не приведет к внеочередному обновлению пароля.

Например, если настройками параметра групповой политики определен срок действия пароля в 30 дней, а на календаре уже 1-го августа, то при включенном ограничении администратор будет не вправе установить вручную срок действия пароля на 3-е сентября или более поздние даты, т.к. в этом случае пароль будет автоматически
обновлен.

Атрибут «Сложность пароля» позволяет задать желаемый уровень сложности нового пароля для локального администратора. Допустимые значения:

  • 1 — прописные символы;

  • 2 — прописные символы + строчные символы;

  • 3 — прописные символы + строчные символы + цифры (этот уровень используется по умолчанию);

  • 4 — прописные символы + строчные символы + цифры + специальные символы;

  • 5 — предыдущий набор символов за вычетом непечатных знаков, например, I, O, Q, l, o, 0, 1, и др.

Атрибут «Длина пароля» позволяет задать желаемую длину нового пароля для локального администратора. Значение должно представлять собой целое число в диапазоне от 8 до 64. Если значение не определено, по умолчанию пароли генерируются длиной в 14 символов.

Для принудительного применения параметров групповых политик на целевых хостах вы можете использовать следующую команду:

sudo aldpro-gpupdate --gp

Просмотр информации LAPS в графическом интерфейсе

Графическая утилита LAPS предназначена для управления паролями локальных администраторов Linux-компьютеров, которые подключены к домену ALD Pro. Авторизованный пользователь может узнать учетные данные локального
администратора, чтобы использовать их для устранения проблем в работе операционной системы в условиях недоступности доменных сервисов. Для работы с утилитой пользователь должен быть участником группы admins.
После установки deb-пакета запустить приложение можно из меню ().

../_images/aldpro_mod6_image61.png

рис. 328 Графический интерфейс администратора LAPS

В основном окне приложения доступны следующие элементы интерфейса:

  1. Поле «Имя компьютера» предназначено ввода полного имени компьютера, по которому будет выполнен поиск записи в LDAP-каталоге.

  2. Кнопка «Найти» запускает поиск учетной записи компьютера в LDAP-каталоге.

    Для выбора контроллера домена приложение использует результаты автоматического обнаружения сервисов от службы SSSD из файла /var/lib/sss/pubconf/kdcinfo.DOMAIN. Аутентификация выполняется по протоколу Kerberos V5 с использованием билетов из связки ключей Linux.
    Если в связке ключей не окажется действительного TGT-билета пользователя, то по нажатию кнопки “Найти” откроется окно для ввода пароля от доменной учетной записи, из-под которой был выполнен вход в систему.

    В случае неуспешного поиска в строке состояния будет выведена информация об ошибке, а кнопки «Установить», «Копировать пароль» и «Показать пароль» будут неактивны. При успешном поиске в соответствующих полях отобразится найденная информация, как указано на рис. 328.

  3. Поле «Пароль LAPS действителен до» отображает текущее значение срока действия пароля локального администратора для выбранного компьютера.

  4. Далее на форме представлены элементы управления для установки нового срока действия пароля. Вы можете как уменьшить это значение, так и увеличить его. Пароль будет автоматически обновлен при применении параметра групповой политики в следующих двух случаях:

  • Если срок действия будет установлен меньше текущей даты и времени.

  • Если срок действия будет больше того значения, которое должно быть установлено в соответствии с текущими настройками параметра групповой политики, и включено ограничение максимального срок действия пароля.

  1. Кнопка «Установить» сохраняет новое значение срока действия пароля.

  2. Поле «Дата последнего изменения пароля LAPS» отображает дату и время, когда пароль был установлен групповой политикой последний раз. Значение отображается в том часовом поясе, который установлен на рабочем месте администратора.

  3. Поле «Имя аккаунта» отображает имя локального администратора, для которого был установлен пароль в системе.

  4. Поле «Пароль» отображает текст пароля, который был установлен локальному администратору в операционной системе компьютера. По умолчанию пароль скрыт символами звездочки. Если при применении параметра групповой политики произошла ошибка, то в поле «Пароль» будет отображаться текст с уточнением причины этой ошибки.

  5. Кнопка «Копировать пароль» позволяет скопировать скрытый пароль локального администратора в буфер обмена.

  6. Кнопка «Показать пароль» — позволяет отключить отображение пароля на экране открытым текстом.

  7. Строка состояния выводит информацию о работе приложения для упрощения отладки.

Практика и тестирование

  • Практическая работа: Модуль 6. Управление политиками ALD Pro
  • Тест: Модуль 6. Управление политиками ALD Pro

Заключение

В этом модуле мы прошли тему политик, поэтому можно сказать, что обязательный минимум уже выполнен. Далее мы перейдем к установке и настройке дополнительных подсистем, которые позволят вам быстро закрыть типовые потребности, которые будут возникать на большинстве предприятий.

Дополнительные источники информации

  • Основы Salt, Крейг Себеник и Томас Хэтч

  • Дополнительные параметры групповых политик из личного кабинета

  • Формат даты GeneralizedTime

  • Рекомендуем ознакомиться также с видеороликами нашего хорошего товарища на канале «ИТ-Проповедник». Учитывайте, что ролики записаны для версии 2.2.1, поэтому часть информации потеряла актуальность, но в целом они могут быть крайне полезны.

    • Политики паролей в ALD Pro 2.2.1

Обратная связь

Если остались вопросы, то их всегда можно задать в специальной теме.

Unable to change Windows password and keep getting the error “The password you typed does not meet the password policy requirements“? How to make the system lock your account when a hacker tries to guess your password continuously? In this guide we’ll show you how to change the account lockout and password complexity requirement policy from Command Prompt, Local Security Policy Editor, or by exporting / importing your policy. These methods work on Windows 10, 8, 7, Vista and XP.

  • Part 1: Local Security Policy
  • Part 2: Change Password Complexity Requirement Policy
  • Part 3: Change Account Lockout Policy
  • Part 4: Change Local Security Policy by Exporting and Importing

Local Security Policy

Local Security Policy allows enforcing many system-wide, user and security-related settings, such as password policy, account lockout policy, audit policy and user rights.

When you want change a security setting this is how you launch the Local Security Policy Editor:

  1. Press the Windows key + R to bring up the Run box.
  2. Type secpol.msc and hit Enter.

    When the Local Security Policy Editor opens, you can navigate to the security policy you’re interested.

Note that the Local Security Policy Editor is not available on the Home edition of Windows. So if you’re running Windows 10/8/7/Vista/XP Home, you have to change the local security policy from Command Prompt.

Change Password Complexity Requirement Policy

In the left pane of Local Security Policy Editor, expand Account Policies and then click Password Policy. In the right pane you see a list of password policy settings. Double-click on the policy you want to modify, it will open the Properties box and you can change the setting to desired value.

password-policy

  • Maximum password age
    Set the maximum number of days that a password is valid. After this number of days, the password is expired and Windows will force you to change the password at the next logon. You can set the Maximum password age between 1 and 999, or set it to 0 so your password will never expire.
  • Minimum password age
    This security setting determines the period of time (in days) that a password must be used before the user can change it. You can set a value between 1 and 998 days, or set it to 0 for allowing to change password anytime. This policy allows you to limit how frequently a user may change the password.
    Note: The Minimum password age must be less than the Maximum password age, unless the Maximum password age is set to 0.
  • Minimum password length
    Specify the least number of characters a password can have. You can set a value of between 1 and 14 characters, or set to 0 if you allow blank password. This policy can reject a user to set a short password that does not meet a minimum password length. For security reasons you’ll generally want passwords of at least six characters because long passwords are usually harder to crack than short ones.
  • Password must meet complexity requirements
    If this policy is enabled, passwords must meet the following minimum requirements:

    1. Be at least six characters long
    2. Contain a combination of at least three of the following characters: uppercase letters, lowercase letters, numbers, symbols (punctuation marks)
    3. Don’t contain the user’s user name or screen name

You can also change the password policy from an elevated Command Prompt. This is especially useful if you’re running Windows Home edition.
For example, if you want to change Maximum password age to 42 days, type the command:
net accounts /maxpwage:42

Set Minimum password age to 2 days, type:
net accounts /minpwage:2

Set Minimum password length to 3 characters, type:
net accounts /minpwlen:3

change-password-policy

Change Account Lockout Policy

In the left pane of Local Security Policy Editor, expand Account Policies and then click Account Lockout Policy. In the right pane you see three policy settings. Double-click on the policy and you can change the setting to desired value.

account-lockout-policy

  • Account lockout duration
    Specify the number of minutes that a locked account remains inaccessible before it automatically becomes unlocked. You can set the account lockout duration between 1 and 99,999 minutes. If you set it to 0, then a locked out account will remain locked until an administrator manually unlocks that account. This policy has to set along with Account lockout threshold policy.
  • Account lockout threshold
    Set the number of invalid logon attempts that are allowed before an account becomes locked out. The lockout threshold can be set to any value from 0 to 999. If the lockout threshold is set to zero, accounts will never be locked out due to invalid logon attempts.
  • Reset account lockout counter after
    Specify the time (in minutes) that must elapse after a failed logon attempt before logon attempt counter is reset to 0. The available range is 1 minute to 99,999 minutes.

    Note: The Account lockout duration must be greater than or equal to the Reset account lockout counter after time.

Here is how you can change the account lockout policy from an elevated Command Prompt.
For example, if you want to set Account lockout duration to 30 minutes, type:
net accounts /lockoutduration:30

Set Account lockout threshold to 5 bad logon attempts, type:
net accounts /lockoutthreshold:5

Set Reset account lockout counter after to 10 minutes, type:
net accounts /lockoutwindow:10

change-account-lockout-policy

Change Local Security Policy by Exporting and Importing

How to copy local group policy objects from one machine to another? Is it possible to disable the “Password must meet complexity requirements” policy using Command Prompt? All these can be achieved by exporting & importing the local security policy. Here’s how:

  1. Open an elevated Command Prompt.
  2. Type the following command and press Enter. This will export all the settings of local security policy to a text file.
    secedit.exe /export /cfg C:\secconfig.cfg

    export-account-policies

  3. Open the C:\secconfig.cfg file with NotePad and you can view and modify the policy for your own purpose. For example, if you want to disable the password complexity requirements policy, just set the value PasswordComplexity to 0 and save your changes.

    secconfig

  4. Type the following command to import the local security policy from the file C:\secconfig.cfg. Of course, you can move the secconfig.cfg file to another computer and then import the policy.
    secedit.exe /configure /db %windir%\securitynew.sdb /cfg C:\secconfig.cfg /areas SECURITYPOLICY
  5. Restart your computer and the imported security policy will take effect.

  • Previous Post: How to Turn on / off Adaptive Brightness in Windows 10 / 8
  • Next Post: How to Restore Local Security Policy to Default in Windows 10, 8, 7, Vista and XP

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Оптимизация windows 10 для слабого железа
  • Включить панель задач поверх всех окон windows 7
  • Windows server system center
  • Open git bash on windows
  • Windows 10 папка загрузки обновлений