Вкажіть пароль sudo для Ansible


224

Як я можу вказати пароль 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**

Чи є спосіб? Я хочу максимально автоматизувати розгортання проекту.


4
Дивіться також: serverfault.com/questions/560106/…
utapyngo

Відповіді:


169

Ви можете передати змінну в командному рядку через --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
JasonG

2
@scrutari Це цілком справедливо в деяких ситуаціях: Наприклад: перехід від загальновідомого, всесвітньо відомого, початкового пароля, щоб ввести відкритий ключ користувача ssh ... Подумайте про початкову конфігурацію щойно переробленої системи.
Середіг

236

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


Оновлення 2016 року:

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


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, яке надає скоттод, - використовувати рішення Мірчі Вутковичів у поєднанні з ансамблем Ansible .

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

- hosts: all

  vars_files:
    - secret

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

Тут ми включаємо файл, secretякий називається, який буде містити наш пароль sudo.

Ми будемо використовувати ansible-treult для створення зашифрованої версії цього файлу:

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-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


5
Примітка: станом на ansible 1.9, здається, що ви більше не можете використовувати змінну ansible_sudo_pass (або ansible_become_pass): "fatal: [...] => Пропустіть пароль"
toast38coza

6
Я використовую це рішення у виробництві, jenkins зберігає пароль сховища як приховану змінну середовища, записує його під час виконання у тимчасовий файл і переходить до виклику ansible.
simone cittadini

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).


7
Прекрасним способом безпечного налаштування було б зберегти це у каталозі host_varsor або group_varsпотім зашифрувати файл за допомогою ansible-vault
Kyle

44

Я не думаю, що ansible не дозволить вам вказати пароль у прапорах, як ви хочете зробити. Може бути десь у налаштуваннях, це можна встановити, але це зробить використання ansible менш захищеним і не рекомендується.

Одне, що ви можете зробити, - це створити користувача на цільовій машині та надати їм привілеї sudo без паролів для всіх команд чи списку обмежених команд.

Якщо ви запускаєте sudo visudoта вводите рядок, як показано нижче, то користувачеві "privilegedUser" не слід вводити пароль, коли він виконує щось на кшталт sudo service xxxx start:

%privilegedUser ALL= NOPASSWD: /usr/bin/service

7
@bschlueter, щоб ви схвалювали погану практику?
Стефан

1
Я не думаю, що це гарна ідея. Використання --ask-sudo-pass має для мене сенс.
kgpdeveloper

@simone cittadini Я повністю згоден, адже насправді це відповідь, яку я збирався дати. Це ризик для безпеки.
einarc

Це менше ризику для безпеки, якщо ви використовуєте бездоглядний sudo для розгортання для постановки / 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

На групу, у групах ( 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

/ тощо / ansible / господарі:

[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"

як ви впорядковуєте пароль Vault (введіть через --ask-vault-pass) або cfg, залежить від вас

на основі цього я підозрюю, що ви можете просто зашифрувати весь файл хостів ...


Шифрування за допомогою Vault має для мене найбільш сенс, хоча я намагався їх використовувати 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 - очевидно запуск ігрової книги через ansible-playbook
  • $(lpass show folder1/item1 --password)"- запускає CLI 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)"'

Тепер ви можете запустити свою книгу так:

$ 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 .


5

ви можете написати пароль sudo для вашої книжки у файл хостів так:

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'

5

Тут кілька разів пропонували відповідне сховище, але я віддаю перевагу git-crypt для шифрування чутливих файлів у своїх ігрових книгах. Якщо ви використовуєте git для зберігання своїх чутливих ігор, це зовсім нескладно. Проблема, яку я виявив з допомогою ansible treult, полягає в тому, що я неминуче стикаюся із зашифрованими копіями файлу, з яким я хочу працювати, і мені потрібно розшифрувати його, перш ніж я можу працювати. git-cryptпропонує приємніший робочий процес ІМО.

Використовуючи це, ви можете помістити ваші паролі у змінну книгу і позначити свою книгу як зашифрований файл у .gitattributesтакому вигляді:

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

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

Тут є хороші запитання та відповіді щодо gpgключів переадресації, таких як ваші ssh-agentSSH-ключі вперед: /superuser/161973/how-can-i-forward-a-gpg-key-via-ssh-agent .


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

І просто запустіть книжку з цим інвентарем як:

ansible-playbook -i inventory copyTest.yml

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') }}'"

Хороші відповіді:


2

Ви можете використовувати ansible treult, який буде кодувати ваш пароль у зашифрованому сховищі. Після цього ви можете використовувати змінну від сховища в ігрових книгах.

Деяка документація про ansible treult:
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

Так, ми зберігаємо пароль Vault у локальному каталозі у простому тексті, але це не небезпечніше, як зберігати кореневий пароль для кожної системи. Корінний пароль знаходиться у файлі Vault, або ви можете мати його як файл sudoers для вашого користувача / групи.

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



1

Через п’ять років я можу бачити, що це все ще дуже актуальна тема. Дещо дзеркальна відповідь лейкоса, яку я вважаю найкращою у своєму випадку, використовуючи лише інструменти ansible (без будь-якої централізованої автентифікації, лексеми чи будь-чого іншого). Це передбачає, що ви маєте однакове ім’я користувача та однаковий відкритий ключ на всіх серверах. Якщо ви цього не зробите, звичайно, вам потрібно буде бути більш конкретними та додати відповідні змінні поруч із хостами:

[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'

Принаймні таким чином не потрібно більше писати змінні, які вказують на паролі.


1

Над нами розроблено рішення @ toast38coza; якраз це судо: так , в Ansible зараз застаріло. Використовуйте натомість станьте і станьте_ користувачем .

tasks:
 - name: Restart apache service
   service: name=apache2 state=restarted
   become: yes
   become_user: root

0

ми також можемо використовувати ОЧАКВАННЯ БЛОКУ, який відповідає антену, щоб нерестувати баш та налаштувати його відповідно до ваших потреб

- 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

Дякую, але я думаю, ви маєте на увазі ansible_become_pass замість Ansible_become_pass.
Крішном

0

Просто доповнення, тому більше ніхто не переживає роздратування, яке я нещодавно робив:

AFAIK, найкраще рішення - це уздовж загальних ліній тостів38coza, наведених вище. Якщо є сенс статично пов’язати файли паролів і вашу книгу, тоді слідкуйте за його шаблоном vars_files(або include_vars). Якщо ви хочете залишити їх окремими, ви можете надати вміст сховища в командному рядку так:

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

Це очевидно в ретроспективі, але ось ось що:

  1. Цей кривавий знак @ . Якщо ви не залишите його, синтаксичний аналіз буде провалено беззвучно , і програвач ansible-play продовжиться так, ніби ви ніколи не вказували файл в першу чергу.

  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" - ваш userid.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.