Глава 10. Управление пользователями Linux

ни один сервер Linux не обходится без некого метода доступа к нему для пользователей. Будь то администраторы или конечные пользователи, а к тому же и локальные или централизованные учётные данные, серверам Linux требуется некий механизм доступа к ним для пользователей (и даже для таких инструментов как Ansible!)

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

В этой главе мы на практических примерах исследуем как автоматизировать управление вашими пользователями и управление доступом посредством Ansible в соответствии с нашей моделью SOE (Standard Operating Environment, Стандартной операционной среды).

В данной главе будут рассмотрены следующие вопросы:

  • Выполнение задач по управлению учётными записями пользователей

  • Централизованное управление учётными записями пользователей через LDAP (Lightweight Directory Access Protocol, облегчённый протокол службы каталогов)

  • Принудительная настройка и аудит конфигураций

Технические требования

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

  • Ubuntu Server 18.04 LTS

  • CentOS 7.6

  • Ansible 2.8

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

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

Все обсуждаемые в данной главе образцы кода доступны с GitHub по следующему URL.

Выполнение задач управления учётными записями пользователя

На уровне своего основания всякий сервер Linux в вашей среде потребует некоторой степени доступа для пользователей. В неком предприятии, в котором могут иметься сотни, если не тысячи серверов, такие централизованные системы управления пользователями как LDAP или Active Directory были бы идеальным решением, поскольку, принимая во внимание примеры с уходящими или изменяющими пароли пользователями, это всё можно делать в одном месте и применяется для всех серверов. Мы изучим эту сторону управления и автоматизации Корпоративного Linux в своём следующем разделе, Централизация управления учётными записями пользователя при помощи LDAP.

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

[Замечание]Замечание

Обратим внимание, что как и для всех примеров из этой книги, они могут в равной степени запускаться как на 1, так и на 100 или даже на 1 000 серверов. В действительности применение Ansible снижает наличие необходимости в системе централизованного управления пользователями, поскольку изменения учётных записей пользователя могут запросто активно доставляться по всему имеющемуся штату серверов. Тем не менее, существуют хорошие причины не полагаться исключительно на это - к примеру, когда один сервер остановлен при сопроводительных работах в процессы исполнения некого плейбука Ansible, это будет означать, что он не получит выполненными необходимые изменения учётной записи. В наихудшем случае такой сервер затем попадает в ситуацию риска безопасности после своего возврата в рабочее состояние.

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

Аудит и изменение пользователей через Ansible

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

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

Для примера, возьмём следующую команду оболочки (которая позднее будет автоматизирована в Ansible):


$ useradd -c "John Doe" -s /bin/bash johndoe
		

Эта команда может быть запущена как в CentOS 7, так и в Ubuntu Server 18.04, и она даст вам те же самые результаты, а именно:

  • Создаваемая учётная запись пользователя johndoe будет добавлена со следующим свободным для пользователей UID (user identification number).

  • Комментарий для этой учётной записи будет установлен в значение John Doe.

  • Его оболочкой будет установлена /bin/bash.

И в самом деле, вы можете исполнить эту команду практически в любой системе Linux и она сработает. Присутствие отличий, однако, начнёт проявляться при рассмотрении групп, в особенности встроенных. К примеру, если вы желаете чтобы эта учётная запись была способна применять sudo для доступа от имени root (то есть johndoe является системным администратором), вы пожелаете поместить эту учётную запись в соответствующую группу wheel в CentOS 7. В сервере Ubuntu, однако, нет никакой группы wheel, а попытка помещения этого пользователя в такую группу будет иметь результатом некую ошибку. Вместо этого, в Ubuntu, такой пользователи проследует в имеющуюся там группу sudo.

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

Давайте построим этот пример, чтобы вместо того чтобы создавать соответствующего пользователя johndoe в качестве некой роли Ansible, доступ к нему можно было бы раскручивать на всех серверах Linux. Собственно код roles/addusers/tasks/main.yml для выполнения той же самой функции что и в соответствующей оболочке с предыдущей командой должен выглядеть подобным образом:


---
- name: Add required users to Linux servers
  user:
    name: johndoe
    comment: John Doe
    shell: /bin/bash
 	   

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

 

Рисунок 10-1



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

Прежде чем мы приступим к своему следующему примеру, мы покажем как с помощью Ansible выработать некий хэш пароля. Здесь мы выберем значение слова secure123. Наш модуль Ansible user обладает возможностью установки и изменения паролей учётных записей пользователя, однако он не допускает (по очень веским основаниям) для вас определять значение пароля в открытом тексте. Вместо этого вы обязаны создать некий хэш пароля для его отправки в настраиваемую машину. В Главе 6, Персональные сборки с PXE загрузкой мы рассмотрели некий способ выполнения этого небольшим фрагментом кода на Python и вы вольны повторно применить этот метод здесь. Тем не менее,вы также можете применять подавляющее большинство массивов фильтров Ansible для выработки хэшированного пароля из некой строки. Выполните из своей оболочки такую команду:


$ ansible localhost -i localhost, -m debug -a "msg={{ 'secure123' | password_hash('sha512') }}"
		

Выполнение этого произведёт некий хэшированный пароль, который вы можете скопировать и вставить в свою роль, как это отображено на следующем снимке экрана:

 

Рисунок 10-2



Это очень полезно само по себе - однако давайте засечём себе на носу: никакой хэшированный пароль не является полностью безопасным. Помните, что было время когда хэши MD5 рассматривались как безопасные, но сейчас это не так. В идеале вам не следует хранить значение хэша в открытом тексте и следует восстанавливать его в каждой системе, поскольку он содержит уникальную соль. К счастью, мы можем применять в некой роли фильтр password_hash непосредственно для получения этого.

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

  1. Прежде всего давайте создадим roles/addusers/vars/main.yml и запомним пароль Jhon Doe в некой переменной следующим образом:

    
    ---
    johndoepw: secure123
    	   
  2. Затем создадим какую- то пару ключей SSH для этого пользователя в каталоге roles/addusers/files/, выполнив в этом каталоге такую команду:

    
    $ ssh-keygen -b 2048 -t rsa -f ./johndoe_id_rsa -q -N ''
    	   

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

  3. Наконец, допустим, что johndoe намерен быть администратором систем Ubuntu и, следовательно, должен присутствовать в группе sudo. Наша получаемая в результате роль должна выглядеть так:

    
    ---
    - name: Add required users to Linux servers
      user:
        name: johndoe
        comment: John Doe
        shell: /bin/bash
        groups: sudo
        append: yes
        password: "{{ johndoepw | password_hash('sha512') }}"
    
    - name: Add user's SSH public key
      authorized_key:
        user: johndoe
        state: present
        key: "{{ lookup('file', 'files/johndoe_id_rsa.pub') }}"
    	   
  4. Исполнение этого кода выдаст результатом changed, как мы и ожидали, а следующий снимок экрана отображает успешное добавление надлежащего пользователя и соответствующего общедоступного ключа SSH:

     

    Рисунок 10-3



Отметим, что мы успешно изменили здесь имеющуюся учётную запись johndoe, ибо мы создали её ранее в данном разделе - тем не менее,мы также можем запускать свою самую последнюю роль перед созданием такой учётной записи и конечный результат будет тем же самым. Этим и прекрасен Ansible - вам не нужно писать различный код для изменений и добавлений. Имеется множество прочих возможных изменений при помощи рассматриваемого модуля user и они должны обслужить большинство ваших потребностей.

На миг вернёмся к своему созданному ранее файлу vars/main.yml, который мы для простоты данного примера оставили в открытом тексте. Тем не менее, мы можем запросто зашифровать свой имеющийся файл при помощи такой команды:


$ ansible-vault encrypt main.yml
		

Приводимый далее снимок экрана отображает это процесс шифрования в действии:

 

Рисунок 10-4



Все данные теперь зашифрованы на месте! Мы всё ещё способны запускать этот плейбук без их расшифровки - просто добавьте соответствующий параметр --ask-vault-pass в свою команду ansible-playbook и введите выбранный вами пароль vault при её приглашении на ввод.

Прежде чем завершить этот раздел, неплохо отметить что мы можем воспользоваться loops для создания за раз множества учётных записей. Наш следующий пример создаст двух новых пользователей с различным членством в группах и с различными именами пользователя и соответствующими комментариями в их учётных записях. Расширение данного примера для решения с начальными паролями и/ или ключами SSH мы оставим в качестве некого упражнения для вас, но у вас уже должно быть достаточно сведений для построения того чтобы достичь этого. Код отображается ниже:


---
- name: Add required users to Linux servers
  user:
    name: "{{ item.name }}"
    comment: "{{ item.comment }}"
    shell: /bin/bash
    groups: "{{ item.groups }}"
    append: yes
    state: present
  loop:
    - { name: 'johndoe', comment: 'John Doe', groups: 'sudo'}
    - { name: 'janedoe', comment: 'Jane Doe', groups: 'docker'}
 	   

Обратите внимание, что ранее в этой главе мы уже создали johndoe, как мы можем увидеть запустив эту роль, создаётся только пользотель janedoe, так как он пока ещё не существует - приводимый далее снимок экрана в точности воспроизводит это. janedoe отображает состояние changed, информируя нас что было выполнено изменение - в данном случае была создана соответствующая учётная запись. Состояние ok для соответствующей учётной записи johndoe сообщает нам что не было выполнено никакого действия, и всё это видно на снимке внизу:

 

Рисунок 10-5



Таким образом могут масштабно создаваться учётные записи пользователей и осуществляться управление ими, причём по большому числу серверов Linux. Как мы можем видеть в своём предыдущем снимке экрана, в обычном стиле Ansible требуется выполнение лишь изменений при оставлении неизменными уже имеющихся учётных записей. Хотя добавление учётных записей достаточно непосредственно, нам также следует рассмотреть и вариант того, что сотрудники время от времени покидают предприятие, а потому в таком экземпляре также следует выполнять и очистку учётной записи.

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

Удаление пользователей через Ansible

Хотя мы же показали как просто добавлять и изменять учётные записи пользователей при помощи Ansible, нам следует рассматривать удаление как некий отдельный случай. Причина этого проста - Ansible полагает, что когда мы применяем его модуль user совместно с loop для добавления как johndoe, так и janedoe, он добавит их обоих если они не присутствуют; в противном случае он их изменит. Естественно, если они соответствуют тому состоянию, которое описано в данной роли или в плейбуке, он не сделает с ними совсем ничего.

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

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


---
- name: Add required users to Linux servers
  user:
    name: johndoe
    state: absent
 	   

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

 

Рисунок 10-6



Запуск этой роли равносилен выполнению команды userdel в вашей оболочке - удаляется учётная запись указанного пользователя совместно с его членством в группах. Тем не менее, его каталог home останется нетронутым. Обычно это наиболее безопасный способ, ибо пользователи могут иметь сохранёнными важный код или прочие сведения в своих каталогах home, будет лучше если кто- то проверит перед реальным удалением. Если вы уверены что вы желаете удалить данный каталог (что и рекомендуется делать, как по причинам безопасности, так и для освобождения дискового пространства), тогда добавьте приводимый ниже код в ту роль которую мы только что создали:


name: Clean up user home directory
  file:
    path: /home/johndoe
    state: absent
 	   

Он выполнит рекурсивное удаление всего заданного пути path, а потому применяйте его с осторожностью!

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

Централизация управления учётными записями пользователя при помощи LDAP

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

И действительно, многие предприятия уже имеют такую систему на её месте, причём двумя наиболее распространёнными являются FreeIPA и Microsoft AD (Active Directory). В своих последующих разделах мы изучим интеграцию этих двух систем с вашими серверами Linux.

Microsoft AD

Поскольку это книга про автоматизацию Linux, какое бы то ни было глубокое обсуждение Microsoft AD и его установки и настройки далеко выходит за её пределы {Прим. пер.: см. наш перевод 2 издания Полного руководства Active Directory Дишана Франсиса}). Достаточно сказать, что в контексте Linux AD, лучше всего приспособлен под централизованное управление учётными записями пользователей, хотя, конечно же, его возможности намного шире этого. Большинство организаций, которым требуется сервер AD уже настроили его, а потому мы заинтересованы не в этом вопросе, а в том как получить серверы Linux прошедшими в нём аутентификацию.

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

[Совет]Совет

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

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

  1. Прежде чем начать сам процесс присоединения к имеющемуся каталогу, жизненно важно чтобы ваш сервер Linux применял правильные серверы DNS, которые содержат надлежащие записи SRV (Service) для данного домена. Зачастую такими серверами DNS будут сами серверы AD, но это, опять- таки, будет отличаться от организации к организации.

  2. Должен быть установлен инструментарий realmd совместно с неким числом пакетов поддержки. Давайте создадим некую роль с названием realmd применяя наше знакомство со структурой каталога roles. Наш roles/realmd/tasks/main.yml должен начинаться со следующего кода для установки требуемых пакетов:

    
    ---  
    - name: Install realmd packages
      yum:
        name: "{{ item }}"
        state: present
      loop:
        - realmd
        - oddjob
        - oddjob-mkhomedir
        - sssd
        - samba-common
        - samba-common-tools
        - adcli
        - krb5-workstation
        - openldap-clients
        - policycoreutils-python
    	   

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

  3. После того как требующиеся предварительно пакеты установлены, нашей следующей задачей является присоединение к самому имеющемуся Active Directory. Здесь мы предполагаем наличие roles/realmd/vars/main.yml с установленными значениями переменных realm_join_password, realm_join_user и realm_domain. Поскольку данный файл может содержать некий пароль с достаточными полномочиями для присоединения к установленному домену AD, рекомендуется чтобы эти переменные файлы были зашифрованы при помощи ansible-vault. Выполните следующий код:

    
    - name: Join the domain
        shell: echo '{{ realm_join_password }}' | realm join --user={{ realm_join_user }} {{ realm_domain }}
        register: command_result
        ignore_errors: True
        notify:
          - Restart sssd
    	   

    Использование модуля shell для выполнения realm join требует особого рассмотрения, поскольку выплнение этой задачи дважды не даст обычного нормального чистого поведения Ansible. Действительно, выполнение повторного realm join когда данный сервер уже участник домена получит результатом некую ошибку. В связи с этим мы устанавливаем ignore_errors: True и register полученный результат этой команды чтобы мы смогли позднее выполнить оценку успешности выполнения. Мы также обращаем внимание на некий обработчик, который будет определён позднее, для перезапуска своей службы sssd. Вышеупомянутый файл vars должен выглядеть как- то так:

    
    ---
    realm_join_password: securepassword
    realm_join_user: administrator@example.com
    realm_domain: example.com
    	   

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

  4. Мы немедленно следуем этой задачей для проверки чтобы убедиться что realm join было успешным. Если оно было удачным, мы должны получить либо код возврата 0, либо некую ошибку, сообщающую нам что Already joined to this domain (Сервер уже был подключён к домену). Если мы не получим таких ожидаемых результатов, тогда мы провалим (fail) всё воспроизведение чтобы обеспечить возможность исправления данной проблема следующим образом:

    
    - name: Fail the play when the realm join fails
        fail: 
          msg="Realm join failed with this error: {{ command_result.stderr }}"
        when: "'Already joined to this domain' not in command_result.stderr and command_result.rc != 0"
    	   
  5. Наконец, мы создаём необходимый обработчик для перезапуска sssd в roles/realmd/handlers/main.yml, таким манером:

    
    ---
    - name: Restart sssd
      service:
        name: sssd
        state: restarted
        enabled: yes
    	   

Этих шагов достаточно для выполнения базового добавления сервера Linux к некому домену AD. Хотя данный пример приведён для CentOS 7, этот процесс должен быть в целом аналогичным для таких операционных систем как Ubuntu, при условии учёта имеющихся отличий в диспетчере пакетов и названий пакетов.

Конечно же, существует великое множество расширений, которые могут быть сделаны для нашей предыдущей процедуры, большинство из которых будет выполняться при помощи команды realm. К сожалению, на момент написания нет никакого модуля realm для Ansible, а потому все команды realm должны вызываться при помощи модуля shell - хотя это всё ещё позволяет автоматизировать раскрутку участия в AD для серверов Linux при помощи Ansible.

Возможные усовершенствования, которые вы должны рассмотреть в предыдущем процессе (причём все они запросто могут быть автоматизированы расширением примера плейбука, который мы предложили ранее), заключаются в следующем

    Определите OU (organizational unit ), в который проследует данный сервер Liux после завершения своего присоединения. Без указания этого он окажется в установленном по умолчанию OU Computers. Вы можете изменить это поведение задав нечто подобное --computer-ou=OU=Linux,OU=Servers,OU=example,DC=example,DC=com внутри своей команды realm join. Убедитесь вначале что данный OU был создан и настройте предыдущие параметры для их соответствия вашей среде.

  • По умолчанию все допустимые учётные записи пользователей домена будут иметь возможность зарегистрироваться в вашем сервере Linux. Это может быть нежелательным, и когда это так, вам понадобится вначале запретить доступ для всех при помощи команды realm deny --all. Далее чтобы сообщить что вы желаете позволить всех пользователей из AD группы LinuxAdmins, вы затем можете вызвать следующую команду: realm permit -g LinuxAdmins.

  • Маловероятно что вы будете обладать в своём AD группой с названием wheel и sudo, а как результат, пользователи AD могут обнаружить что они не способны исполнять привилегированные команды. Это можно исправить добавляя соответствующих пользователей или группы в /etc/sudoers или всё же лучше в некий уникальный файл в /etc/sudoers.d, которым сможет управлять Ansible. Например, создание /etc/sudoers.d/LinuxAdmins с приводимым ниже содержимым позволит всем участникам из группы AD LinuxAdmins выполнять команды sudo без повторного ввода их паролей:

    
    %LinuxAdmins ALL=(ALL) NOPASSWD: ALL
     	   

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

В своём следующем разделе мы рассмотрим применение службы каталога FreeIPA, которая является естественной для Linux и то как интегрировать её в вашу среду при помощи Ansible.

FreeIPA

FreeIPA является свободно распространяемой службой каталога с открытым исходным кодом, которую просто установить и которой легко управлять. Она работает в Linux и изначально запускается в CentOS или RHEL (Red Hat Enterprise Linux), хотя поддержка клиентов доступна в Ubuntu и прочих платформах Linux. Даже возможна интеграция с Windows AD, хотя она никоим образом и не требуется {Прим. пер.: спорное отверждение: например, можно рассмотреть вариант снижения числа требуемых лицензий Microsoft AD при наличии масштабирования серверов}.

Когда вы строите среду целиком на Linux, имеет смысл рассмотреть FreeIPA в качестве альтернативы размещению частного решения, подобного Microsoft AD.

[Замечание]Замечание

FreeIPA и Microsoft AD ни коим образом не претендуют на два исключительных варианта на рынке служб каталогов и в настоящее время доступен ряд альтернатив на облачной основе, таких как JumpCloud, AWS Directory Service и многие иные. Всегда принимайте наилучшее именно для вас решение, поскольку это поле быстро эволюционирует, в особенности когда речь заходит об облачных службах каталогов.

Как и в отношении предыдущего раздела с Microsoft AD, проектирование и развёртывания FreeIPA выходит за рамки данной книги. Службы каталога являются центральными службами в вашей сетевой среде - представьте себе что вы построили лишь единственный сервер каталога и затем отключили его поддержку. Даже простая перезагрузка оставит пользователей не способными зарегистрироваться во всех машинах, к которым они подключены для продолжения остановленных служб. По этим причинам жизненно важно чтобы вы проектировали инфраструктуру своей службы каталога с учётом избыточности и восстановления после сбоев. Также важно чтобы вы обладали достаточно безопасными локальными учётными записями на случай падения инфраструктуры вашего каталога, как это уже объяснялось ранее в данной главе в разделе, озаглавленном Выполнение задач управления учётными записями пользователя.

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

Данная книга оставляет саму задачу установки инфраструктуры FreeIPA за вами - однако давайте взглянем на применение свободно доступных ролей FreeIPA для установки клиентов в вашей инфраструктуре. Помимо всего прочего, это одно из самых основных преимуществ программного обеспечения с открытым исходным кодом - совместное применение знаний, сведений и кода.

  1. Прежде всего мы клонируем применяемый репозиторий ansible-freeipa в свою локальную машину и изменяем текущий каталог для его применения так:

    
    $ cd ~
    $ git clone https://github.com/freeipa/ansible-freeipa
    $ cd ansible-freeipa
    	   
  2. Затем создаём символические ссылки на только что клонированные нами roles и modules в своей локальной среде Ansible следующим образом:

    
    $ ln -s ~/ansible-freeipa/roles/ ~/.ansible/
    $ mkdir ~/.ansible/plugins
    $ ln -s ~/ansible-freeipa/plugins/modules ~/.ansible/plugins/
    $ ln -s ~/ansible-freeipa/plugins/module_utils/ ~/.ansible/plugins/
    	   
  3. После этого мы обязаны создать некий образец файла описи (inventory), который содержит надлежащие переменные для задания сферы (realm, королевства) и домена FreeIPA, а также значения пароля для своего пользователя admin (которому требуется присоединиться к некому новому серверу в устанавливаемом королевстве IPA). Ниже показан некий пример, но будьте вольны персонализировать его под собственные требования:

    
    [ipaclients]
    centos-testhost
    
    [ipaclients:vars]
    ipaadmin_password=password
    ipaserver_domain=example.com
    ipaserver_realm=EXAMPLE.COM
    	   
  4. Обладая установленными надлежащими переменными и скомпилированной описью мы далее способны запускать предоставляемые плейбуки с тем кодом, который выгружается из GitHub. Вот показан некий пример такого плейбука установки клиента FreeIPA:

     

    Рисунок 10-7



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

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

Принудительная настройка и аудит конфигурации

Когда дело доходит до управления учётными записями пользователя, важна безопасность. Как мы уже обсуждали в разделе, озаглавленном Централизация управления учётными записями пользователя при помощи LDAP, Ansible не заточен конкретно для принудительной настройки или аудита - однако он способен нам здорово помогать. Давайте рассмотрим несколько имеющихся рисков безопасности, связанных с управлением пользователями, которые способен смягчать Ansible, начав с файла sudoers.

Управление sudoers через Ansible

Файл /etc/sudoers является одним из самых чувствительных в большинстве систем Linux, поскольку он определяет какие именно учётные записи способны запускать команды в качестве суперпользователя. Излишне напоминать, что если этот файл будет скомпрометирован или изменён неким не авторизованным образом, это может представлять большой риск безопасности не только в вопросе самого сервера Linux, но также и всей сетевой среды в целом.

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

  • /etc/sudoers: Это основной файл хозяина и он ссылается на все прочие подлежащие рассмотрению файлы.

  • /etc/sudoers.d/*: Эти файлы обычно содержатся в ссылках в основном файле /etc/sudoers.

Как мы уже обсуждали это в Главе 7, Управление настройками при помощи Ansible, некто потенциально может изменить /etc/sudoers и сообщить ему о необходимости содержать совершенно иной путь дополнительно к /etc/sudoers.d/*, что подразумевает жизненно важным чтобы мы развёртывали этот файл через некий шаблон. Это обеспечивает нам контроль над тем какие файлы предоставляют настройку sudo.

Мы не будем повторять свои рассуждения о шаблонах и уровнях разработки с помощью Ansible, так как те технологии, что описаны в Главе 7, Управление настройками при помощи Ansible, применимы и здесь. Тем не менее, мы добавим важное предостережений. Когда вы разбиваете имеющуюся конфигурацию sudo разработав некий файл с (допустим) синтаксической ошибкой в нём, вы рискуете заблокировать всех пользователей для их привилегированного доступа. Это будет означать что единственным способом исправления такой проблемы будет регистрация в данном сервере от имени учётной записи root, а если это отключено (как это установлено по умолчанию в Ubuntu и рекомендуется во многих прочих средах), тогда восстановление вашего пути становится достаточно хитроумным.

Как и во многих прочих случаях, профилактика лучше лечения и применяемый нами ранее модуль шаблона template имеет некую хитрость, способную помочь нам с этим. Когда мы изменяем свой файл sudoers при помощи visudo в некой системе Linux, создаваемый вами файл автоматически проверяется перед его записью на диск. В случае наличия какой- то ошибки вы получите предупреждение и будете обладать возможностью её исправления. Ansible выполняет эту особенность через дополнительный параметр validate в своём модуле template. Таким образом, в первом приближении роль для развёртывания некой новой версии файла sudoers при помощи Ansible может выглядеть так:


---
- name: Copy a new sudoers file on if visudo validation is passed
  template:
    src: templates/sudoers.j2
    dest: /etc/sudoers
    validate: /usr/sbin/visudo -cf %s
 	   

В нашем предыдущем примере наш модуль template передаёт необходимое название самого файла, определяемого в dest для команды в установке параметра validate - именно в этом смысл %s. Если эта проверка проходит, такой получаемый новый файл записывается по месту. Когда проверка неудачна, тогда этот новый файл не записывается и остаётся старый. Кроме того, при отказе проверки данная задача имеет результатом состояние failed, тем самым завершая выполнение воспроизведения и выдавая предупреждение пользователю для исправления этого условия.

[Совет]Совет

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

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

Аудит учётных записей пользователя через Ansible

Допустим, ваше предприятие обладает 1 000 серверов Linux, причём все они применяют для аутентификации службы каталога, которые мы обсудили ранее. Теперь допустим, что некий шальной пользователь, желающий обойти эти полномочия управления, управляет созданием какой- то локальной учётной записи с названием john в отдельном сервере. Это может происходить когда привилегии временно предоставлены для запроса изменения, но затем отзываются - недобросовестные люди легко могут создавать свои собственные методы доступа для обхода той безопасности, которая предоставляется вашей службой каталога.

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

Поскольку все строимые вами серверы обязаны придерживаться некого стандарта (см. Главу 1, Построение стандартной среды работы в Linux), тогда вам следует знать какие учётные записи предполагаются для каждого из серверов Linux. Может оказаться, что будут иметься некие отклонения - например, если вы установили сервер баз данных PostgreSQL, обычно это создаёт некую локальную учётную запись пользователя с названием postgres. Тем не менее, такой случай легко понять и его можно быстро отфильтровать.

Нам даже не следует писать некий плейбук Ansible целиком чтобы помочь нам в этом - раз ы вас имеется некий файл описи с вашим сервером (или серверами) Linux, вы можете запустить то, что носит название команды для данного случая (ad hoc). Это просто команда в одну строку, которую может исполнить любой отдельный модуль Ansible с неким набором параметров - во многом как и некий плейбук со всего одной задачей в нём.

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


$ ansible -i hosts -m shell -a 'cat /etc/passwd' all
		

Это всё что необходимо сделать - Ansible будет добросовестно подключаться ко всем серверам из имеющгося файла описи, определяемого параметром -i и выводить содержимое файла /etc/passwd на свой экран. Вы можете переправить конвейерно этот вывод в какой- то файл для последующих обработки и анализа, вместо того чтобы регистрироваться во всех ящиках. Хотя Ansible в действительности и не выполнит никакого анализа, он представляет собой очень мощный и простой инструмент для осуществления сбора сведений с целью их аудита и, поскольку в этом и состоит прелесть Ansible, не требуется никакой агент в ваших удалённых машинах.

Наш следующий снимок экрана отображает некий пример получения Ansible имеющихся локальных учётных записей пользователей от одной из наших тестовых систем при помощи простой команды grep для фильтрации двух наиболее часто присутствующих учётных записей. Естественно, вы можете расширить данный пример по своему желанию для улучшения обработки сведений, а следовательно для упрощения своих задач:

 

Рисунок 10-8



Таким образом вы можете действенно применять Ansible для сбора полезных сведений из большого числа систем для последующей обработки - поскольку результаты возвращаются обратно непосредственно в сам Терминал, причём их легко коневейеризировать в некий файл, а затем обрабатывать предпочитаемыми вами инструментами (например, AWK) чтобы определять имеются ли какие- то системы выполняющие нарушающие корпоративные политики запросы. несмотря на то, что данный пример выполнен с применением локальных учётных записей пользователей, он также может эффективно применяться для любого заданного текстового файла в удалённых системах.

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

  • Измените написанную нами на данный случай команду и запустите ей вместо этого как некий плейбук.

  • Создайте расписание для данного плейбука для его запуска на регулярной основе в AWX.

  • Измените этот плейбук для проверки на определённые ключевые учётные записи пользователей.

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


$ ansible -i hosts -m shell -a 'grep "authentication failure | cat" /var/log/auth.log' all
		

В CentOS этот журнал событий может быть обнаружен вместо этого в /var/log/secure, а потому вам следует изменять надлежащим образом для этих систем.

[Совет]Совет

Команда grep возвращает код 1 когда найдена предписанная вами строка, а Ansible, наоборот, возвращает его как отказ, сообщая о провале своей задачи. Как результат, мы отправляем конвейером вывод своей команды grep в следующую команду cat, которая всегда возвращает ноль, а следовательно такая задача не откажет, даже когда не найдена указанная нами строка поиска.

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

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

Выводы

Управление учётными записями пользователей и доступом является неотъемлемой частью любой корпоративной среды Linux и Ansible способен выступать ключевым компонентом как в её настройке, так и в развёртывании большого числа серверов. Действительно, в случае FreeIPA уже имеются доступные бесплатно роли Ansible и плейбуки, которые могут устанавливать не только клиенты Linux, но также даже и архитектуру вашего сервера. Тем самым можно достичь автоматизации всех ключевых компонентов вашей инфраструктуры Linux.

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

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

Вопросы

  1. В чём состоят основные преимущества локальных учётных записей пользователей даже когда применяется некая служба каталогов?

  2. Какой модуль применяется для создания учётных записей пользователей в Ansible и манипуляции ими?

  3. Как бы вы могли выработать некий зашифрованный хэш пароля при помощи только Ansible?

  4. Какой пакет применяется для интеграции серверов Linux с AD?

  5. Как вы можете применять Ansible для аудита настроек в группе серверов?

  6. В чём состоит основная цель проверки файла sudoers при его развёртывании из некого шаблона?

  7. Какие дополнительные преимущества предоставляет служба каталога, которые не способен предоставлять Ansible даже несмотря на то, что он способен развёртывать учётные записи пользователей во всех ваших серверах?

  8. Как бы вы сделали выбор между FreeIPA и AD?

Последующее чтение

Для более глубокого понимания Ansible, пожалуйста, обратитесь к третьему изданию Mastering Ansible Джеймса Фримана и Джесса Китинга {Прим. пер.: или к нашему переводу}.

Для намного более глубокого изучения и настройки AD читатели могут обратиться ко второму изданию Mastering Active Directory Джеймса Фримана и Джесса Китинга {Прим. пер.: или к нашему переводу}.