Строим высоко-доступную Windows-инфраструктуру в командной строке. AD DS. Часть 2-я — Пост-конфигурация

В предыдущей части — Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 1 — Installation

Вступление

В этом посте мы займёмся пост-конфигурацией Active Directory: Мы определим зоны безопасности, которые в дальнейшем станут краеугольными камнями в вопросе делегирования разрешений, и ограничим добавление объектов в домен. Также, мы немного донастроим службу DNS.



Переменные, используемые в статье:

 

Определяем зоны безопасности (security tiers)

Что такое зоны безопасности?

При работе с информационных системами, в особенности с Active Directory, важно аккуратно планировать разделение привилегий и их делегирование. В идеале, следует применять модель наименьших привилегий и разделять сеть на зоны безопасности. Несколько зон безопасности могут управляться единым лесом AD DS, если допустимо, чтобы члены групп
Domain/Enterprise Admins имели полный доступ ко всем ресурсам в этом лесу.

Note

Помните, что в инфраструктуре AD только лес является границей безопасности, но не домен. Злонамеренный администратор любого домена в лесу может легко получить привилегии Enterprise Admin. Читайте больше об этом в следующих статьях:
What Are Forests?
The Forest Is Under Control. Taking over the entire Active Directory forest
The Most Common Active Directory Security Issues and What You Can Do to Fix Them

 

Где проводить границы зон безопасности?

В каждом лесу Active Directory есть зона безопасности, которую мы будем называть «Зона 0» (Tier 0). В неё входят контроллеры домена, группы Domain/Enterprise/Schema Admins, встроенная группа Administrators, Group Policy Creator Owners и т.д. – т.е. всё, что не назначено в какие-либо другие зоны. Только члены групп Domain/Enterprise Admins должны быть способны изменять объекты в Tier 0.

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

Как достигнуть этого? Тщательно изучите имеющиеся у вас сервисы и определите какая зона безопасности наилучшим образом подходит для каждого объекта.
Я обычно распределяю следующим образом:

  • Tier 0 – контроллеры домена, группы Domain/Enterprise/Schema Admins, встроенная группа Administrators, группа Group Policy Creator Owners + всё остальное, что не определено в других зонах.
  • Tier 1 – набор серверов/ресурсов, которые должны быть подконтрольны только ограниченном набору администраторов.
  • Tier 2 – обычные серверы, доступ к которым есть у всех администраторов серверов.
  • Tier 3 – Рабочие станции и прочие объекты, управляемые службой поддержки.

Кто-то может также использовать следующие дополнительные зоны:

  • Tier 2.5 – локальные администраторы на серверах.
  • Tier 3.5 – локальные администраторы на рабочих станциях.

Идея этих дополнительных зон состоит в том, чтобы владелец машины с привилегиями локального администратора на машинах не мог захватить у/з, используемую для управления объектами в Active Directory.

Вы можете узнать больше о защите Windows-сетей в этих документах: Pass-the-Hash (PtH), Securing Privileged Access.

Реализация

В этой лабораторной инфраструктуре я буду использовать следующие OU:

  • Зона 0 – $Tier0OUName
  • Зона 1 – $TierOU.Tier1.OUName
  • Зона 2 – $TierOU.Tier2.OUName
  • Зона 3 – $TierOU.Tier3.OUName

В зонах 1, 2 и 3 мы создадим иерархию из отдельных OU для компьютеров, пользователей и групп. Кроме того, я предлагаю объединять зоны 1 и 2 организационным подразделением более высокого уровня, называющимся $Tiers12CombinedOUName. Это нужно для упрощения применения групповых политик на все серверы – так будет достаточно применить их всего лишь к одному OU вместо двух.
Внутри организационного подразделения для Зоны 0 мы не будем создавать никаких OU: слишком мало объектов, оставим их тусоваться всем вместе. Кроме того, на самом деле у нас уже полно организационных подразделений и контейнеров в этой зоне — всё, что не покрывается другими тремя зонами, в т.ч. OU Domain Controllers и контейнеры Users/Computers.

OK, давайте создадим иерархию:

Note

Что такое «-f» и почему бы не использовать двойные кавычки? Это оператор форматирования, вы можете узнать больше о нём здесь. А про двойные кавычки очень хорошо написали Jonathan Angliss и Warren Frame.

 

Тонкая настройка

Присоединение к домену

По умолчанию, любой аутентифицированный пользователь может ввести до 10 компьютеров в домен AD DS — объекты компьютеров будут создаваться в контейнере «Computers». Кто-то может полагать, что это очень удобно, однако гораздо лучше этим процессом управлять и ограничивать такую возможность потому, что:

  1. Невозможно назначить политики на контейнер Computers — компьютеры в нём получают настройки только от GPO в корне домена.
  2. Невозможно делегировать: Вы не можете отделить серверы от рабочих станций в этом компьютере, а нам зачастую требуется предоставлять разные разрешения для разных типов компьютеров.

Это же справедливо и для контейнера «Users», где, по умолчанию, создаются пользователи и группы.

Для контроля за созданием учётных записей компьютеров, обычно используют атрибут ms-DS-MachineAccountQuota, который выставляют в 0, но это не оказывает никакого эффекта на пользователей и группы.

Поэтому, с помощью команд ниже, мы:

  1. Перенаправим операции создания компьютеров, пользователей и групп в специально созданное OU.
  2. Остановим хаотичное создание объектов всеми подряд, установкой явно запрещающей записи контроля доступа (Access Control Entry, ACE). После этого, только администраторы, которым явно делегированы полномочия создания объектов смогут это делать, причём только в тех OU, где вы им разрешите. Например, сотрудники службы поддержки не смогут положить рабочую станцию рядом с серверами.
  3. И, конечно же, используем классический подход, с определением атрибута ms-DS-MachineAccountQuota, тоже.

Что же здесь происходит? Первая команда довольно очевидна: Мы создаём OU. Далее мы переходит в это OU. Зачем? Потому, что командлеты *-Acl могут работать только с дисками, будь то физические тома или виртуальные диски как «AD:\».

Дальше идут несколько длинных команд с какими-то числами. Давайте разделим их построчно и разберём:

Исправление разрешений

Первое, что мы видим, это командлет Get-Acl: Он нужен, т.к. Set-Acl не может сам менять списки контроля доступа (ACL), а может только перезаписывать их другими объектами класса System.Security.AccessControl.DirectoryObjectSecurity. Т.е. мы должны сперва создать такой объект со всеми нужными ACE. Важно, что т.к. мы не хотим ничего сломать, этот объект должен содержать не только новые запрещающие записи, но и те, что уже установлены на OU.
Get-Acl позволяет нам легко получить объект нужного типа со всеми текущими записями контроля доступа. Обратите внимание, что мы даже не сохраняем этот объект ни в какой переменной, а сразу передаём через пайплайн в цикл ForEach-Object (% – это стандартный псевдоним командлета ForEach-Object). Цикл необходим здесь потому, что нам нужно осуществить две операции над этим объектом и мы не можем отправить вывод пайплайна просто в скриптовый блок. Другим решением этой проблемы было бы, конечно, сохранение объекта ACL в переменную.

В цикле мы:

  1. Добавляем новое правило контроля доступа в объект ACL.
  2. Записываем этот модифицированный объект обратно в свойства организационного подразделения, при помощи командлета Set-Acl.
Note

Про разницу между «ForEach-Object» и «foreach» читайте в замечательной статье Boe Prox`а.

 

Если то, что делает командлет Set-Acl понятно и достаточно просто, то вот команды выше не так очевидны. Давайте разберём: Там мы вызываем метод AddAccessRule, который добавляет правило контроля доступа к объекту ACL. Само правило, это, конечно же, тоже объект класса System.DirectoryServices.ActiveDirectoryAccessRule. Мы конструируем объект используя командлет New-Object. У каждого класса в .NET есть конструктор с как минимум одной перегрузкой (overload). Перезагрузка определяет, какие данные вы должны использовать для создания объекта.
Для ActiveDirectoryAccessRule все перегрузки можно посмотреть здесь.

Я буду использовать перегрузку с наибольшим количеством входных данных (самая последняя в списке), чтобы точно описать наши объекты. Для этой перегрузки мы должны определить: объекты безопасности, к которым будет применяться правило, набор разрешений, запрещающий это будет набор или разрешающий, будут ли разрешения наследоваться и, если да, то объектами какого класса.
В качестве набора разрешений я указал «CreateChild, Self, WriteProperty, DeleteTree, Delete» — эти разрешения будут запрещены (следующий параметр «Deny») и будут применены к этому OU и всему, что под ним. Дальше идут два GUID 00000000-0000-0000-0000-000000000000 — такой GUID здесь означает «объект любого класса». Перед каждым GUID явно указан тип ([guid]) — это конвертирует на лету строку в GUID, как того требует перегрузка.

Вернёмся к первому аргументу команды создания объекта ActiveDirectoryAccessRule: Здесь мы видим вызов ещё одного командлета New-Object. Почему? Потому, что этот аргумент принимает только объекты класса IdentityReference, таким образом, мы не можем просто написать здесь «Everyone». Как же нам применить это правило доступа ко всем? IdentityReference — это базовый класс для классов NTAccount и SecurityIdentifier. Т.к. «Everyone» — это не настоящая учётная запись, мы должны использовать один из конструкторов класса SecurityIdentifier. Т.к. «Everyone» — это хорошо известный участник безопасности (security principal), мы используем специальный конструктор.
Перечисление WellKnownSidType избавляет нас от необходимости искать настоящий SID для Everyone — мы просто используем «WorldSid» вместо него. Т.к. второй параметр игнорируется для большинства хорошо известных участников безопасности, я записывают туда пустоту (NULL).

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

Перенаправление контейнеров

Следующая команда гораздо-гораздо проще:

Она состоит из одного вызова командлета Set-ADObject, который удаляет элемент из многострочного атрибута wellKnownObjects и добавляет другой элемент вместо удалённого. В атрибуте wellKnownObjects записаны указатели на важные контейнеры Active Directory. Два из них, это контейнер по умолчанию для пользователей и контейнер по умолчанию для компьютеров. Просмотрев эту статью, вы можете определить, что здесь мы меняем контейнер для пользователей, т.к. «A9D1CA15768811D1ADED00C04FD8D5CD» означает GUID_USERS_CONTAINER_W.

Первый параметр (-Remove) удаляет текущее значение из многострочного атрибута. Значение для удаления (текущее значение) мы берём из свойств объекта $Domain, который мы создали в начале этой статьи командлетом Get-ADDomain. Мы совмещаем две строки, используя тот же оператор форматирования, о котором говорили ранее. Результирующую строку как раз и надо передать в параметр «Remove» для удаления.
Далее, мы добавляем новый указатель на OU Redirected, которое мы создали парой команд назад. Здесь нет ничего сложного, просто два вложенных соединения строк.

Следующий вызов Set-ADObject делает то же самое, но для контейнера Computers.
В принципе, мы делаем то, что описано в этой статье, но при помощи PowerShell.

Note

Зачем явно указывать PDC-эмулятор при записи значений атрибута wellKnownObjects? Т.к. модификация этого атрибута может происходить только на PDC-эмуляторе, вы получите ошибку «A referral was returned from the server», если попробуете использовать какой-либо другой контроллер домена.

 

Последний вызов командлета Set-ADObject нужен для того, чтобы даже, если параметр wellKnownObjects будет восстановлен в изначальное состояние, аутентифицированные пользователи всё-равно не смогут добавлять компьютеры в домен без предварительного создания учётных записей для них.

Обратная зона DNS

Наконец, пожалуй, самая наименее полезная настройка во всей серии — обратная зона DNS. Она, в самом деле, не делает ничего полезного, кроме превращения сетевых трассировок в более понятный вид — вы будете видеть DNS-имена, вместо IP-адресов.
Создайте зону обратного просмотра следующей командой:
Add-DnsServerPrimaryZone -Name ('{0}.in-addr.arpa' -f $ReverseDNSZoneName) -ReplicationScope Forest -DynamicUpdate Secure

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

Important

Обратите внимание, что адрес сети в переменной $ReverseDNSZoneName записан в обратном порядке. Зачем так сделано и что такое суффикс «in-addr.arpa», читайте здесь.

Leave a Reply

Your email address will not be published. Required fields are marked *