Spec-Zone.ru › Ansible 2.6

Понимание повышения привилегий

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

  • Стать
  • Директивы
    • Переменные подключения
    • Параметры командной строки
    • Для тех, кто использует версии до 1.9, sudo и su всё ещё работают!
    • Ограничения
      • Стать непривилегированным пользователем
      • Поддержка плагинов подключения
      • Только один метод может быть включен на хост
      • Нельзя ограничить повышение привилегий определёнными командами
      • Переменные окружения, заполненные pam_systemd
  • Стать и сети
    • Установка режима включения для всех задач
      • Пароли для режима включения
    • authorize и auth_pass
  • Стать и Windows
    • Права администратора
    • Локальные учётные записи служб
    • Учётные записи без пароля
    • Флаги become
    • Ограничения

Стать

Ansible позволяет вам «стать» другим пользователем, отличным от пользователя, который вошёл в систему (удалённый пользователь). Это делается с помощью существующих инструментов повышения привилегий, таких как sudo, su, pfexec, doas, pbrun, dzdo, ksu, runas, machinectl и другие.

Примечание

До версии 1.9 Ansible в основном позволял использовать sudo и ограниченное использование su, чтобы позволить пользователю входа/удалённому пользователю стать другим пользователем и выполнять задачи, создавать ресурсы с правами второго пользователя. Начиная с Ansible версии 1.9, become заменяет устаревшие sudo/su, оставаясь при этом совместимым со старыми версиями. Эта новая реализация также упрощает добавление других инструментов повышения привилегий, включая pbrun (Powerbroker), pfexec, dzdo (Centrify) и другие.

Примечание

Переменные и директивы become независимы. Например, установка become_user не устанавливает become.

Директивы

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

become
установлено на yes для активации повышения привилегий.
become_user
установлено на пользователя с желаемыми привилегиями — пользователя, которым вы become, НЕ пользователя, с которым вы вошли в систему. НЕ подразумевает become: yes, чтобы его можно было установить на уровне хоста.
become_method
(на уровне плейбука или задачи) переопределяет метод по умолчанию, заданный в ansible.cfg, заданный на sudo/su/pbrun/pfexec/doas/dzdo/ksu/runas/machinectl.
become_flags
(на уровне плейбука или задачи) позволяют использовать определённые флаги для задач или ролей. Обычное использование — изменение пользователя на nobody, когда оболочка задана как no login. Добавлено в Ansible 2.2.

Например, для управления системной службой (которая требует root привилегий), когда подключение выполняется как непривилегированный root пользователь (это использует тот факт, что значение по умолчанию для become_user - root):

- name: Ensure the httpd service is running
  service:
    name: httpd
    state: started
  become: yes

Для выполнения команды как пользователь apache.

- name: Run a command as the apache user
  command: somecommand
  become: yes
  become_user: apache

Для выполнения чего-то как пользователь nobody , когда оболочка nologin:

- name: Run a command as nobody
  command: somecommand
  become: yes
  become_method: su
  become_user: nobody
  become_flags: '-s /bin/sh'

Переменные подключения

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

ansible_become
эквивалент директивы become, решает, использовать ли повышение привилегий.
ansible_become_method
какой метод повышения привилегий следует использовать
ansible_become_user
устанавливает пользователя, которым вы станете с помощью повышения привилегий; не подразумевает ansible_become: yes
ansible_become_pass
устанавливает пароль для повышения привилегий. См. Использование Vault в плейбуках для подробностей о том, как избежать наличия секретов в открытом виде

Например, если вы хотите выполнить все задачи как root на сервере с именем webserver, но можете подключаться только как manager пользователь, вы можете использовать запись в инвентаре следующим образом:

webserver ansible_user=manager ansible_become=yes

Параметры командной строки

--ask-become-pass, -K
запрашивает пароль для повышения привилегий; не подразумевает, что будет использовано become. Обратите внимание, что этот пароль будет использован для всех хостов.
--become, -b выполнять операции с повышением привилегий (пароль не подразумевается)
--become-method=BECOME_METHOD
метод повышения привилегий для использования (по умолчанию=sudo), допустимые значения: [ sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas | machinectl ]
--become-user=BECOME_USER
выполнять операции от имени этого пользователя (по умолчанию=root), не подразумевает --become/-b

Для тех, кто использует версии до 1.9, sudo и su всё ещё работают!

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

Become по умолчанию использует старые настройки/переменные sudo/su, если они существуют, но переопределит их, если вы укажете новые.

Ограничения

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

Стать непривилегированным пользователем

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

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

Проблема возникает, когда become_user - непривилегированный пользователь. Ansible 2.0.x и ниже делают файл модуля общедоступным для чтения в этом случае, так как файл модуля записывается как пользователь, с которым Ansible подключён, но файл должен быть доступен для чтения пользователю, которому Ansible назначен become.

Примечание

В Ansible 2.1 это ограничение сужается: Если подключение выполняется как привилегированный пользователь (root), Ansible 2.1 и выше будут использовать chown для установки владельца файла на непривилегированного пользователя, на которого производится смена. Это означает, что и пользователь, выполняющий подключение, и пользователь, на которого производится смена через become, должны быть непривилегированными, чтобы вызвать эту проблему.

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

Способы решения этой проблемы включают:

  • Используйте pipelining. При включенном конвейере Ansible не сохраняет модуль во временный файл на клиенте. Вместо этого он передает модуль в стандартный ввод удаленного интерпретатора Python. Конвейер не работает для модулей Python, связанных с передачей файлов (например: копирования, получения, шаблона), или для модулей, не являющихся модулями Python.
  • (Доступно в Ansible 2.1) Установите поддержку файловых ACL POSIX.1e на управляемом хосте. Если временная директория на удалённом хосте смонтирована с включёнными POSIX ACL и утилита setfacl находится в удалённой PATH, Ansible будет использовать POSIX ACL для совместного доступа к файлу модуля со вторым пользователем без привилегий вместо того, чтобы делать файл доступным для всех.
  • Не выполняйте действие на удалённой машине, становясь пользователем без привилегий. Временные файлы защищены правами доступа Unix, когда вы become root или не используете become. В Ansible 2.1 и выше права доступа Unix также безопасны, если вы подключаетесь к управляемой машине как root, а затем используете become к пользователю без привилегий.

Предупреждение

Несмотря на то, что файловая система Solaris ZFS имеет файловые ACL, эти ACL не являются файловыми ACL POSIX.1e (вместо этого это NFSv4 ACL). Ansible не может использовать эти ACL для управления разрешениями своего временного файла, поэтому вам может потребоваться allow_world_readable_tmpfiles если удалённые машины используют ZFS.

Изменено в версии 2.1.

В дополнение к дополнительным способам безопасного выполнения этого, Ansible 2.1 также затрудняет неосторожное выполнение небезопасного поведения. В то время как в Ansible 2.0.x и ниже Ansible молча позволял небезопасное поведение, если не удалось найти другой способ обмена файлами с пользователем без привилегий, в Ansible 2.1 и выше Ansible по умолчанию выводит ошибку, если это нельзя сделать безопасно. Если вы не можете внести вышеупомянутые изменения для решения проблемы, и вы решили, что машина, на которой вы работаете, достаточно безопасна для того, чтобы модули, которые вы хотите запустить там, были доступны для всех, вы можете включить allow_world_readable_tmpfiles в файле ansible.cfg. Установка allow_world_readable_tmpfiles изменит это с ошибки на предупреждение и позволит задаче выполняться так же, как и до версии 2.1.

Поддержка плагинов подключения

Методы повышения привилегий также должны поддерживаться используемым плагином подключения. Большинство плагинов подключения будут предупреждать, если они не поддерживают become. Некоторые просто проигнорируют это, так как всегда работают от имени root (тюрьма, chroot и т. д.).

Разрешено только один метод на хост

Методы не могут быть объединены. Вы не можете использовать sudo /bin/su - для получения доступа к пользователю, вам нужно иметь права на выполнение команды от имени этого пользователя в sudo или иметь возможность напрямую переключиться на него (то же самое для pbrun, pfexec или других поддерживаемых методов).

Ограничение повышения привилегий определёнными командами невозможно

Разрешения на повышение привилегий должны быть общими. Ansible не всегда использует определённую команду для выполнения действия, но выполняет модули (код) из временного файла с именем, меняющимся каждый раз. Если у вас есть «/sbin/service» или «/bin/chmod» в качестве разрешённых команд, это приведёт к ошибке в ansible, так как эти пути не будут совпадать с временным файлом, созданным ansible для выполнения модуля.

Переменные окружения, заполненные pam_systemd

Для большинства дистрибутивов Linux, использующих systemd в качестве init, используемые по умолчанию методы become не открывают новую «сессию» в смысле systemd. Поскольку модуль pam_systemd не будет полностью инициализировать новую сессию, у вас могут возникнуть неожиданные результаты по сравнению с обычной сессией, открытой через ssh: некоторые переменные окружения, заданные pam_systemd, в частности XDG_RUNTIME_DIR, не заполняются для нового пользователя, а вместо этого наследуются или просто очищаются.

Это может вызвать проблемы при попытке вызова команд systemd, которые зависят от XDG_RUNTIME_DIR для доступа к шине:

$ echo $XDG_RUNTIME_DIR

$ systemctl --user status
Failed to connect to bus: Permission denied

Чтобы принудительно заставить become открыть новую сессию systemd, которая проходит через pam_systemd, вы можете использовать become_method: machinectl.

Дополнительную информацию см. в этом вопросе по системе systemd.

Become и сети

Начиная с версии 2.6, Ansible поддерживает become для повышения привилегий (вход в enable режим или режим привилегированного выполнения) на всех поддерживаемых Ansible платформах, которые поддерживают режим enable: eos`, ios, и nxos. Использование become заменяет параметры authorize и auth_pass в словаре provider.

Для использования become для повышения привилегий на сетевых устройствах необходимо установить тип подключения либо на connection: network_cli, либо на connection: httpapi. Для получения подробностей см. документацию по параметрам платформ и сетевым модулям.

Вы можете использовать повышенные привилегии только для конкретных задач, для всего выполнения или для всех выполнений. Добавление become: yes и become_method: enable указывает Ansible на вход в режим enable перед выполнением задачи, выполнения или книги задач, где установлены эти параметры.

Если вы видите это сообщение об ошибке, задача, которая его сгенерировала, требует режима enable для успешного выполнения:

Invalid input (privileged mode required)

Для установки режима enable для определённой задачи добавьте become на уровне задачи:

- name: Gather facts (eos)
  eos_facts:
    gather_subset:
      - "!hardware"
  become: yes
  become_method: enable

Чтобы включить режим для всех задач в одном выполнении, добавьте become на уровне выполнения:

- hosts: eos-switches
  become: yes
  become_method: enable
  tasks:
    - name: Gather facts (eos)
      eos_facts:
        gather_subset:
          - "!hardware"

Установка режима enable для всех задач

Часто вам нужно, чтобы все задачи во всех выполнениях выполнялись с привилегиями. Лучше всего это сделать, используя group_vars.

group_vars/eos.yml

ansible_connection: network_cli
ansible_network_os: eos
ansible_user: myuser
ansible_become: yes
ansible_become_method: enable

Пароли для режима enable

Если для входа в режим enable требуется пароль, вы можете указать его двумя способами:

  • указав параметр командной строки --ask-become-pass
  • установив переменную подключения ansible_become_pass

Предупреждение

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

authorize и auth_pass

Ansible всё ещё поддерживает режим enable с connection: local для устаревших книг задач. Чтобы войти в режим enable с connection: local, используйте параметры модуля authorize и auth_pass.

- hosts: eos-switches
  ansible_connection: local
  tasks:
    - name: Gather facts (eos)
      eos_facts:
        gather_subset:
          - "!hardware"
      provider:
        authorize: yes
        auth_pass: " {{ secret_auth_pass }}"

Рекомендуется обновить ваши книги задач для использования become для сетевых устройств enable режима последовательно. Использование словарей authorize и provider будет устаревать в будущем. Для получения подробностей см. документацию по параметрам платформ и сетевым модулям.

Become и Windows

Начиная с Ansible 2.3, become может использоваться на хостах Windows через метод runas. Become на Windows использует ту же конфигурацию инвентаризации и аргументы вызова, что и become на хосте, не являющемся Windows, поэтому настройки и имена переменных такие же, как определены в этом документе.

Хотя become может использоваться для принятия идентичности другого пользователя, существуют и другие варианты его использования с хостами Windows. Важным вариантом использования является обход некоторых ограничений, накладываемых при выполнении на WinRM, таких как ограниченное делегирование сети или доступ к запрещённым системным вызовам, таким как API WUA. Вы можете использовать become с тем же пользователем, что и ansible_user, чтобы обойти эти ограничения и выполнить команды, которые обычно недоступны в сессии WinRM.

Примечание

До Ansible 2.4 become работал только при ansible_winrm_transport установлено либо basic, либо credssp, но начиная с Ansible 2.4 become теперь работает на всех типах транспорта.

Права администратора

Многие задачи в Windows требуют прав администратора для завершения. При использовании метода runas become Ansible попытается выполнить модуль с полными правами, доступными удалённому пользователю. Если не удастся повысить права пользователя, он продолжит использовать ограниченный токен во время выполнения.

До Ansible 2.5 токен можно было повысить только тогда, когда UAC был отключён или удалённый пользователь имел SeTcbPrivilege назначенное значение. Это ограничение было снято в Ansible 2.5, и пользователь, являющийся членом группы BUILTIN\Administrators, должен иметь повышенный токен во время выполнения модуля.

Чтобы определить тип токена, который Ansible смог получить, выполните следующую задачу и проверьте вывод:

- win_whoami:
  become: yes

В разделе GROUP INFORMATION, запись Mandatory Label определяет, имеет ли пользователь права администратора. Вот метки, которые могут быть возвращены и что они означают:

  • Medium: Ansible не смог получить повышенный токен и выполнил под ограниченным токеном. Только подмножество прав, назначенных пользователю, доступно во время выполнения модуля, и у пользователя нет прав администратора.
  • High: Использовался повышенный токен, и все права, назначенные пользователю, доступны во время выполнения модуля.
  • System: Используется учётная запись NT AUTHORITY\System и она имеет максимальный уровень доступных привилегий.

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

Если используется версия Ansible, более старая, чем 2.5, или стандартный процесс эскалации runas завершается неудачно, то повышенный токен можно получить, выполнив:

  • Установите become_user на System, который имеет полный контроль над операционной системой.
  • Предоставьте SeTcbPrivilege пользователю, с которым Ansible подключается через WinRM. SeTcbPrivilege — это привилегия высокого уровня, предоставляющая полный контроль над операционной системой. По умолчанию пользователю эта привилегия не предоставляется, и следует проявлять осторожность при предоставлении её пользователю или группе. Для получения дополнительной информации об этой привилегии, обратитесь к Действовать от имени операционной системы. Вы можете использовать задачу ниже, чтобы установить эту привилегию на хосте Windows:

    - name: grant the ansible user the SeTcbPrivilege right
      win_user_right:
        name: SeTcbPrivilege
        users: '{{ansible_user}}'
        action: add
    
  • Отключите UAC на хосте и перезагрузите его перед попыткой стать пользователем. UAC — это протокол безопасности, предназначенный для запуска учетных записей с принципом least privilege. Вы можете отключить UAC, выполнив следующие задачи:

    - name: turn UAC off
      win_regedit:
        path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system
        name: EnableLUA
        data: 0
        type: dword
        state: present
      register: uac_result
    
    - name: reboot after disabling UAC
      win_reboot:
      when: uac_result is changed
    

Примечание

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

Учетные записи локальных служб

До версии Ansible 2.5 become работало только с учетными записями локальных или доменных пользователей. Учетные записи локальных служб, такие как System или NetworkService, не могли использоваться в качестве become_user в этих более старых версиях. Это ограничение было снято с момента выпуска Ansible 2.5. Три учетные записи служб, которые могут быть установлены в become_user, следующие:

  • System
  • NetworkService
  • LocalService

Поскольку учетные записи локальных служб не имеют паролей, параметр ansible_become_password не требуется и игнорируется, если указан.

Учетные записи без пароля

Предупреждение

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

Ansible может использоваться для получения прав учетной записи без пароля (например, учетной записи Guest). Чтобы получить права учетной записи без пароля, настройте переменные как обычно, но либо не определяйте ansible_become_pass, либо установите ansible_become_pass: ''.

Прежде чем become сможет работать с такой учетной записью, необходимо отключить локальную политику Учетные записи: ограничить использование пустых паролей локальными учетными записями только для входа в консоль. Это можно сделать с помощью объекта групповой политики (GPO) или с помощью этой задачи Ansible:

- name: allow blank password on become
  win_regedit:
    path: HKLM:\SYSTEM\CurrentControlSet\Control\Lsa
    name: LimitBlankPasswordUse
    data: 0
    type: dword
    state: present

Примечание

Это относится только к учетным записям без паролей. Вам по-прежнему необходимо установить пароль учетной записи в ansible_become_pass, если у become_user есть пароль.

Флаги become

Ansible 2.5 добавляет параметр become_flags к методу become runas. Этот параметр можно установить, используя директиву задачи become_flags или в конфигурации Ansible с помощью ansible_become_flags. Две поддерживаемые значения этого параметра — logon_type и logon_flags.

Примечание

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

Ключ logon_type задаёт тип операции входа. Значение может быть установлено на одно из следующих:

  • interactive: Тип входа по умолчанию. Процесс будет выполняться в контексте, аналогичном выполнению процесса локально. Это обходит все ограничения WinRM и является рекомендуемым методом.
  • batch: Выполняет процесс в контексте пакетного файла, аналогичном запланированной задаче с установленным паролем. Это должно обойти большинство ограничений WinRM и полезно, если become_user не может входить в систему интерактивно.
  • new_credentials: Выполняет процесс с теми же учетными данными, что и вызывающий пользователь, но исходящие подключения выполняются в контексте become_user и become_password, аналогично runas.exe /netonly. Флаг logon_flags также должен быть установлен на netcredentials_only. Используйте этот флаг, если процесс должен получить доступ к сетевому ресурсу (например, сетевому ресурсу SMB) с использованием другой набора учетных данных.
  • network: Выполняет процесс в сетевом контексте без кэшированных учетных данных. Это приводит к тому же типу сеанса входа, что и выполнение обычного процесса WinRM без делегирования учетных данных, и работает с теми же ограничениями.
  • network_cleartext: Подобно типу входа network, но вместо этого кеширует учетные данные, чтобы иметь доступ к сетевым ресурсам. Это тот же тип сеанса входа, что и выполнение обычного процесса WinRM с делегированием учетных данных.

Дополнительную информацию см. в dwLogonType.

Ключ logon_flags определяет, как Windows выполнит вход пользователя при создании нового процесса. Значение может быть установлено в пустое значение или несколько из следующих:

  • with_profile: Установлен флаг входа по умолчанию. Процесс загрузит профиль пользователя в ключ реестра HKEY_USERS в HKEY_CURRENT_USER.
  • netcredentials_only: Процесс будет использовать тот же токен, что и вызывающий пользователь, но при обращении к удалённому ресурсу будут использоваться become_user и become_password. Это полезно в междоменных сценариях, где нет отношений доверия, и должно использоваться с new_credentials logon_type.

По умолчанию logon_flags=with_profile установлен, если профиль не должен загружаться, установите logon_flags=, или если профиль должен быть загружен с netcredentials_only, установите logon_flags=with_profile,netcredentials_only.

Дополнительную информацию см. в dwLogonFlags.

Вот несколько примеров использования become_flags с задачами Windows:

- name: copy a file from a fileshare with custom credentials
  win_copy:
    src: \\server\share\data\file.txt
    dest: C:\temp\file.txt
    remote_src: yex
  vars:
    ansible_become: yes
    ansible_become_method: runas
    ansible_become_user: DOMAIN\user
    ansible_become_pass: Password01
    ansible_become_flags: logon_type=new_credentials logon_flags=netcredentials_only

- name: run a command under a batch logon
  win_whoami:
  become: yes
  become_flags: logon_type=batch

- name: run a command and not load the user profile
  win_whomai:
  become: yes
  become_flags: logon_flags=

Ограничения

Учитывайте следующие ограничения при использовании become в Windows:

  • Запуск задачи с async и become в Windows Server 2008, 2008 R2 и Windows 7 не работает.
  • По умолчанию пользователь become входит с интерактивным сеансом, поэтому он должен иметь право на это на хосте Windows. Если он не наследует привилегию SeAllowLogOnLocally или наследует привилегию SeDenyLogOnLocally, процесс become завершится ошибкой. Либо добавьте привилегию, либо установите флаг logon_type для изменения типа входа.
  • До версии Ansible 2.3 become работал только в том случае, когда ansible_winrm_transport было либо basic, либо credssp. Это ограничение было снято с момента выпуска Ansible 2.4 для всех хостов, за исключением Windows Server 2008 (без версии R2).

См. также

Список рассылки
Вопросы? Помощь? Идеи? Обратитесь к списку на Google Groups
webchat.freenode.net
#ansible IRC чат-канал

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.6/user_guide/become.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API