Понимание повышения привилегий
Ansible может использовать существующие системы повышения привилегий, чтобы позволить пользователю выполнять задачи от имени другого пользователя.
- Стать другим пользователем
- Директивы
- Стать другим пользователем и сети
- Стать другим пользователем и Windows
Стать другим пользователем
Ansible позволяет «стать» другим пользователем, отличным от пользователя, который вошёл в систему (удаленный пользователь). Это делается с использованием существующих инструментов повышения привилегий, таких как sudo, su, pfexec, doas, pbrun, dzdo, ksu, runas и другие.
Примечание
До версии 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: 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 в playbooks для получения подробностей о том, как избежать использования секретов в открытом виде
Например, если вы хотите выполнить все задачи от имени 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 по-прежнему работают!
Для тех, кто использует старые playbooks, не нужно ничего менять, даже несмотря на то, что они устарели, директивы, переменные и опции 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, связанных с передачей файлов (например: copy, fetch, template), или для модулей, не являющихся модулями Python. - (Доступно в Ansible 2.1) Установите поддержку POSIX.1e ACL файловой системы на управляемом хосте. Если временная директория на удалённом хосте смонтирована с поддержкой POSIX ACL и утилита setfacl находится в удалённом
PATH, то Ansible будет использовать POSIX ACL для совместного использования файла модуля со вторым неу привилегированным пользователем, вместо того, чтобы делать файл читаемым для всех. - Не выполняйте действие на удалённой машине, становясь неу привилегированным пользователем. Временные файлы защищены разрешениями файлов UNIX, когда вы
becomeroot или не используетеbecome. В Ansible 2.1 и выше разрешения файлов UNIX также безопасны, если вы подключаетесь к управляемому компьютеру как root и затем используетеbecomeк неу привилегированному аккаунту.
Предупреждение
Хотя файловая система Solaris ZFS имеет файловые ACL, эти ACL не являются POSIX.1e файловыми ACL (они являются 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 или привилегированный режим EXEC) на всех поддерживаемых 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"
Установка режима включения для всех задач
Часто вы хотите, чтобы все задачи во всех заданиях выполнялись в режиме с повышенными привилегиями, это лучше всего достигается с помощью 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, вы можете указать его двумя способами:
- указав параметр командной строки
--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: ''.
Прежде чем вход будет работать с такой учетной записью, необходимо отключить локальную политику Учетные записи: Ограничение использования локальными учетными записями пустых паролей только для входа в консоль. Это можно сделать либо с помощью объекта групповой политики (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 войдет в систему пользователя при создании нового процесса. Значение может быть установлено на none или на несколько из следующих:
-
with_profile: Установлен флаг входа по умолчанию. Процесс загрузит профиль пользователя в реестреHKEY_USERSключу, чтобыHKEY_CURRENT_USER. -
netcredentials_only: Процесс будет использовать тот же токен, что и вызывающий, но будет использоватьbecome_userиbecome_passwordпри доступе к удаленному ресурсу. Это полезно в сценариях междоменных взаимодействий, где нет доверия, и должно использоваться сnew_credentialslogon_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 работает только при использовании Ansible 2.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.7/user_guide/become.html