@Seboreia

Как запускать ansible playbooks с ограниченным sudo?

Приветствую!
Возникла проблема с элементарными операциями, выполняемыми через ansible. Есть несколько машин с ограниченными sudo правами:
[user1@vm02 ~]$ sudo -l
[sudo] password for user1:
Matching Defaults entries for user1 on this host:
group_plugin=/opt/quest/lib64/libsudo_vas.so, requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS",
env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME
LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User user1 may run the following commands on this host:
(root) /bin/traceroute *
(root) /usr/sbin/tcpdump *
(root) /bin/su - user2
(user2) ALL
(root) /bin/su - user2, (root) /bin/su - zabbix
(root) /bin/systemctl * nginx*, (root) /bin/systemctl * keepalived*, (root) /bin/systemctl * mongod*, (root) /bin/systemctl * zabbix*, (root) /bin/nginx-ha-setup
(root) /bin/systemctl * rabbitmq-server*, (root) /bin/systemctl * svnserve*, (root) /bin/systemctl * httpd*, (root) /bin/systemctl * tomcat-*
(zabbix) ALL
(docker) ALL
(etcdctl) ALL
(root) /bin/systemctl * haproxy*
И, соотвественно, для user2:
[user2@vm02 ~]$ sudo -l
Matching Defaults entries for user2 on this host:
group_plugin=/opt/quest/lib64/libsudo_vas.so, requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS",
env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME
LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User user2 may run the following commands on this host:
(root) /bin/traceroute *
(root) /usr/sbin/tcpdump *
(root) NOPASSWD: /usr/bin/systemctl * kube-apiserver, (root) /usr/bin/systemctl * kube-controller-manager, (root) /usr/bin/systemctl * kube-scheduler, (root)
/usr/bin/systemctl * kube-proxy, (root) /usr/bin/systemctl * kubelet, (root) /usr/bin/systemctl * docker, (root) /usr/bin/systemctl * flanneld, (root)
/usr/bin/systemctl * etcd, (root) /usr/bin/systemctl * nginx
(root) NOPASSWD: /data/nginx_kill_hup.sh
Откуда столько наркомании - вопрос не ко мне, такова политика внутри компании...
Краткая суть: я могу выполнять только часть команд из-под пользователя user1 (и только с вводом пароля) и часть команд из-под пользователя user2 (без ввода пароля).
Все попытки элементарно произвести рестарт nginx заканчиваются провалом:
1)ansible -a "systemctl restart nginx" -K 10.8.227.22
SUDO password:
10.8.227.22 | FAILED | rc=1 >>
Failed to restart nginx.service: Interactive authentication required.
2)ansible -a "systemctl restart nginx" -b -K 10.8.227.22
SUDO password:
10.8.227.22 | FAILED | rc=0 >>
MODULE FAILURE
3)ansible -m raw -a "systemctl restart nginx" -b -K 10.8.227.22
SUDO password:
10.8.227.22 | FAILED | rc=1 >>
Sorry, user user1 is not allowed to execute '/bin/sh -c echo BECOME-SUCCESS-jbjuxgbogegafznhqwfbjurlpjdvmngk; systemctl restart nginx' as root on vm2.company.net.
4)playbook тоже не работает
---
- hosts: 10.8.227.22
tasks:
- service: "name=nginx state=restarted"
name: "restart nginx"
become: yes
ansible-playbook restart-nginx.yaml -K
SUDO password:

PLAY [10.8.227.22] *************************************************************

TASK [setup] *******************************************************************
ok: [10.8.227.22]

TASK [restart nginx] ***********************************************************
fatal: [10.8.227.22]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", "module_stdout": "\r\nSorry, user user1 is not allowed to execute '/bin/sh -c echo BECOME-SUCCESS-thfyiybjootfvadrtoyhposukqltsmfd; LANG=ru_RU.UTF-8 LC_ALL=ru_RU.UTF-8 LC_MESSAGES=ru_RU.UTF-8 /usr/bin/python /home/user1/.ansible/tmp/ansible-tmp-1486317561.37-213426575430392/service; rm -rf \"/home/user1/.ansible/tmp/ansible-tmp-1486317561.37-213426575430392/\" > /dev/null 2>&1' as root on vm2.company.net.\r\n", "msg": "MODULE FAILURE"}

NO MORE HOSTS LEFT *************************************************************
to retry, use: --limit @/home/admin/ansible/restart-nginx.retry

PLAY RECAP *********************************************************************
10.8.227.22 : ok=1 changed=0 unreachable=0 failed=1
5)Пробовал даже так:
ansible -m raw -a "sudo systemctl restart nginx" -K 10.8.227.22
SUDO password:
соответственно на таргет-хосте висит процесс root 32541 32498 0 21:03 pts/0 00:00:00 sudo systemctl restart nginx и ничего не происходит (видимо, ожидается ввод пароля)
Мучаюсь с этим 2 дня уже, никак не могу найти workaround. Может у кого-то есть мысли?
  • Вопрос задан
  • 4322 просмотра
Решения вопроса 1
@Seboreia Автор вопроса
Итак, нашел на просторах интернета обходной путь: fibed.net/2016/10/29/ansible-i-restricted-sudo
Краткая суть: необходимо создать connection-модуль, положить его в директорию ansible/lib/ansible/plugins/connection/ и в playbook'е в секции connection выбрать тип транспорта transport = ssh_sudo (либо сразу в основном конфиге задать transport = ssh_sudo).
Сам модуль ssh_sudo.py:
import ansible.constants as C
import ansible.plugins.connection.ssh as SSH
import pipes

class Connection (SSH.Connection):

    def __init__(self, play_context, *args, **kwargs):

        super (Connection, self).__init__(play_context, *args, **kwargs)        
        
        self._make_become_cmd = self._play_context.make_become_cmd
        self._play_context.make_become_cmd = self.make_become_cmd
        

    def make_become_cmd (self, cmd, executable = None):
      
        becomecmd = self._make_become_cmd(cmd, executable=None)

        if cmd.split('=')[0] == 'sudo':
            
            command = cmd.split('=')[1]
            exe = self._play_context.become_method
            flags = getattr(C, 'DEFAULT_%s_FLAGS' % self._play_context.become_method.upper(), None)
            prompt = self._play_context.prompt
            user = self._play_context.become_user
            success_key = self._play_context.success_key         

            sudocmd = '%s -k && setsid %s %s-p "%s" -u %s %s;' 'rc=$?; echo %s; exit $rc' % \
                      (exe, exe, flags.replace('-n',''), prompt, user, command, success_key)
 
            becomecmd = '$SHELL -c ' + pipes.quote (sudocmd)
       
        return (becomecmd)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
opium
@opium
Просто люблю качественно работать
в ансибле есть опция спросить пароль, спросить пароль для судо, и даже насколько помню можно задать пароль на судо в файле сценария(не помню точно так как паролями нигде не пользуюсь)
https://groups.google.com/forum/#!topic/ansible-pr...
Ответ написан
@p1dl0
vars_prompt:
- name: ansible_user
prompt: "Product deploy user"
default: "ansible"
- name: ansible_ssh_pass
prompt: "Enter ssh password"
private: yes
- name: ansible_become_pass
prompt: "Enter root password"
private: yes
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы