Privilege escalation in Ansible is expecting a password - linux

I am trying to create a file on a few remote nodes using Ansible.
I am connecting as 'xyz' user and after privilage escalation I want to become 'abc' user.
Problem here is Ansible is expecting a password to become 'abc' user, but i can directly use command : sudo su abc to switch as abc user on Putty.
My playbook runs fine if I pass the command like : ansible-playbook TestPlay.yml --ask-become-pass and then I enter the password.
But, we cannot share password for 'abc' user, so we need Ansible to directly become 'abc' user using sudo, which is not happening.
when I used : become_method: sudo in my playbook, it failed with {"msg": "Timeout (12s) waiting for privilege escalation prompt: "}.
I tried adding ANSIBLE_BECOME_EXE=’sudo su -‘ in hosts file and still it did not work!!.
Please let me know if i am missing something in my configuration.
My TestPlay playbook :
- name: TestPlay sample
become: true
become_method: su
become_user: abc
hosts: group1
tasks:
- name : create a file after becoming abc user
file:
path: /var/tmp/temp.txt
state: touch
mode: '0665'
Hosts file entry :
[group1]
ip address1
ip address2
[group1:vars]
ansible_user=xyz
ansible_password=passxyz

Related

Ansible Run Command As Another User

I know my question is what become is designed to solve. And I do use it. However, my command seems to still be run as the ssh user. I'm trying to execute a which psql command to get the executable path. Running which psql as ssh user gives a different output than running the same command as my become user which is the output I want.
EDIT The problem is the $PATH variable ansible is using as suggested in comments. It is not using the correct $PATH variable. How can I direct ansible to use postgres users $PATH variable? Using environment module didn't work for me as suggested here https://serverfault.com/questions/734560/ansible-become-user-not-picking-up-path-correctly
EDIT2 So a solution is to use the environment module and set the path to the path I know has the psql executable but this seems hacky. Ideally, I'd like to just be able to use the become users path and not have to explicitly set it. Here's the hacky solution:
- name: Check if new or existing host
command: which psql
environment:
PATH: "/usr/pgsql-13/bin/:{{ansible_env.PATH}}"
become: yes
become_user: postgres
Playbook
---
- name: Playbook Control
hosts: all
become: yes
become_user: postgres
tasks:
- name: Check if new or existing host
shell: whoami && which psql
register: output
Relevant Output (the same as if I were to run the task command as my_user on myhost.net)
"stdout_lines": [
"postgres",
"/usr/bin/psql"
]
Expected Output (the output if I were to run the task command as postgres user on myhost.net)
"stdout_lines": [
"postgres",
"/usr/pgsql-13/bin/psql"
]
Inventory
myhost.net
[all:vars]
ansible_connection=ssh
ansible_user=my_user
Command
ansible-playbook --ask-vault-pass -vvv -i temp_hosts playbook.yml
In vault I only have the ssh pass of my_user.
Running the playbook with -vvv flag shows me that escalation was successful and that the output of this task is the output of running the command as ssh user, not become user. Any ideas?
Ansible by default uses sudo as the default become method.
Depending on how your linux system is configured (check /etc/sudoers), it could be that your $PATH variable is preserved for sudo commands.
You can either change this, or force ansible to use a different become method such as su:
https://docs.ansible.com/ansible/latest/user_guide/become.html#become-directives

Error: sudo: a password is required\r\n - although user have permissions on sudoers

I am trying to run a simple Ansible playbook that shows a content of 'home' directory.
It runs successfully, but when I use:
become_user: "{{ TARGET_USER }}"
I get error:
"sudo: a password is required\r\n"
The 'Ansible user' is "blnapp1" and the 'Target user' is "couchbase"
I added permissions for "blnapp1" and "couchbase" users inside sudoers file as follows:
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
blnapp1 ALL=(ALL) NOPASSWD: ALL
blnapp1 ALL=(ALL) ALL
ansible ALL= NOPASSWD: /home/blnapp1/playbook #path to playbook
couchbase ALL=(ALL) NOPASSWD: ALL
couchbase ALL=(ALL) ALL
I also added to all of the users ssh public key of each other into /.ssh/authorized_keys
Here is my inventory file:
web1 ansible_host=**** ansible_connection=local
[couchbase-install:children]
couchbase_cluster_nodes
couchbase_server_nodes
[couchbase_cluster_nodes]
primary1 ansible_host=**** ansible_user=blnapp1 TARGET_USER=couchbase couchbase_primary_cluster_node=**** couchbase_cluster_admin_port=*** couchbase_bucket_name=exampleBucket group_server=default
[couchbase_server_nodes]
[all:vars]
#configuration_mode can be vars or cc
configuration_mode=vars
couchbase_data_path="/userdata/data/CB/var/lib/couchbase/data"
couchbase_index_path= "/userdata/data/CB/var/lib/couchbase/data"
yum_path="sudo /bin/yum"
#couchbase_admin="Administrator"
#couchbase_password="Administrator"
And here is my playbook:
---
- name: I-test
hosts: primary1
become: true
become_user: "{{ TARGET_USER }}"
tasks:
- debug:
msg: 'TARGET_USER is: "{{ TARGET_USER }}"'
- name: show repo content
shell:
cmd: ls -la /home
The only way I found is to add "blnapp1" user to 'wheel' group. However, I really don't want "blnapp1" to have 'wheel' permissions..
Thanks in advance!
blnapp1 ALL=(ALL) NOPASSWD: ALL
blnapp1 ALL=(ALL) ALL
Those 2 lines basically tell the exact same thing: let blnapp1 launch any command as anyone. But the first one tells sudo not to ask for a password while the second one doesn't.
And after testing quickly against a debian:buster docker image, it appears only the last line encountered rules in this case, making sudo always ask for a password.
Simply remove the second line in your sudoers file. Note that you have the exact same problem for your couchbase user.

Ansible become_user useradd issue

When trying to add a user using Ansible, I set ansible_become_user in my inventory to an account on the server that is a sudoer, but adding a user still fails with this error:
usermod: cannot open /etc/passwd usermod: failed to unlock /etc/passwd
I tested on the server running the command like this from my normal ssh account:
sudo -u <sudo_user> useradd test
useradd: cannot open /etc/passwd
useradd: failed to unlock /etc/passwd
If I su to my sudo account and run sudo useradd test, it works just fine.
I can also get it to work from my base SSH account by running su <sudo_user> -c "sudo useradd test".
The variable to set on your playbook/task is become_user not ansible_become_user. ansible_become_user is used when you set the value for a specific host/group in your inventory. See the privilege escalation doc
Moreover, you also have to set become: true for the above option to have any effect.
A quick example (does not become anything with debug, just to put you on track)
---
- hosts: all
become: true
become_user: someone
tasks:
- name: dummy task with play's defaults
debug:
msg: I would run with play's become_user
- name: dummy task with overriden user
become_user: some_other
debug:
msg: I would run with the overriden become_user
You can try another option, that is execute it like other user, for example root, and try it again.
For do it, edit /etc/sysconfig/jenkins
Then search for:
JENKINS_USER="jenkins"
And change it for
JENKINS_USER="root"
This should resolve the issue.
Another way is to add jenkins to visudo

Unable to run Ansible with sudo user

We have a user userA on the server which has access to sudo. I can login into the server and run sudo su - userA to switch to new user. However if I use Ansible, it is throwing me below error:
fatal: [node1]: FAILED! => {"changed": false, "module_stderr": "Shared connection to node1 closed.\r\n", "module_stdout": "\r\nSorry, user abc is not allowed to execute '/bin/sh -c echo BECOME-SUCCESS-pzwmlpcvzvwafleunmvpwioi; /usr/bin/python /var/tmp/ansible-tmp-1533926060.36-184244176073120/setup.py' as userA on node1.\r\n", "msg": "MODULE FAILURE", "rc": 1}
Ansible file:
---
- hosts: all
become: yes
become_user: userA
become_method: sudo
tasks:
- name: Create file
command: touch /home/userA/testing
We don't have access to sudoers file. Is there a way to fix this without changing sudoers file?
I depends... If the sudoers configuration permits running /usr/bin/su - userA* (with a wildcard at the end allowing for the -c argument), then you can add become-configuration to your task in the following way:
- name: Create file
command: touch /home/userA/testing
vars:
ansible_become: true
ansible_become_method: su
ansible_become_user: userA
ansible_become_exe: 'sudo -p "Password: " su -'
If the password is required by sudoers, you must run ansible-playbook with --ask-become-pass (-K) option and connecting user's password (as for sudo).
First three parameters can be written directly as parameters to the task / play.
Otherwise you are probably destined for running expect module (likely on the controller machine) with all the drawbacks.
you can SetUID chmod u+s file on the files you want to run with UserA from userB. For Example, /usr/bin/passwd is a root file which has SetUID, so, any user can change its own passwd (using passwd command) while running the /usr/bin/passwd as root.
ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
passwd
Changing password for user user.
Changing password for user.
(current) UNIX password:

Edit current user's shell with ansible

I'm trying yo push my dot files and some personal configuration files to a server (I'm not root or sudoer). Ansible connects as my user in order to edit files in my home folder.
I'd like to set my default shell to usr/bin/fish.
I am not allowed to edit /etc/passwd so
user:
name: shaka
shell: /usr/bin/fish
won't run.
I also checked the chsh command but the executable prompt for my password.
How could I change my shell on such machines ? (Debian 8, Ubuntu 16, Opensuse)
I know this is old, but I wanted to post this in case anyone else comes back here looking for advise like I did:
If you're running local playbooks, you might not be specifying the user and expecting to change the shell of user you're running the playbook as.
The problem is that you can't change the shell without elevating the privileges (become: yes), but when you do - you're running things as root. Which just changes the shell of the root user. You can double check that this is the case by looking at /etc/passwd and seeing what the root shell is.
Here's my recipe for changing the shell of the user running the playbook:
- name: set up zsh for user
hosts: localhost
become: no
vars:
the_user: "{{ ansible_user_id }}"
tasks:
- name: change user shell to zsh
become: yes
user:
name: "{{ the_user }}"
shell: /bin/zsh
This will set the variable the_user to the current running user, but will change the shell of that user using root.
I ended up using two ansible modules :
ansible expect
ansible prompt
First I record my password with a prompt :
vars_prompt:
- name: "my_password"
prompt: "Enter password"
private: yes
And then I use the module expect to send the password to the chsh command :
tasks:
- name: Case insensitve password string match
expect:
command: "chsh -s /usr/bin/fish"
responses:
(?i)password: "{{ my_password }}"
creates: ".shell_is_fish"
The creates sets a lock file avoiding this task to be triggered again. This may be dangerous because the shell could be changed after and ansible will not update it (because of the lock still present). You may want to avoid this behaviour.
Here is how I do it:
- name: Set login shell of user {{ ansible_env.USER }} to `/bin/zsh` with `usermod`
ansible.builtin.command: usermod --shell /bin/zsh {{ ansible_env.USER }}
become: true
changed_when: false
Ubuntu 16
add first line in ~/.bashrc
/usr/bin/fish && exit

Resources