Назад | Перейти на главную страницу

Как создать правильное правило sudoer для обработчика Ansible?

Можно ли использовать become в обработчике?

Мы запускаем ansible 2.9.3 на машине RHEL 7.4. У нас есть пользователь, который изменяет некоторые файлы конфигурации для демона (Consul), и мы хотим, чтобы служба перезапустилась после любого изменения конфигурации. У нас есть уведомление в задачах и обработчик.

Файлы модифицируются правильно, обработчик получает уведомление и запускается. Однако правило sudo работает некорректно, поскольку Ansible завершает работу с ошибкой:

"module_stderr": "sudo: a password is required\n"

Когда они запускают его из командной строки, пользователь может запускать любые команды systemctl, которые они хотят, используя команды sudo; например sudo systemctl restart consul и sudo systemctl restart consul.service работают классно. Только обработчик Ansible требует пароль.

Вот наш обработчик:

---

- name: Restart consul
  service:
    name: consul
    state: restarted
  become: yes
  become_user: root
  become_method: sudo

Какая магия в файле sudoers нужна Ansible? Я искал подсказки в ansible -vvv вывод, но единственное, что он мне говорит, это как показано ниже. Похоже, он хочет запустить что-то вроде

sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-hltnfuwykrbhkmyixwzzockacxeosntn ; /usr/bin/python /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py'"'"'

что было бы невозможно поместить в наш файл sudoers. Вот результат работы обработчика:

RUNNING HANDLER [workdir : Restart consul] *****************************************************************************************************
task path: /home/consinstall/bitbucket/workdir/roles/deploy/handlers/main.yml:3
<testhost01> ESTABLISH LOCAL CONNECTION FOR USER: consinstall
<testhost01> EXEC /bin/sh -c 'echo ~consinstall && sleep 0'
<testhost01> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861 `" && echo ansible-tmp-1584133543.53-230020740311861="` echo /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/systemd.py
<testhost01> PUT /home/consinstall/.ansible/tmp/ansible-local-79139pfL0dr/tmpauDoVw TO /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py
<testhost01> EXEC /bin/sh -c 'chmod u+x /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/ /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py && sleep 0'
<testhost01> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-hltnfuwykrbhkmyixwzzockacxeosntn ; /usr/bin/python /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py'"'"' && sleep 0'
<testhost01> EXEC /bin/sh -c 'rm -f -r /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/ > /dev/null 2>&1 && sleep 0'
fatal: [testhost01]: FAILED! => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "daemon_reexec": false, 
            "daemon_reload": false, 
            "enabled": null, 
            "force": null, 
            "masked": null, 
            "name": "consul", 
            "no_block": false, 
            "scope": null, 
            "state": "restarted", 
            "user": null
        }
    }, 
    "msg": "Unable to start service consul: Job for consul.service failed because the control process exited with error code. See \"systemctl status consul.service\" and \"journalctl -xe\" for details.\n"
}
META: ran handlers

NO MORE HOSTS LEFT *******************************************************************************************************************************************

PLAY RECAP ***************************************************************************************************************************************************
testhost01                : ok=2    changed=1    unreachable=0    failed=1    skipped=2    rescued=0    ignored=0   

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

Необходимое правило sudo: запуск произвольных скриптов Python от имени стать_пользователем. Ограничить это практически невозможно, поэтому пользователи Ansible в менее строгих средах, как правило, предоставляют пользователю Ansible sudo для запуска всех.

Альтернативой удаленному входу Ansible ssh-ing и становлению root является запуск воспроизведения из уже привилегированного процесса. Подумайте о клонировании в стиле ansible-pull и запускайте из корневого каталога. Можно стать менее привилегированным пользователем для задач, которые этого не требуют.

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

Еще одна запись об этом: Невозможно использовать ограничение команд sudo в Ansible.