Ansible privilege escalation become without -u flag - ansible

How is it possible to become a certain user without the -u flag (sudo su test_user instead of sudo su -u test_user)
Inventory (hosts)
[example]
test0001.example.org ansible_become_user=test_user ansible_become=true
ansible.cfg:
[defaults]
timeout=30
[privilege_escalation]
become_method="sudo"
become_flags="su"
And on the target machine:
$ sudo -l
User foo may run the following commands on test0001:
(root) NOPASSWD: /bin/su test_user
Running the playbook now fails with:
<test0001> (0, b'', b'')
<test0001> ESTABLISH SSH CONNECTION FOR USER: None
<test0001> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=30 -o ControlPath=/home/foo/.ansible/cp/c7eeb339b6 -tt test0001 '/bin/sh -c '"'"'sudo su -u test_user /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-geolooxawvydfclkjnetjajadmffqjvz ; /usr/bin/python /var/tmp/ansible-tmp-1578410709.7699296-180938533114945/AnsiballZ_setup.py'"'"'"'"'"'"'"'"' && sleep 0'"'"''
fatal: [test0001]: FAILED! => {
"msg": "Timeout (32s) waiting for privilege escalation prompt: \r\nWe trust you have received the usual lecture from the local System\r\nAdministrator. It usually boils down to these three things:\r\n\r\n #1) Respect the privacy of others.\r\n #2) Think before you type.\r\n #3) With great power comes great responsibility.\r\n\r\n"
}
And that is because it tries to become test_user with sudo su -u test_user. I actually want it to become test_user with sudo su test_user (so without the -u flag). How would it be possible to tell ansible not to include the -u flag?
Note that I am not able to change the sudoers files.

Related

Ansible: Timeout (12s) waiting for privilege escalation prompt

Ansible 2.9.27. Target is Linux CentOs7
'become sudo' always fails with the error Timeout (12s) waiting for privilege escalation prompt
When I try manually, sudo su takes about 60 seconds to return a prompt. I don't know why, but I'd like to know how to change the timeout so that Ansible waits more time for become.
I've tried different solutions I found in StackOverflow, such as running with -c paramiko, but they didn't work.
<myhostname.com> ESTABLISH SSH CONNECTION FOR USER: myuserid
<myhostname.com> SSH: EXEC sshpass -d8 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="myuserid"' -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o ControlPath=/home/myuserid/.ansible/xx/e123e1234e myhostname.com '/bin/sh -c '"'"'rm -f -r /tmp/myuserid/ansible/ansible-tmp-12334567890/ > /dev/null 2>&1 && sleep 0'"'"''
<myhostname.com> (0, '', '')
fatal: [myhostname.com]: FAILED! => {"msg": "Timeout (12s) waiting for privilege escalation prompt: \r\n"
There are multiple ways, one way is to set environment variable as below
export ANSIBLE_TIMEOUT=120;
Run the playbook on same terminal where environment variable is set.

Ansible with "sudo su - "

(There are already a few questions about this, but no solution worked for me)
On the servers I work on, we have to "sudo su - webapps" and then run our commands as webapps.
Ansible does not provide a native way to do this I believe (sudo only is available but the sysadmins restricted the list of commands I can run it with, su is available with Ansible but does not work on its own on the servers).
I've tried
https://www.coveros.com/ansible-privledge-escalation-using-sudo-su/
[privilege_escalation]
become_exe=sudo su -
With playbook :
---
- hosts:
- test
become: yes
become_user: webapps
become_method: su
tasks:
- name: Updates file
copy:
src: a.txt
dest: dest/a.txt
Running it gives :
SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o
ControlPersist=60s -o KbdInteractiveAuthentication=no -o
PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey
-o PasswordAuthentication=no -o 'User="myUser"' -o ConnectTimeout=10 -o ControlPath=/Users/lmoreau/.ansible/cp/d895b40f7e -tt myServer '/bin/sh -c '"'"'sudo su - webapps -c '"'"'"'"'"'"'"'"'/bin/sh -c
'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'echo
BECOME-SUCCESS-nxilvumwmfikgyuisutwiwobidrgqpao ; /usr/bin/python
/var/tmp/ansible-tmp-1583355901.6967812-200466745901442/AnsiballZ_setup.py'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"'
&& sleep 0'"'"''
...
"msg": "Timeout (12s) waiting for privilege escalation prompt: \r\nWe
trust you have received the usual lecture from the local
System\r\nAdministrator. It usually boils down to these three
things:\r\n\r\n #1) Respect the privacy of others.\r\n #2) Think
before you type.\r\n #3) With great power comes great
responsibility.\r\n\r\n"
Alternative attempt with :
[privilege_escalation]
become_exe=’sudo su - ‘
"module_stdout": "/bin/sh: ’sudo: command not found\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
Without overriding the become_exe:
"su" method gives "Timeout (12s) waiting for privilege escalation
prompt: "
"sudo" method gives "msg": "Missing sudo password"
Note : I do not have the password of the account I want to become, and am not supposed to have any.
How can I do the same as what I do by hand with Ansible ?
Use this:
- hosts: application
become: yes
become_exe: "sudo su - webapps"
become_method: su
tasks:

Installing package via Ansible using a user with limited sudo rights [duplicate]

I have a playbook that performs some prechecks on the database as the Oracle user. The remote node is an AIX server and so I created a shell script that is ran via the playbook.
---
- hosts: db
var_files:
- ansible_var.yml
tasks:
- name: "DB Checks"
become: True
become_user: oracle
script: "{ db_prechk }"
On the AIX server, I added the below entry to the sudoers file
ansible ALL=(oracle) NOPASSWD: /tmp/ansible-tmp-*/db_prechecks.sh
But the playbook fails with the error that it's waiting for the privilege escalation prompt.
This runs fine if it is ran as root. However we do not want passwordless root between the Ansible controller and the remote nodes. So we created ansible user on the controller and remote nodes and exchanged the SSH keys.
This also runs if the sudoers entry is just
ansible ALL=(oracle) NOPASSWD: ALL
We do not want to provide full access to the oracle userid via the ansible user id too.
I ran the playbook in the verbose mode and can see that Ansible is copying the script to the remote_tmp dir and is executing it as the oracle userid. In that case the sudoers line should've allowed it to run?
If you look at the verbose mode output, you will see that the actual command differs from the one you specified in the sudoers file:
<127.0.0.1> SSH: EXEC ssh -o ForwardAgent=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=2202 -o 'IdentityFile="/Users/techraf/devops/testground/debian/.vagrant/machines/debian/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ansible -o ConnectTimeout=120 -o ControlPath=/Users/techraf/.ansible/cp/ansible-ssh-%h-%p-%r -tt 127.0.0.1 '/bin/sh -c '"'"'sudo -H -S -n -u oracle /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-xoamupogqwtteubvedoscaghzmfascsr; /tmp/ansible-tmp-1488508771.72-271591203197790/db_prechecks.sh '"'"'"'"'"'"'"'"' && sleep 0'"'"''
So what is executed after sudo -u oracle starts actually with /bin/sh -c.
I managed to filter a working string to:
ansible ALL=(oracle) NOPASSWD: /bin/sh -c echo BECOME-SUCCESS*; * /tmp/ansible-tmp-*/db_prechecks.sh*
But it is based on trial-and-error. I'm not sure yet why * is required between ; and /tmp/... and at the end, but otherwise it does not work.
In both places Ansible added superfluous space characters and it seems to be the reason, as adding a space to a shell command (specified in the sudoers file) does affect the ability to sudo.
You might try with ? instead of *, I will test later
Q: "This also runs if the sudoers entry is just ansible ALL=(oracle) NOPASSWD: ALL"
A: Quoting from Privilege escalation must be general:
"You cannot limit privilege escalation permissions to certain commands..."
Replying to #techraf's answer: sudo seems to truncate the extra space and you can see it with sudo -l. I was able to get around this by escaping the spaces with \ as instructed in sudo's man page:
\x For any character ‘x’, evaluates to ‘x’.

Restrict Ansible script module using sudoers on the remote node

I have a playbook that performs some prechecks on the database as the Oracle user. The remote node is an AIX server and so I created a shell script that is ran via the playbook.
---
- hosts: db
var_files:
- ansible_var.yml
tasks:
- name: "DB Checks"
become: True
become_user: oracle
script: "{ db_prechk }"
On the AIX server, I added the below entry to the sudoers file
ansible ALL=(oracle) NOPASSWD: /tmp/ansible-tmp-*/db_prechecks.sh
But the playbook fails with the error that it's waiting for the privilege escalation prompt.
This runs fine if it is ran as root. However we do not want passwordless root between the Ansible controller and the remote nodes. So we created ansible user on the controller and remote nodes and exchanged the SSH keys.
This also runs if the sudoers entry is just
ansible ALL=(oracle) NOPASSWD: ALL
We do not want to provide full access to the oracle userid via the ansible user id too.
I ran the playbook in the verbose mode and can see that Ansible is copying the script to the remote_tmp dir and is executing it as the oracle userid. In that case the sudoers line should've allowed it to run?
If you look at the verbose mode output, you will see that the actual command differs from the one you specified in the sudoers file:
<127.0.0.1> SSH: EXEC ssh -o ForwardAgent=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=2202 -o 'IdentityFile="/Users/techraf/devops/testground/debian/.vagrant/machines/debian/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ansible -o ConnectTimeout=120 -o ControlPath=/Users/techraf/.ansible/cp/ansible-ssh-%h-%p-%r -tt 127.0.0.1 '/bin/sh -c '"'"'sudo -H -S -n -u oracle /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-xoamupogqwtteubvedoscaghzmfascsr; /tmp/ansible-tmp-1488508771.72-271591203197790/db_prechecks.sh '"'"'"'"'"'"'"'"' && sleep 0'"'"''
So what is executed after sudo -u oracle starts actually with /bin/sh -c.
I managed to filter a working string to:
ansible ALL=(oracle) NOPASSWD: /bin/sh -c echo BECOME-SUCCESS*; * /tmp/ansible-tmp-*/db_prechecks.sh*
But it is based on trial-and-error. I'm not sure yet why * is required between ; and /tmp/... and at the end, but otherwise it does not work.
In both places Ansible added superfluous space characters and it seems to be the reason, as adding a space to a shell command (specified in the sudoers file) does affect the ability to sudo.
You might try with ? instead of *, I will test later
Q: "This also runs if the sudoers entry is just ansible ALL=(oracle) NOPASSWD: ALL"
A: Quoting from Privilege escalation must be general:
"You cannot limit privilege escalation permissions to certain commands..."
Replying to #techraf's answer: sudo seems to truncate the extra space and you can see it with sudo -l. I was able to get around this by escaping the spaces with \ as instructed in sudo's man page:
\x For any character ‘x’, evaluates to ‘x’.

Remote Machine unreachable while trying to ping through ansible

This is my hosts file :
[openstack]
ec2-54-152-162-0.compute-1.amazonaws.com
I am trying to ping it using the following command :
ansible openstack -u redhat -m ping -vvvv
I got the following response :
Loaded callback minimal of type stdout, v2.0
Using module file /usr/lib/python2.7/site-packages/ansible-2.2.0-py2.7.egg/ansible/modules/core/system/ping.py
<ec2-54-152-162-0.compute-1.amazonaws.com> ESTABLISH SSH CONNECTION FOR USER: redhat
<ec2-54-152-162-0.compute-1.amazonaws.com> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o Port=22 -o 'IdentityFile="/home/centos/AnsibleKeyPair.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=redhat -o ConnectTimeout=10 -o ControlPath=/home/centos/.ansible/cp/ansible-ssh-%h-%p-%r ec2-54-152-162-0.compute-1.amazonaws.com '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1480529571.83-128837972481874 `" && echo ansible-tmp-1480529571.83-128837972481874="` echo $HOME/.ansible/tmp/ansible-tmp-1480529571.83-128837972481874 `" ) && sleep 0'"'"''
ec2-54-152-162-0.compute-1.amazonaws.com | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh.",
"unreachable": true
}
NOTE : I am able to connect to centos machines properly. But, I can't ping Ubuntu and Redhat machines. My controller machine is Centos. What might the problem be?
I solved it finally by using the following command :
ansible openstack -u ec2-user -m ping
I have been typing -u redhat but AWS has already given a name to it automatically ec2-user
"ESTABLISH SSH CONNECTION FOR USER: None" - this means that it is trying to ssh this host using a blank username which will not work.
Two solutions:
Edit the hosts file to include ansible_user=ubuntu (or whatever user your flavor uses, i.e. ec2-user for amazon linux)
[openstack]
ec2-54-204-230-203.compute-1.amazonaws.com ansibler_user=ubuntu
Just call it with the -u ubuntu when calling the playbook (or again whatever your flavor uses).
ansible openstack -u ubuntu -m ping -vvvv
Hope this helps!
--Edit--
(this is what helped me do it)
1.) Add your ssh key to the ~/.ssh directory
touch ~/.ssh/mykey.pem
2.) Enter ssh-agent bash mode
ssh-agent bash
3.) Ehange its permissionschmod
chmod 600 ~/.ssh/mykey.pem
4.) Make a path for ansible to use the permission
ssh-add ~/.ssh/mykey.pem
In your command line, use argument -k to ask ssh passwork:
ansible openstack -u redhat -m ping -k

Resources