Ansible unable to run command by becoming other user and using sudo

Hi all,

I have a target server where I have a user, user1, who can become another privileged user, admin1, without password.and admin1 can run any command with sudo, like “sudo ls /root” → works.

So from remote server I can do this:
[user1@server1~]$ sudo su - admin1 → successful
[admin1@server1~]$ sudo ls -l /root/ → successful

Now, if I try this from ansible, it doesn’t work, note that I do not need password to become admin1 from user1 user.

Tried this, failed, while connecting to server1 as user1:
$ ansible -i hosts server1 -m shell -a “ls /root/” --become-user admin1 --become-method sudo -b

I receive error like:

<192.168.10.10> ssh_retry: attempt: 5, caught exception(Missing sudo password) from cmd ([‘ssh’, ‘-vvv’, ‘-C’, ‘-o’, ‘ControlMaster=auto’, ‘-o’, ‘ControlPersist=60s’, ‘-o’, ‘StrictHostKeyChecking=no’, ‘-o’, ‘Port=22’, ‘-o’, ‘IdentityFile=“/home/user1/ansible-env/user1”’, ‘-o’, ‘KbdInteractiveAuthentication=no’, ‘-o’, ‘PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey’, ‘-o’, ‘PasswordAuthentication=no’, ‘-o’, ‘User=“user1”’, ‘-o’, ‘ConnectTimeout=10’, ‘-o’, ‘ControlPath=/home/user1/.ansible/cp/e81f1307f9’, ‘-tt’, ‘192.168.10.10’, ‘/bin/sh -c 'sudo -H -S -n -u mygpadmin /bin/sh -c '“'”'echo BECOME-SUCCESS-prgmplogeczegkatiwtdoyhjtxaphgrv ; /usr/bin/python /var/tmp/ansible-tmp-1589381399.57-2262637800948/AnsiballZ_command.py'“'”' && sleep 0'’]…), pausing for 15 seconds
<192.168.10.10> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o ‘IdentityFile=“/home/user1/ansible-env/user1”’ -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ‘User=“user1”’ -o ConnectTimeout=10 -o ControlPath=/home/user1/.ansible/cp/e81f1307f9 -tt 192.168.10.10 ‘/bin/sh -c ‘"’“'sudo -H -S -n -u mygpadmin /bin/sh -c '”’“'”‘"’“'”‘"’“‘echo BECOME-SUCCESS-prgmplogeczegkatiwtdoyhjtxaphgrv ; /usr/bin/python /var/tmp/ansible-tmp-1589381399.57-2262637800948/AnsiballZ_command.py’”‘"’“'”‘"’“'”‘"’ && sleep 0’“'”‘’
Escalation requires password

How can I resolve this issue if I want to become another and run command with sudo using ansible/ansible-playbook but without using password. As user1, I can run all commands user1 is allowed to.

Thanks.

  • Zayed.

Hello,

can we have the output of:

sudo -l

for the user you're using for the connection? You need to be sure that
the given user is allowed to sudo with NOPASSWD

Luca

Hi Luca, thanks for replying. Here’s the data you requested:

Here’s the output of ‘sudo -l’ for user1:

[user1@server1 ~]$ sudo -l
Matching Defaults entries for user1 on server1:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep=“COLORS DISPLAY HOSTNAME
HISTSIZE 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 server1:
(ALL) NOPASSWD: /bin/su - admin1
[user1@server1 ~]$

And here’s it for admin1 user:

[admin1@server1 ~]$ sudo -l
Matching Defaults entries for admin1 on server1:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep=“COLORS DISPLAY HOSTNAME
HISTSIZE 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 admin1 may run the following commands on server1:
(ALL) NOPASSWD: ALL, !/bin/sh, !/bin/ksh, !/bin/bash, !/bin/zsh, !/bin/csh, !/bin/tcsh, !/usr/bin/login, !/usr/bin/su,
!/etc/sudoers, !/bin/su, !/usr/sbin/visudo, !/sbin/shutdown, !/sbin/reboot, !/sbin/init, !/usr/bin/shutdown -h now,
!/usr/bin/halt, !/usr/bin/poweroff, !/usr/bin/mount -o nosuid,nodev,noexec, !/usr/bin/umount, !/sbin/fdisk,
!/usr/sbin/format, !/usr/bin/dd, !/usr/bin/rlogin, !/etc/init.d/iptables, !/usr/bin/exportfs, !/sbin/pvs, !/sbin/lvs,
!/sbin/vgs, !/sbin/pvscan, !/sbin/pvscan, !/sbin/vgscan, !/sbin/lvscan, !/sbin/lvdisplay, !/sbin/vgdisplay,
!/sbin/pvdisplay, !/usr/bin/ifenslave, !/usr/bin/ethtool, !/usr/sbin/tcpd, !/usr/sbin/dump, !/usr/sbin/rdump,
!/usr/sbin/restore, !/usr/sbin/rrestore, !/usr/bin/mt, !/usr/bin/journalctl, !/usr/bin/netctl, !/usr/sbin/syslogd,
!/usr/bin/finger, !/usr/bin/tty
[admin1@server1 ~]$

The entry is saying that your user can run as any other user of the
system the command su - admin1. Looks to me as formally wrong.
Additionally is not the right command for a new interactive session,
you should use: sudo -u admin1 -i

You're are allowing only to do sudo su - admin1 without passowrd. As
far as i know is not what ansible does when you do become.

AFAIK ansible runs something similar to this:

echo BECOME-SUCCESS-sjsscfneygqfcntttkcomefpxnbkzumb; /bin/command --options

you can see with ansible -vvvv

It's difficult to create a single entry for this, so try first with (not tested)

user1 ALL: (admin1) NOPASSWD: ALL

To allow user1 to run any command as admin1 with sudo (sudo -u admin1
somecommand) without password.

This should work.

Luca

Hey Luca,

Thanks for your great advice, but maybe there were some syntax error, hence I couldn’t update suoders file.but i figured it out the syntax error too.

here’s an update for my testing, and it seems to work as i wanted to…but i will test in my main prod hosts where i faced the problem. here’s what i did:

I have 2 vms: vm1 & vm2

  1. vm1 is my ansible control machine and vm2 is target node.

  2. vm1 has user harry

  3. vm2 has user tom (non-admin) and admin (admin user)

  4. in vm2, i added tom & admin to sudoers file as:
    # ansible testing
    admin ALL=(ALL) NOPASSWD:ALL
    tom ALL = (admin) NOPASSWD: ALL

so, in vm2, i can do this as tom:
[tom@centos7vm2 ~]$ sudo -u admin -i sudo touch /root/new_file → successful

[tom@centos7vm2 ~]$ sudo -u admin -i sudo ls -l /root/ → successful
total 4
-rw-------. 1 root root 1519 May 7 22:58 anaconda-ks.cfg
-rw-r–r–. 1 root root 0 May 14 20:31 new_file

[tom@centos7vm2 ~]$ sudo -u admin -i sudo whoami → successful
root

  1. in vm2, i can switch to admin user from tom user without password too:
    [tom@centos7vm2 ~]$ sudo -u admin -i → successful
    [admin@centos7vm2 ~]$ whoami
    admin → became admin user from tom
    [admin@centos7vm2 ~]$ exit
    logout
    [tom@centos7vm2 ~]$ → back to tom user

  2. but this fails in vm2 as tom, as expected:
    [tom@centos7vm2 ~]$ sudo ls -l /root
    [sudo] password for tom:
    Sorry, user tom is not allowed to execute ‘/bin/ls -l /root’ as root on centos7vm2. → failed, as expected
    [tom@centos7vm2 ~]$

  3. in vm1, i installed ansible (v2.9.9), and ensured connectivity from vm1 to vm2. in vm1, i connect to vm2 as tom for ansible. this works fine:

→ my host file
[harry@centos7vm1 ansible]$ cat hosts
vm2 ansible_ssh_host=192.168.10.2 ansible_ssh_user=tom

→ run ping to vm2 from vm1 using ansible
[harry@centos7vm1 ansible]$ ansible -i hosts all -m ping → successful, connectivity check
vm2 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}

[harry@centos7vm1 ansible]$ ansible -i hosts all -m shell -a “whoami” → successful
vm2 | CHANGED | rc=0 >>
tom → at remote host, it’s tom user
[harry@centos7vm1 ansible]$

  1. Now, from vm1 i tried this, and it worked:
    → run command at vm2 as admin user while establishing ssh connection to vm2 as tom user from vm1
    [harry@centos7vm1 ansible]$ ansible -i hosts all -m shell -a “sudo ls -l /root” --become-method sudo --become-user admin -b -K
    BECOME password: (entered tom’s password)
    [WARNING]: Consider using ‘become’, ‘become_method’, and ‘become_user’ rather than running sudo
    vm2 | CHANGED | rc=0 >>
    total 4
    -rw-------. 1 root root 1519 May 7 22:58 anaconda-ks.cfg
    -rw-r–r–. 1 root root 0 May 14 20:31 new_file → successful, i can list root user’s file using sudo by becoming admin user

→ use ‘become’ but without ask password flag (-K)
[harry@centos7vm1 ansible]$ ansible -i hosts all -m shell -a “ls -l /home/admin” --become-method sudo --become-user admin -b
vm2 | CHANGED | rc=0 >>
total 0
-rw-rw-r–. 1 admin admin 0 May 14 20:40 admin-secret-file → i can list admin’s home folder file’s while connecting to vm2 as tom user

  1. So, i can connect to vm2 as tom (non-admin user) and run commands as admin (without sudo).

and for those commands that admin needs sudo, i can also run them as tom in vm2 using ansible from vm1, with sudo prefix, although ansible shows warning like below:
[WARNING]: Consider using ‘become’, ‘become_method’, and ‘become_user’ rather than running sudo

so in this test, as harry user i’m able to run commands as admin user without pass, and admin has full sudo access without pass (except few commands like shutdown) and ansible showing warning not to use sudo prefix in shell module.

example of running sudo command as admin while ssh-ing to vm2 as tom (non-admin) from vm1:
[harry@centos7vm1 ansible]$ ansible -i hosts all -m shell -a “sudo ls -l /root” --become-method sudo --become-user admin -b
[WARNING]: Consider using ‘become’, ‘become_method’, and ‘become_user’ rather than running sudo
vm2 | CHANGED | rc=0 >>
total 4
-rw-------. 1 root root 1519 May 7 22:58 anaconda-ks.cfg
-rw-r–r–. 1 root root 0 May 14 20:31 new_file
[harry@centos7vm1 ansible]$

Thank you very much for pointing in the right direction. i didn’t know about ansible’s mechanism of sudo-ing internally.