Укажите пароль sudo для Ansible

225

Как указать пароль sudo для Ansible неинтерактивным способом?

Я запускаю Ansible playbook следующим образом:

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username --ask-sudo-pass

Но я хочу запустить это так:

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username` **--sudo-pass=12345**

Есть ли способ? Я хочу максимально автоматизировать развертывание моего проекта.

Слава Фомин II
источник
4
См. Также: serverfault.com/questions/560106/…
utapyngo

Ответы:

170

Вы можете передать переменную в командной строке через --extra-vars "name=value". Переменная пароля Sudo есть ansible_sudo_pass. Итак, ваша команда будет выглядеть так:

ansible-playbook playbook.yml -i inventory.ini --user=username \
                              --extra-vars "ansible_sudo_pass=yourPassword"

Обновление 2017 : Ansible 2.2.1.0 теперь использует var ansible_become_pass. Либо, кажется, работает.

Александр никитин
источник
7
С точки зрения безопасности лучший ответ, если вы добавите следующее: history -cпосле выполнения yml.
kiltek
12
@kiltek: или добавьте дополнительный пробел в начале строки (в bash), который не будет * записывать строку в .bash_history.
ccpizza
44
Не рекомендуется передавать пароли в командной строке. Любой сможет увидеть пароль в списке процессов, пока выполняется команда ...
Павел Черников
22
все же, просто не делай этого. --ask-sudo-pass
Джейсон
2
@scrutari В некоторых ситуациях это совершенно справедливо: например, изменить стандартный всемирный пароль по умолчанию, чтобы ввести открытый ssh-ключ пользователя ... Подумайте о первоначальной конфигурации заново перерисованной системы.
Середиг
236

Документы настоятельно рекомендуют не устанавливать пароль sudo в виде открытого текста и использовать вместо этого --ask-sudo-passв командной строке при запускеansible-playbook


Обновление 2016:

Ansible 2.0 (не 100%, когда) помечен --ask-sudo-passкак устаревший. Документы теперь рекомендуют использовать --ask-become-passвместо этого, а также поменять местами использование во sudoвсех ваших книгах с become.

deefour
источник
16
Да, я понимаю, почему это рекомендуется. Однако, когда мы используем Ansible как часть процесса развертывания, как лучше это автоматизировать? Не очень удобно останавливаться в середине процесса развертывания и просить пользователя ввести пароль sudo.
Слава Фомин II
9
Примечание. --Ask-sudo-pass может быть сокращен до -K, однако, насколько я вижу, нет способа обработки книги воспроизведения, запущенной на нескольких серверах с разными паролями (она запрашивает вас только один раз), поэтому я думаю, что она не содержит пароля Судо это путь.
Уильям Туррелл
1
Не похоже на работу. но следующее предложение ("some-host ansible_sudo_pass = 'foobar'")
nadavkav
--ask-sudo-pass устарел ранее, в 1.9
Крис Бетти
Я хотел бы обновить ответ с ссылкой на источник, если у вас есть.
deefour
106

Вероятно, лучший способ сделать это - предполагая, что вы не можете использовать решение NOPASSWD, предоставляемое scottod, - это использовать решение Мирчи Вутковича в сочетании с хранилищем Ansible .

Например, у вас может быть что-то вроде книги:

- hosts: all

  vars_files:
    - secret

  tasks:
    - name: Do something as sudo
      service: name=nginx state=restarted
      sudo: yes

Здесь мы включаем файл с именем, secretкоторый будет содержать наш пароль sudo.

Мы будем использовать ansible-vault для создания зашифрованной версии этого файла:

ansible-vault create secret

Это попросит вас ввести пароль, а затем откройте редактор по умолчанию для редактирования файла. Вы можете поставить свой ansible_sudo_passздесь.

например secret:

ansible_sudo_pass: mysudopassword

Сохраните и выйдите, теперь у вас есть зашифрованный secretфайл, который Ansible может расшифровать при запуске вашей книги воспроизведения. Примечание: вы можете отредактировать файл с помощью ansible-vault edit secret(и ввести пароль, который вы использовали при создании файла)

Последняя часть головоломки - предоставить Ansible файл, --vault-password-fileкоторый он будет использовать для расшифровки вашего secretфайла.

Создайте файл с именем vault.txtи введите пароль, который вы использовали при создании secretфайла. Пароль должен быть строкой, хранящейся как одна строка в файле.

Из Ansible Docs:

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

Наконец: теперь вы можете запустить свою книгу с чем-то вроде

ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt 

Выше предполагается, что следующий макет каталога:

.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt

Вы можете прочитать больше о Ansible Vault здесь: https://docs.ansible.com/playbooks_vault.html

toast38coza
источник
5
Примечание: начиная с ansible 1.9, кажется, что вы больше не можете использовать переменную ansible_sudo_pass (или ansible_become_pass): "fatal: [...] => Missing стать паролем"
toast38coza
6
Я использую это решение в производственной среде, jenkins хранит пароль хранилища в качестве скрытой переменной среды, записывает его во время выполнения во временный файл и переходит к вызову ansible.
Симона Читтадини
6
или проще: ansible-vault create group_vars/all/ansible.ymlи добавь ansible_sudo_pass: yourpasswordтуда. Не нужно менять книжки или инвентарь
Bouke Versteegh
1
Пробовал это, но я получил эту ошибку:fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE", "parsed": false}
JohnnyQ
8
Что хорошего в хранилище, если вы храните пароль в хранилище в виде простого текста рядом с ним?
Эрик
44

Глядя на код ( runner/__init__.py), я думаю, что вы, вероятно, можете установить его в своем файле инвентаризации:

[whatever]
some-host ansible_sudo_pass='foobar'

Похоже, что в ansible.cfgконфигурационном файле есть некоторые условия , но они не реализованы прямо сейчас ( constants.py).

LEUCOS
источник
7
Отличный способ настроить это безопасно - сохранить это в каталоге host_varsили, group_varsа затем зашифровать файл с помощью ansible-vault
Кайл,
44

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

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

Если вы запустите sudo visudoи введете строку, подобную приведенной ниже, то пользователю 'privilegedUser' не нужно будет вводить пароль, когда он запускает что-то вроде sudo service xxxx start:

%privilegedUser ALL= NOPASSWD: /usr/bin/service
scottod
источник
7
@bschlueter, так что вы поддерживаете плохую практику?
Стивен
1
Я не думаю, что это хорошая идея. Использование --ask-sudo-pass имеет для меня смысл.
kgpdeveloper
@ Simone Cittadini Я полностью согласен, так как на самом деле это ответ, который я собирался дать. Это угроза безопасности.
Einarc
Это менее опасно для безопасности, если вы используете sudo без пароля для развертывания в staging / prod, но хотите использовать эти ответы, чтобы пропустить необходимость ввода пароля для входа на локальный ноутбук при развертывании на локальном хосте каждые 15 минут в течение дня каждый день.
Джонатан Хартли,
Как добавить эту строку, используя Ansible?
Матиас
21

Пароль Sudo хранится в переменной с именем ansible_sudo_pass. Вы можете установить эту переменную несколькими способами:

Для каждого хоста в файле инвентаризации хостов ( inventory/<inventoryname>/hosts)

[server]
10.0.0.0 ansible_sudo_pass=foobar

По группе, в вашем файле групп инвентаря ( inventory/<inventoryname>/groups)

[server:vars]
ansible_sudo_pass=foobar

По группе, в группе vars ( group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

За группу, зашифровано ( ansible-vault create group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"
Бук Верстег
источник
18

Вы можете установить пароль для группы или для всех серверов одновременно:

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts

[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1
Мирча Вуцовичи
источник
14

Я рвал на себе волосы, и теперь нашел решение, которое делает то, что я хочу:

1 зашифрованный файл на хост, содержащий пароль sudo

/ и т.д. / анзибль / хосты:

[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa

[some_service_group]
node-0
node-1

затем вы создаете для каждого хоста зашифрованный var-файл примерно так:

ansible-vault create /etc/ansible/host_vars/node-0

с содержанием

ansible_sudo_pass: "my_sudo_pass_for_host_node-0"

как вы организуете пароль хранилища (введите --ask-vault-pass) или cfg зависит от вас

основываясь на этом, я подозреваю, что вы можете просто зашифровать весь файл hosts ...

greenone83
источник
Шифрование с использованием хранилища имеет для меня наибольшее значение, хотя я изо всех сил пытался использовать их ansible-playback. Я должен был использовать, -e @vault/filename.extчтобы использовать хранилище с моим ansible-playbookвызовом.
Алекс
9

Более разумный способ сделать это - сохранить ваш sudoпароль в безопасном хранилище, таком как LastPass или KeePass, а затем передать его с ansible-playbookиспользованием, -e@но вместо жесткого кодирования содержимого в реальном файле вы можете использовать конструкцию -e@<(...)для запуска команды в суб-оболочки и перенаправить его вывод (STDOUT) в анонимный файловый дескриптор, эффективно передавая пароль в -e@<(..).

пример

$ ansible-playbook -i /tmp/hosts pb.yml \
   -e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")

Выше делается несколько вещей, давайте разберемся с этим.

  • ansible-playbook -i /tmp/hosts pb.yml - очевидно запускает playbook через ansible-playbook
  • $(lpass show folder1/item1 --password)"- запускает интерфейс LastPass lpassи получает пароль для использования
  • echo "ansible_sudo_pass: ...password..." - принимает строку ansible_sudo_pass: и объединяет ее с паролем, предоставленным lpass
  • -e@<(..)- объединяет вышеперечисленное и подключает подоболочку <(...)как дескриптор файла для ansible-playbookиспользования.

Дальнейшие улучшения

Если вы не хотите вводить это каждый раз, вы можете просто так делать. Сначала создайте псевдоним в вашем .bashrcвиде:

$ cat ~/.bashrc
alias asp='echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)"'

Теперь вы можете запустить свой playbook следующим образом:

$ ansible-playbook -i /tmp/hosts pb.yml -e@<(asp)

Ссылки

ОДС
источник
1
Использование подоболочки - очень умная идея! Для тех, кто интересуется, вот как это выглядит с CLI 1Password:--extra-vars @<(echo ansible_become_pass: $(op get item <item name> | jq --raw-output '.details.sections[0].fields[] | select(.t=="password").v'))
Дити
1
Мне это нравится, потому что когда я проверял историю Баха, пароль не раскрывался в открытом виде. Вероятно, верно и то, что если включен системный аудит, команда записывается как чтение файла, например, /dev/fd/63так как пароль находится в дескрипторе временного файла, она не раскрывается.
JPvRiel
5

Если вам удобно хранить пароли в текстовых файлах, другой вариант - использовать файл JSON с параметром --extra-vars (обязательно исключите этот файл из системы контроля версий):

ansible-playbook --extra-vars "@private_vars.json" playbook.yml 

Ansible поддерживает эту опцию с версии 1.3 .

sidecarcat
источник
5

Вы можете написать пароль sudo для вашей книги воспроизведения в файле hosts следующим образом:

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'
fawadRafiq
источник
5

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

Используя это, вы можете поместить свои пароли в переменную в своей книге игр и пометить свою книгу как зашифрованный файл .gitattributesследующим образом:

 my_playbook.yml filter=git-crypt diff=git-crypt

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

Хорошие вопросы и ответы по переадресации gpgключей, таких как ваши ssh-agentпереадресованные ключи SSH, здесь: /superuser/161973/how-can-i-forward-a-gpg-key-via-ssh-agent .

user2432419
источник
3

Вы можете использовать sshpassутилиту, как показано ниже,

$ sshpass -p "your pass" ansible pattern -m module -a args \
   -i inventory --ask-sudo-pass
Сэчин
источник
3

Использование ansible 2.4.1.0 и следующие должны работать:

[all]
17.26.131.10
17.26.131.11
17.26.131.12
17.26.131.13
17.26.131.14

[all:vars]
ansible_connection=ssh
ansible_user=per
ansible_ssh_pass=per
ansible_sudo_pass=per

И просто запустите playbook с этим инвентарем как:

ansible-playbook -i inventory copyTest.yml
Hearen
источник
3

Мой способ автоматизировать это состоял в том, чтобы использовать переменную окружения и получать к ней доступ через --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'".

Экспортируйте env var, но избегайте истории bash / shell (добавьте пробел или другие методы). Например:

     export ANSIBLE_BECOME_PASS='<your password>'

Поиск env var при передаче дополнительной ansible_become_passпеременной в ansible-playbook, например:

ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"

Хорошие альтернативные ответы:

JPvRiel
источник
2

Вы можете использовать ansible Vault, который будет кодировать ваш пароль в зашифрованном хранилище. После этого вы можете использовать переменную из хранилища в playbooks.

Некоторая документация по безопасному хранилищу:
http://docs.ansible.com/playbooks_vault.html

Мы используем его как хранилище для каждой среды. Для редактирования хранилища у нас есть команда как:
ansible-vault edit inventories/production/group_vars/all/vault

Если вы хотите вызвать переменную vault, вы должны использовать ansible-playbook с такими параметрами:
ansible-playbook -s --vault-password-file=~/.ansible_vault.password

Да, мы храним пароль хранилища в локальном каталоге в виде простого текста, но это не более опасно, чем хранить пароль root для каждой системы. Root пароль находится внутри файла хранилища, или вы можете использовать его как файл sudoers для вашего пользователя / группы.

Я рекомендую использовать файл sudoers на сервере. Вот пример для группы администраторов:
%admin ALL=(ALL) NOPASSWD:ALL

Maxo
источник
1

Через пять лет я вижу, что это все еще очень актуальная тема. Несколько отражающий ответ leucos, который я считаю лучшим в моем случае, используя только доступные инструменты (без какой-либо централизованной аутентификации, токенов или чего-либо еще). Это предполагает, что у вас одинаковое имя пользователя и один и тот же открытый ключ на всех серверах. Если вы этого не сделаете, конечно, вам нужно быть более конкретным и добавить соответствующие переменные рядом с хостами:

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_private_key_file=home/user/.ssh/mykey
[group]
192.168.0.50 ansible_sudo_pass='{{ myserver_sudo }}'

ansible-vault create mypasswd.yml
ansible-vault edit mypasswd.yml

Добавить:

myserver_sudo: mysecretpassword

Затем:

ansible-playbook -i inv.ini my_role.yml --ask-vault --extra-vars '@passwd.yml'

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

Lethargos
источник
1

Выше решение @ toast38coza работало для меня; просто это sudo: да, в Ansible устарела. Вместо этого используйте становитесь и становитесь_пользователем .

tasks:
 - name: Restart apache service
   service: name=apache2 state=restarted
   become: yes
   become_user: root
ГНАУ
источник
0

Мы также можем использовать EXPECT BLOCK в ansible, чтобы создать bash и настроить его в соответствии с вашими потребностями

- name: Run expect to INSTALL TA
  shell: |
    set timeout 100
    spawn /bin/sh -i

    expect -re "$ "
    send "sudo yum remove -y xyz\n"

    expect "$ "
    send "sudo yum localinstall -y {{ rpm_remotehost_path_for_xyz }}\n"

    expect "~]$ "
    send "\n"

    exit 0
  args:
  executable: /usr/bin/expect
Ашиш Ранджан
источник
0

Очень просто, и только добавить в файл переменной:

Пример:

$ vim group_vars/all

И добавьте это:

Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123
rafaelrms
источник
Спасибо, но я думаю, что вы имеете в виду ansible_become_pass вместо Ansible_become_pass.
Кришном
0

Просто дополнение, так что никто больше не переживает раздражение, которое я недавно сделал:

AFAIK, лучшее решение - это одно из общих соображений вышеупомянутого toast38coza. Если имеет смысл статически связать ваши файлы паролей и игровую книгу вместе, следуйте его шаблону с помощью vars_files(или include_vars). Если вы хотите сохранить их отдельно, вы можете указать содержимое хранилища в командной строке следующим образом:

ansible-playbook --ask-vault-pass -e@<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>

Это очевидно в ретроспективе, но вот ошибки:

  1. Этот кровавый знак @ . Если вы не включите его, синтаксический анализ завершится неудачно , и ansible-playbook будет работать так, как если бы вы никогда не указывали файл в первую очередь.

  2. Вы должны явно импортировать содержимое хранилища либо с помощью командной строки --extra-vars / -e, либо внутри своего кода YAML. --ask-vault-passФлаг ничего сам по себе (кроме запросит у вас значение , которое может или не может быть использована позже) не делать.

Можете ли вы включить ваши "@" и сэкономить час.

Эрик Андерсон
источник
-3

Это сработало для меня ... Создан файл /etc/sudoers.d/90-init-users с NOPASSWD

echo "user ALL=(ALL)       NOPASSWD:ALL" > 90-init-users

где «user» - ваш идентификатор пользователя.

ScottM
источник