Ansible with "sudo su - " - ansible

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

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 privilege escalation become without -u flag

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.

starting jboss server using ansible and returning back control [duplicate]

This question already has answers here:
Ansible Command module says that '|' is illegal character
(2 answers)
Closed 5 years ago.
Below yaml playbook restarts the jboss server but doesnt get back control to execute next ansible command. I have also used wait for module to stop waiting for current command result and go for next command. But still ansbile hangs on current command indefinitely . Please let me know when I went wrong?
---
- hosts: test1
tasks:
- name: simple command
become: true
command: whoami
register: output
- debug:
msg: "I gave the command whoami and the out is '{{output.stdout}}'"
- name: change to jboss user
become: true
become_user: jboss
command: whoami
register: output
- debug:
msg: "I gave the command whoami and the out is '{{output.stdout}}'"
- name: start jboss server as jboss user
become: true
become_user: jboss
command: sh /usr/jboss/bin/run.sh -c XXXXXXXX -b x.x.x.x &
when: inventory_hostname in groups['test1']
register: restartscript
- debug:
msg: "output of server restart command is '{{restartscript.stdout}}'"
- name: waiting for server to come back
local_action:
module: wait_for
timeout=20
host=x.x.x.x
port=8080
delay=6
state=started
terminal output message
ESTABLISH SSH CONNECTION FOR USER: XXXXXXXXXXX
SSH: EXEC sshpass -d12 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=XXXXXXXXX -o ConnectTimeout=10 -o ControlPath=/home/tcprod/XXXXXXXXXX/.ansible/cp/ansible-ssh-%h-%p-%r -tt X.X.X.X '/bin/sh -c '"'"'sudo -H -S -p "[sudo via ansible, key=hvgwnsbxpkxvbcmtcfvvsplfphdrevxg] password: " -u jboss /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-hvgwnsbxpkxvbcmtcfvvsplfphdrevxg; /usr/bin/python /tmp/ansible-tmp-XXXXXXXXX.XX-XXXXXXXXXXXXXX/command.py'"'"'"'"'"'"'"'"' && sleep 0'"'"''
The & is not allowed in Ansible "command".
command: sh /usr/jboss/bin/run.sh -c XXXXXXXX -b x.x.x.x &
Try removing it or use shell instead of command.
From Ansible documentation about command:
The given command [...] will not
be processed through the shell, so variables like $HOME and operations
like "<", ">", "|", ";" and "&" will not work (use the shell module if
you need these features).

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

Ansible lineinfile give an error with /etc/hosts

I have this simple task in my role:
- name: Updating the /etc/hosts
lineinfile: dest=/etc/hosts line="192.168.99.100 {{ item }}"
with_items:
- domain1.com
- domain2.com
tags: etc
When I run my Ansible playbook:
robe:ansible-develop robe$ ansible-playbook -i inventory develop-env.yml -vvvv --extra-vars "user=`whoami`" --tags etc --become-user=robe --ask-become-pass
SUDO password:
PLAY [127.0.0.1] **************************************************************
GATHERING FACTS ***************************************************************
<127.0.0.1> REMOTE_MODULE setup
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p /tmp/ansible-tmp-1446050161.27-256837595805154 && chmod a+rx /tmp/ansible-tmp-1446050161.27-256837595805154 && echo /tmp/ansible-tmp-1446050161.27-256837595805154']
<127.0.0.1> PUT /var/folders/x1/dyrdksh50tj0z2szv3zx_9rc0000gq/T/tmpMYjnXz TO /tmp/ansible-tmp-1446050161.27-256837595805154/setup
<127.0.0.1> EXEC ['/bin/sh', '-c', 'chmod a+r /tmp/ansible-tmp-1446050161.27-256837595805154/setup']
<127.0.0.1> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=rqphpqfpcbsifqtnwflmmlmpwrcnkpqe] password: " -u robe /bin/sh -c '"'"'echo BECOME-SUCCESS-rqphpqfpcbsifqtnwflmmlmpwrcnkpqe; LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /tmp/ansible-tmp-1446050161.27-256837595805154/setup'"'"''
<127.0.0.1> EXEC ['/bin/sh', '-c', 'rm -rf /tmp/ansible-tmp-1446050161.27-256837595805154/ >/dev/null 2>&1']
ok: [127.0.0.1]
TASK: [docker-tool-box | Updating the /etc/hosts] *****************************
<127.0.0.1> REMOTE_MODULE lineinfile dest=/etc/hosts line="192.168.99.100 ptxrt.com"
<127.0.0.1> EXEC ['/bin/sh', '-c', 'mkdir -p /tmp/ansible-tmp-1446050161.49-9492873099893 && chmod a+rx /tmp/ansible-tmp-1446050161.49-9492873099893 && echo /tmp/ansible-tmp-1446050161.49-9492873099893']
<127.0.0.1> PUT /var/folders/x1/dyrdksh50tj0z2szv3zx_9rc0000gq/T/tmpyLOGd6 TO /tmp/ansible-tmp-1446050161.49-9492873099893/lineinfile
<127.0.0.1> EXEC ['/bin/sh', '-c', u'chmod a+r /tmp/ansible-tmp-1446050161.49-9492873099893/lineinfile']
<127.0.0.1> EXEC /bin/sh -c 'sudo -k && sudo -H -S -p "[sudo via ansible, key=nofwziqxytbhjwhluhtzdfcqclqjuypv] password: " -u robe /bin/sh -c '"'"'echo BECOME-SUCCESS-nofwziqxytbhjwhluhtzdfcqclqjuypv; LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /tmp/ansible-tmp-1446050161.49-9492873099893/lineinfile'"'"''
<127.0.0.1> EXEC ['/bin/sh', '-c', 'rm -rf /tmp/ansible-tmp-1446050161.49-9492873099893/ >/dev/null 2>&1']
failed: [127.0.0.1] => (item=ptxrt.com) => {"failed": true, "item": "ptxrt.com"}
msg: The destination directory (/private/etc) is not writable by the current user.
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit #/Users/robe/develop-env.retry
127.0.0.1 : ok=1 changed=0 unreachable=0 failed=1
I don't understand why the error msg said:
msg: The destination directory (/private/etc) is not writable by the current user.
The correct directory should be /etc/hosts.
Any clue?
I am working on MacOS.
My playbook is:
- hosts: 127.0.0.1
connection: local
become: yes
become_method: sudo
become_user: "{{user}}"
roles:
- role-1
- role-2
I put the become_user by command line. So all my roles are running with become. And it still doesn't work.
On OSX the /etc/ folder is actually a symlink to the /private/etc/ folder - hence the error. (Ansible is just transparently following the symlink).
As for the error you're going to need to run the task with become: yes (sudo permissions) to be able to write to /etc/hosts/
Edit based on update and commments
To get the correct privileges to edit the hosts file you need to be root. Setting become: yes on the task is good enough for this for OSX as Ansible will default to sudo as the become method and root as the user.
To specify the sudo password you can do one of two things.
Use --ask-become-pass on the command line and Ansible will prompt you when it needs it
Use the ansible_become_pass variable on the group or host in the inventory file. E.g. localhost ansible_become_pass=batman
Note that the Ansible docs recommend against 2 and using 1 so as not to store your password in plain text.

Resources