sudo дважды становится методом для Ansible

Вопрос или проблема

Мне нужно разобраться с настройками в “/etc/sudoers”, которые я не могу изменить, потому что серверами управляет другая команда, и они не хотят их менять.

У меня есть доступ к root только через sudo к другой учетной записи. Моя учетная запись может запускать только конкретную команду “sudo su – admin” (никакие дополнительные аргументы не могут быть добавлены). Затем, как пользователь “admin”, я могу выполнять любые команды root с помощью sudo (например, “sudo vi /etc/shadow” и т.д.) или открыть корневую оболочку с помощью “sudo -s” или “sudo su -“, и т.д.

Я хочу выполнять команды и плейбуки Ansible от имени root (например, “become: yes”) на этих серверах с другого сервера, который я контролирую, но это потребует, чтобы Ansible сначала выполнил “sudo su – admin”, а затем запустил обычную команду “sudo”.

Я знаю, что можно создавать собственные методы повышения прав. Это, на мой взгляд, способ решения этой проблемы, но конкретное решение превышает мои возможности. Может кто-то помочь с этим?

Кстати, если это поможет, “NOPASSWD:” установлено для моей учетной записи и “admin” в “/etc/sudoers”.

Вот скрипт на Python, который в конечном итоге решил проблему. Я не писал этот “метод повышения прав”, а скорее мой товарищ по команде и я взяли “метод повышения прав” Ansible и модифицировали его. Он использует переменные окружения оболочки для указания “промежуточного” пользователя, “admin”.

# -*- coding: utf-8 -*-
# Авторские права: (c) 2018, Ansible Project
# Лицензия GNU General Public License v3.0+ (см. COPYING или https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = """
    become: sudoint
    short_description: Sudo с промежуточным пользователем
    description:
        - Это как sudo, но с дополнительными шагами.
    author: Роберт Траллс
    version_added: "2.9"
    options:
        become_intermediate_user:
            description: Пользователь, к которому вы 'повышаетесь' первым для выполнения задачи
            default: root
            ini:
              - section: privilege_escalation
                key: become_intermediate_user
              - section: sudoint_become_plugin
                key: user
            vars:
              - name: ansible_become_intermediate_user
              - name: ansible_sudo__intermediate_user
            env:
              - name: ANSIBLE_BECOME_INTERMEDIATE_USER
              - name: ANSIBLE_SUDO_INTERMEDIATE_USER
        become_user:
            description: Пользователь, к которому вы 'повышаетесь' вторым для выполнения задачи
            default: root
            ini:
              - section: privilege_escalation
                key: become_user
              - section: sudo_become_plugin
                key: user
            vars:
              - name: ansible_become_user
              - name: ansible_sudo_user
            env:
              - name: ANSIBLE_BECOME_USER
              - name: ANSIBLE_SUDO_USER
"""

from ansible.plugins.become import BecomeBase
from ansible.module_utils.six.moves import shlex_quote

class BecomeModule(BecomeBase):

    name="sudoint"

    # сообщения для выявления проблем с запросом пароля
    fail = ('Извините, попробуйте еще раз.',)
    missing = ('Извините, для запуска sudo требуется пароль', 'sudo: требуется пароль')

    def build_become_command(self, cmd, shell):
        super(BecomeModule, self).build_become_command(cmd, shell)

        if not cmd:
            return cmd

        # мы перенаправляем ввод для работы в ситуациях, когда наш пользователь
        # может только "sudo su -" к промежуточному пользователю
        # и не может даже использовать опцию su "-c" для прямого выполнения команды
        return ' '.join([
            'echo',
            shlex_quote(' '.join([
                'sudo su -',
                self.get_option('become_user') or '',
                '-c',
                shlex_quote(' '.join([
                    self._build_success_command(cmd, shell)
                ])),
            ])),
            '| sudo su -',
            self.get_option('become_intermediate_user') or ''
        ])

Вам не нужно изменять /etc/sudoers, ни /etc/sudoers.d/*. Если pam_access.so включен в /etc/pam.d/sshd, чтобы предотвратить вход под учетной записью admin по ssh, добавьте эту строку (с вашим IP или подсетью!) в /etc/security/access.conf:

+:admin:192.168.201.0/24

Сделайте файл неизменяемым для их плейбука

chattr +i /etc/security/access.conf

Скопируйте ваш authorized_keys в ~admin/.ssh/ и сделайте его доступным только для чтения.

Войдите под учетной записью admin.

Ответ или решение

Использование метода «sudo дважды» в Ansible

Введение

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

Описание задачи

Ваша ситуация предполагает следующие условия:

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

Решение

Для решения этой проблемы мы создадим собственный плагин для Ansible, который позволит последовательно использовать sudo дважды. Первый раз — для перехода на пользователя admin, а затем для выполнения команд от имени root.

Реализация плагина

Ниже представлен реализованный код плагина sudoint, который будет обрабатывать двуходовой процесс повышения привилегий:

# -*- coding: utf-8 -*-
from ansible.plugins.become import BecomeBase
from ansible.module_utils.six.moves import shlex_quote

class BecomeModule(BecomeBase):

    name="sudoint"

    def build_become_command(self, cmd, shell):
        super(BecomeModule, self).build_become_command(cmd, shell)

        if not cmd:
            return cmd

        return ' '.join([
            'echo',
            shlex_quote(' '.join([
                'sudo su -',
                self.get_option('become_user') or '',
                '-c',
                shlex_quote(' '.join([
                    self._build_success_command(cmd, shell)
                ])),
            ])),
            '| sudo su -',
            self.get_option('become_intermediate_user') or ''
        ])

Этот код делает следующее:

  • Сначала выполняет sudo su - admin, чтобы переключиться на пользователя admin.
  • Затем выполняет нужную команду с использованием sudo.

Настройка Ansible

Чтобы использовать этот плагин, нужно его зарегистрировать в конфигурации. В вашем ansible.cfg добавьте следующие строки:

[privilege_escalation]
become = yes
become_method = sudoint
become_user = root
become_intermediate_user = admin

Применение

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

- hosts: ваше_имя_хоста
  tasks:
    - name: Запуск команды как root
      command: whoami
      become: yes

Заключение

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

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

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

Капча загружается...