Групповые политики Linux средствами Puppet

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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

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

Для управления конфигурациями устройств в своей организации я выбрал Puppet.

Puppet сам по себе – отличный инструмент для управления небольшим количеством серверов. С помощью puppet DSL мы можем описать и сконфигурировать практически любую задачу. Вот здесь есть хорошая статья о puppet – Введение в Puppet.

Недостаток чистого Puppet – это способ выбора ноды (цели) для конфигурирования. Каждый манифест конфигурации начинается с селектора цели, к которой он будет применён. Цель можно описать точно по имени хоста, регулярным выражением или ключевым словом default – для всех остальных. Проблема в том, что для каждой ноды будет выбран только один, наиболее специфичный манифест. Мы не можем, например, описать некие общие правила для всех хостов в манифесте default, а затем добавить к этим правилам некоторые корректировки только нужным компьютерам. С таким поведением можно мирится, если нужно управлять небольшим количеством нод, но если их становится больше, то нужно что-то делать.

Для управления большим количеством нод тоже есть решения – например Hiera. С помощью Hiera можно гибко управлять большим парком серверов, назначая им функционал и роли. При использовании Hiera вся логика выносится в отдельные модули, а сама система занимается построением файла конфигурации, состоящим из применяемых классов и параметров. Подробнее об использовании Hiera можно почитать тут – Puppet+Hiera. Выжимаем максимум.

Но использование Hiera предполагает, что роли и назначение серверов заранее известно. В случае, когда речь идёт о клиентских машинах, как правило, невозможно определить их функционал заранее. Хочется получить способ динамически управлять конфигурацией компьютера, желательно основываясь на информации, полученной из Active Directory.

Для гибкой настройки конфигураций в Puppet применяется специальный механизм – внешний классификатор узлов (ENC). Если сильно упростить, то внешний классификатор – это программа или скрипт, принимающий в качестве параметра имя компьютера, и отдающая через стандартный вывод конфигурацию, описанную в формате yaml.

Combenc

Воспользовавшись этим механизмом мною на python в муках был рождён внешний классификатор, названный Combenc. Механизм работы связки Puppet + Combenc можно описать примерно так:

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

  2. Сервер запускает Combenc, передавая в качестве параметра имя компьютера.

  3. Combenc получает из Active Directory список групп безопасности, в которых состоит компьютер и пользователь. Обычно в группы включается пользователи, но так как Puppet управляет только хостами, мне был нужен способ привязать пользователя к компьютеру. Для связывания я заполняю атрибут Управляется у объекта компьютера в Active Directory.

  4. Далее классификатор читает:

    1. файл конфигурации, задающий правила для всех нод;

    2. файлы конфигураций, соответствующие именам групп безопасности;

    3. файл, соответствующий имени компьютера.

  5. Затем Combenc комбинирует файлы конфигураций.  Файлы конфигурации представляют собой yaml файлы, состоящие из структуры с именами классов и применяемых к классам параметров. Кроме своих параметров классы могут обладать булевыми параметрами merge и sealed. При использовании параметра merge Combenc будет пытаться объединить списки и словари конфигураций. При использовании параметра sealed класс будет «запечатан» и не будет переопределён, если встретится далее в файлах конфигураций.

  6. В результате полученный конфиг применяется к компьютеру.

Как этим воспользоваться

Я предполагаю, что у Вас уже настроен puppet-сервер, к которому подключено некоторое количество нод.

  1. Сперва разместим классификатор на сервере с Puppet. Создадим папку /opt/combenc/ и расположим в ней скрипты Combenc:

    mkdir /opt/combenc
    cd /opt/combenc
    git clone https://github.com/nsuslov/combenc.git .
  2. После скачивания не забываем дать права на запуск:

    chmod +x /opt/combenc/combenc.py
  3. Далее необходимо заполнить конфигурационный файл config.yaml:

    ldap:
      uri: 'ldap://ns01.example.com'
      user: 'CN=puppet,CN=Users,DC=example,DC=com'
      cred: 'Pa$$word'
      base_dn: 'OU=00-Unit,DC=example,DC=com'
    rules:
      folder: '/etc/puppetlabs/code/environments'
    environments:
      dev:
        - my-pc.example.com
      test:
        - 00-pc-01.example.com
        - 00-pc-02.example.com
    • ldap.uri – адрес одного из наших контроллеров домена;

    • ldap.user, user.cred – уникальное имя (dn) и пароль пользователя, которым мы будем забирать данные с ldap-сервера;

    • ldap.base_dn – начальная точка для поиска компьютеров. Позволяет ограничить поиск определённым организационным юнитом;

    • rules.folder – это каталог, в котором будут располагаться окружения. Я предпочитаю хранить в окружении вместе папку modules – описание логики применяемых конфигураций и combenc – описания конфигураций с параметрами;

    • environments – здесь могут быть словари с названием окружения и массивом нод, которые в него входят. Компьютеры, для которых не указано специфическое окружение, работают в окружении production. Я предпочитаю схему с тремя окружениями: development – моё окружение для разработки, testing – небольшая группа компьютеров для тестирования конфигураций перед внедрением в прод, production – все остальные.

  4. Затем нужно настроить сервер puppet для использования Combenc. Для этого в конфиге /etc/puppetlabs/puppet/puppet.conf нужно добавить следующие строки и перезапустить сервис puppetserver:

    [master]
    node_terminus = exec
    external_nodes = /opt/combenc/combenc.py

В целом на этом настройка закончена. Теперь можно написать какой-нибудь модуль и применить его.

Пример модуля Puppet

Предположим, у нас есть следующая задача: мы хотим дать возможность пользователям группы domain-admins подключаться по ssh ко всем компьютерам, а пользователям группы 01-unit-admins подключаться к компьютерам, входящим в группу 01-computers.

  1. Создадим в /etc/puppetlabs/code/environments/production/modules каталог sshd.

    mkdir -p /etc/puppetlabs/code/environments/production/modules/sshd
  2. Перейдём в него и создадим нужную нам структуру папок:

    cd /etc/puppetlabs/code/environments/production/modules/sshd
    mkdir {manifests,templates}
  3. Теперь создадим файл manifests/init.pp со следующим содержимым:

    # Class: sshd
    #
    # Настройка sshd
    #
    # @param groups Группы, имеющие право подключаться по ssh
    #
    # @param merge Объединить правила. Combenc объединит список, 
    #        если правило встретится ниже
    # @param sealed Запечатать правило. Combenc не переопределит это правило, 
    #        если оно встретится ниже
    #
    class sshd (
      Array[String] $groups,
    
      Boolean $merge = false,
      Boolean $sealed = false,
    ) {
      $groups_line = join($groups, ' ')
    
      file { 'sshd config':
        path    => '/etc/ssh/sshd_config.d/10-puppet.conf',
        content => template('sshd/puppet.erb'),
      }
    
      service { 'sshd service':
        ensure    => running,
        name      => 'sshd',
        enable    => true,
        subscribe => File['sshd config'],
      }
    }

    Этот класс создаст файл /etc/ssh/sshd_config.d/10-puppet.conf по шаблону и перезапустит сервис sshd, если файл 10-puppet.conf был изменен.

  4. Добавим шаблон templates/puppet.erb:

    # Puppet sshd
    # DONT EDIT THIS FILE
    
    <% if (@groups_line) -%>
    AllowGroups <%= @groups_line %>
    <% end -%>

Модуль готов. Теперь напишем правила, согласно которым этот класс будет применяться к компьютерам.

Пример правила Combenc

  1. Создадим каталог с правилами – /etc/puppetlabs/code/environments/production/combenc

    mkdir -p /etc/puppetlabs/code/environments/production/combenc
  2. Затем перейдём в него и создадим нужные папки: groups – для конфигураций групп безопасности и hosts – для конфигураций, применяемых к конкретным хостам.

    cd /etc/puppetlabs/code/environments/production/combenc
    mkdir {groups,hosts}
  3. Создадим общее правило для всех хостов defautl.yaml со следующим содержимым:

    sshd:
      merge: true
      groups:
        - domain-admins
  4. Теперь создадим правило для группы компьютеров groups/01-computers.yaml:

    sshd:
      groups:
        - 01-unit-admins
  5. Предположим, мы хотим дать возможность подключаться к компьютеру 01-pc-34 ещё и локальному пользователю user. Создадим файл hosts/01-pc-34.example.com.yaml со следующим содержимым:

    sshd:
      groups:
        - user

В результате Combenc должен сформировать конфиг для компьютеров объединив правила. Убедимся в этом вызвав скрипт и предав ему dns имя компьютера в качестве параметра:

/opt/combenc/combenc.py 01-pc-34.example.com

Команда вернёт следующий вывод:

classes:
  sshd:
    groups:
    - domain-admins
    - 01-unit-admins
    - user
environment: production

При следующем обращении компьютеров к puppet-серверу эта конфигурация будет применена. 

В результате мы должны добавить такую структуру файлов:

├── combenc
│   ├── default.yaml
│   ├── groups
│   │   └── 01-computers.yaml
│   └── hosts
│       ├── 01-pc-34.example.com.yaml
└── modules
    └── sshd
        ├── manifests
        │   └── init.pp
        └── templates
            └── puppet.erb

Вот такое решение мы используем в нашем предприятии. При желании дополнительно к группам безопасности из ldap можно тащить ещё и структуру организационных юнитов. Таким образом опыт использования будет ещё ближе к привычному GPO, однако мне показалось удобнее пользоваться группами безопасности. 

Спасибо за внимание! Жду предложения, идеи, критику и прочую обратную связь в комментариях. 

Репозиторий Сombenc

Источник: https://habr.com/ru/articles/742718/


Интересные статьи

Интересные статьи

В первой части были рассмотрены системные настройки масштабирования предоставляемые встроенными утилитами, и набор возможностей отличается кардинально. Почему? Потому что в Linux нет единого API для ...
Linux — это операционная система с открытым исходным кодом, которая широко используется на различных устройствах, включая серверы, ПК  и встроенные системы. Важно обеспечить безопасность систем L...
Мой скрипт, с помощью которого я делаю бэкапы в LinuxОбожаю UNIX-way, тут бэкапы можно делать значительно более гибкими.Для бэкапа home директории я использую обычный tar с инкрементацией и шифрую ег...
Так как предыдущая статья зашла довольно хорошо, было бы неправильно не поделиться дополнительными утилитами, которые я использую и по сей день. Сразу хочу оговориться, что статья адаптирована ...
В этом дайджесте читайте: коллекторы планируют получить доступ к национальной базе телефонов россиян; Mozilla решила заменить Firefox для Android; Линус Торвальдс представил ядро Linu...