Автоматизация начальной настройки сервера

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

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

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

Требования

Для выполнения этого туториала понадобится:

  • Главная нода управления Ansible: машина Rocky Linux с установленным Ansible и настроенная для подключения к хостам Ansible с помощью ключей SSH. Убедитесь, что на главной ноде есть пользователь sudo и включенный брандмауэр, как описано в этом мануале. Для настройки Ansible ознакомьтесь с этим мануалом. Обычно никто не устанавливает одну и ту же версию Linux в рамках одной машины (например, в нашем случае мы ставим Rocky Linux 9 на целевую машину с Rocky Linux 9), но в этом мануале мы сделаем это просто для примера.
  • Удаленный сервер со свежей установкой Rocky Linux: предварительная настройка на этом сервере не требуется, но главная нода должна иметь SSH-доступ к этому серверу. Если у вас нет SSH-доступа, ознакомьтесь с этим мануалом. Этот удаленный сервер мы и будем настраивать автоматически с помощью главной ноды.

Что делает плейбук (playbook)?

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

Запуск плейбука выполнит на хостах Ansible следующие действия:

  1. Создаст нового пользователя sudo и настроит запуск sudo без пароля.
  2. Скопирует локальный открытый ключ SSH и включит его в файл authorized_keys нашего нового административного пользователя на удаленном хосте (если ранее вы использовали пароль для SSH).
  3. Отключит парольную аутентификацию для пользователя root.
  4. Установит системные пакеты.

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

Для начала на главной ноде Ansible войдите как пользователь sudo.

1: Подготовка главной ноды Ansible

На главной ноде добавьте IP удаленного сервера хоста Ansible в файл инвентаризации Ansible. Откройте этот файл с помощью редактора vi:

sudo vi /etc/ansible/hosts

Команда откроет файл инвентаризации Ansible. Добавьте IP-адрес удаленного сервера Ansible в блок [servers]:

[servers]
server1 ansible_host=your_remote_server_ip
. . .

Сохраните и закройте файл.

Теперь нужно проверить и аутентифицировать SSH-соединение между главной нодой Ansible и удаленным хостом Ansible:

ssh root@your_remote_server_ip

Примите запрос на аутентификацию и, если появится запрос, введите пароль. После проверки SSH-соединения нажмите CTRL+D, чтобы закрыть соединение и вернуться к главной ноде.

2: Подготовка плейбука

В файле playbook.yml определяются все задачи. Задача — это наименьшая единица действия, которую можно автоматизировать с помощью плейбука Ansible. С помощью vi создадим файл плейбука:

vi playbook.yml

Откроется пустой файл YAML. Прежде чем добавлять задачи в плейбук, поместите в начало файла:

---
- hosts: all
  become: true
  vars:
    created_username: 8host

Замените имя пользователя на свое.

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

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

Примечание: Если вам нужен готовый файл плейбука, просто перейдите к разделу 6. Файлы YAML могут отличаться структурой отступов, поэтому рекомендуем перепроверить плейбук после добавления всех задач.

3: Создание пользователя sudo

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

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

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

tasks:
    - name: Setup passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s' 

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ created_username }}"
        state: present
        groups: wheel
        append: true
        create_home: true

Модуль Ansible lineinfile применяется для поиска и замены определенной строки в файле. В данном случае с помощью regex выполняется поиск строки в файле sudoers, а плейбук изменяет строку, чтобы разрешить использовать sudo без пароля. С помощью visudo мы проверяем изменения.

Модуль user добавляет нового пользователя. Ansible создаст пользователя (если его ещё нет), добавит в группу wheel (admin), не удаляя его при этом из других групп, а также создаст каталог home.

Примечание. Убедитесь, что вы включили кавычки вокруг фигурных скобок переменной. Отсутствие кавычек — очень распространенная синтаксическая ошибка Ansible.

4: Настройка SSH-ключей

Ansible предполагает, что в своей работе вы используете ключи SSH. Настоятельно рекомендуется при использовании таких ключей отключать парольную аутентификацию для root. Для автоматизации этой задачи добавьте в плейбук:

- name: Set authorized key for remote user
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

Модуль author_key можно применить, если вы указываете имя пользователя и расположение ключа. Путь к ключу устанавливается с помощью функции lookup.

Модуль lineinfile применяется для поиска и замены строки в sshd_config, чтобы отключить аутентификацию по паролю для root, ограничивая доступ к его привилегиям для повышения безопасности.

5: Установка пакетов

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

- name: Update and install required system packages
      dnf:
        pkg:
          - curl
          - vim
          - git
          - firewalld
        state: latest
        update_cache: true

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

6: Готовый плейбук

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

---
- hosts: all
  become: true
  vars:
    created_username: 8host

  tasks:
    - name: Setup passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s'

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ created_username }}"
        state: present
        groups: wheel
        append: true
        create_home: true

    - name: Set authorized key for remote user
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

    - name: Update and install required system packages
      dnf:
        pkg:
          - curl
          - vim
          - git
          - firewalld
        state: latest
        update_cache: true

Примечание. Напоминаем, что нужно следить за отступами. Если при запуске плейбука возникает ошибка, то, скорее всего, причина — в неправильно поставленных отступах. YAML предлагает ставить в качестве отступа 2 пробела, как показано в данном примере.

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

7: Запуск плейбука

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

С помощью следующей команды мы можем запустить плейбук можно, подключившись как root только к серверу server1:

ansible-playbook playbook.yml -l server1 -u root -k

Флаг -l указывает сервер, а флаг -u — пользователя, под которым нужно войти на удаленный сервер. Сейчас пользователь root — единственный доступный нам вариант, поскольку удаленный сервер ещё не настроен. Флаг -k необходим, если вы используете SSH с паролем: он запросит пароль SSH.

Получим следующий вывод:

. . .

PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
server1                    : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

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

Теперь, когда настройка плейбука завершена, все последующие вызовы ansible можно выполнять от пользователя 8host (и без флага -k, если вы изначально использовали пароль):

ansible-playbook playbook.yml -l server1 -u 8host

Войти на сервер можно с помощью:

ssh 8host@your_remote_server_ip

Не забудьте заменить 8host именем пользователя, которое указано в переменной created_username, а server_host_or_IP на hostname или IP-адрес сервера.

Подводим итоги

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

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

Ознакомьтесь с этим мануалом, чтобы узнать, как запускать плейбуки Ansible.

Добавить комментарий