Понимание повышения привилегий
Ansible может использовать существующие системы повышения привилегий, чтобы позволить пользователю выполнять задачи от имени другого пользователя.
- Стать
- Директивы
- Стать и сети
- Стать и Windows
Стать
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, когда вы
becomeroot или не используете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_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 не работает. - По умолчанию пользователь 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