I would like to use ansible in a full automated context, where I cannot manually type passwords. To deal with this, I connect the servers with SSH public key, and I whitelisted severals commands such as apt-get install * in my sudoers configuration so I do not need a password to run them. For instance sudo apt-get install git.
However if the setting become is True in a playbook, ansible asks me for a password it does not need.
How can I tell ansible to run a command as sudo, without asking me a password?
Do you know another way to install apt packages without password?
Should I use another become method?
sudoers conf
myuser ALL = NOPASSWD: /usr/bin/apt-get install *
ansible
- name: install the latest version of ntpdate
package:
name: ntpdate
state: latest
become: True
Produces this output:
failed: [x.x.x.x] (item=ntpdate) => {"failed": true, "item": "python3-dev", "module_stderr": "", "module_stdout": "sudo: a password is required\r\n", "msg": "MODULE FAILURE", "rc": 1}
The simple answer is that you cannot do it without enabling all commands (or at least python).
Ansible does not run the commands as you expect it to run. It runs Python scripts. You can see the exact command when you execute ansible-playbook with -vvv. They are much more complex and to enable them you would have to add them to sudoers, for example:
sudo -H -S -n -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-xxxxxx;
/usr/bin/python /var/www/.ansible/tmp/ansible-tmp-xxxxxxxx/apt.py;
rm -rf "/var/www/.ansible/tmp/ansible-tmp-xxxxxxxx/" > /dev/null 2>&1'"'"'
&& sleep 0
The tricky part is that all spaces, quotes, and other special characters are relevant and until you get the correct command pattern by trial and error, replacing characters with wildcards, the system will not allow the command to run with elevated privileges. Effectively you won't be able to whitelist all the commands Ansible runs.
The only exception is raw module which runs the given command intact.
In all the Ansible playbooks I have worked on, I had to do only 2 things so that tasks run with become:True
Create file /etc/sudoers.d/demo on the target hosts with below content:
demo ALL=(ALL) NOPASSWD:ALL
Copy ssh id from Ansible host to target host using ssh-copy-id
template/without_sudo
%sudo ALL=(ALL) NOPASSWD: ALL
%sudo ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot, /sbin/shutdown
tasks/main.yml
- name: Sudoers no password
raw: echo '{{ user_password }}' | sudo -S sh -c 'echo "{{ lookup('file', 'templates/without_sudo') }}" > /etc/sudoers.d/without_sudo'
no sudo for the rest of the ansible command
You can use the ansible 'command' module with sudo as part of the command, instead of 'become: yes'
- name: install the latest version of ntpdate
command: 'sudo apt-get update ntpdate'
The downside is that this is much less portable. The upside is, it works... and you only need to whitelist the specific command.
in my opinion, if you set your node with =(ALL) NOPASSWD:ALL. then anybody: including the hackers can access your nodes.
so what I can suggest ,
ansible-playbook <name>.yml --ask-sudo-pass
this will ask your node sudo password. and u can execute ur operation, as I guess you know ur node's credential.
Related
- name: "read env"
shell: "sudo env"
become: true
I have above snippet in Ansible, I want to know the behaviour of using become and sudo together. I am aware become's default action is to turn the action as sudo. In that case will my sudo in the beginning of shell command get nullified ?
I am getting a different results with shell: "sudo env" and shell: "env" when become is set to true/yes
You do not need to add sudo to your commands when you are using become: true. You can checkout become_method from documentation. It will append sudo for you when you use become: true.
I highly recommend to read documentation for privilege escalation: https://docs.ansible.com/ansible/latest/user_guide/become.html
UPDATE
I did misunderstood your question sorry. The default become_method is sudo in ansible.cfg. When you set become: true without specifying become_method it will basically add a sudo prefix to your cmd. Here i created a example:
# privilege_escalation.yaml
---
- name: privilege escalation
hosts: localhost
tasks:
- name: command without any escalation
shell: env
- name: command with sudo
shell: sudo env
- name: command with become and sudo
shell: sudo env
become: yes
You can run example with this command:
ansible-playbook -vvv --ask-become-pass privilege_escalation.yaml
The first task will run env. In the results you can see USER=your_user line that represents current user.
When you use sudo in command, second task will run sudo env. In the results you can see USER=root and
SUDO_USER=your_user. This means you escalated your privileges to become root when running env command. SUDO_USER environment variable represents the user who invoked sudo.
The last task will run sudo sudo env. In the results you can see USER=root and
SUDO_USER=root. This means the first you become root user, after that root user executed sudo env command.
I hope this helps.
I want to make ssh connection automatically and install a packet to the connected machine. I'm able to process the SSH connection automatically. I can even run commands that do not require sudo authorization. But I didn't find a way to automatically enter the password in the commands that require sudo authorization. How do you think I can automatically enter the sudo password?
asd.sh
/usr/bin/expect -c 'spawn ssh -t usr#ip bash "pwd; sudo apt-get update"; expect "password:"; send "12345\r"; interact;'
asd.sh output
spawn ssh -t usr#ip bash pwd; sudo apt-get update
usr#ip's password:
/bin/pwd: /bin/pwd: cannot execute binary file
[sudo] password for usr:
You need the -c argument to pass a command string to Bash. Also, try to have the pattern match the full line. Try with:
/usr/bin/expect -c 'spawn ssh -t usr#ip bash -c "pwd; sudo apt-get update"; expect "*password:"; send "12345\r"; interact;'
^^ ^
Note that for this kind of task, Ansible can be very helpful as it will take care of all the boilerplate related to SSH and SUDO, and offers high-level modules to carry on any task easily.
The Ansible script ('playbook') would look like this (untested):
- hosts: ip
tasks:
- name: Update and upgrade apt packages
become: true
apt:
upgrade: yes
You can store the SUDO password in a file, and that file can be encrypted.
I am trying to run a "folder creation" command with my ansible playbook. (Code is below)
The creation requires sudo login to execute.
I run the playbook as follows:
ansible-playbook myfile.yml --ask-pass
This prompts for user account password of remote machine.
The ssh connection gets established, but commands fail with permission denied since its not taking super user password.
How can I fix my issue?
hosts: GSP
tasks:
- name: "make build directory"
command: mkdir -p /home/build/
become: true
become_user: root
- name: "change permissions on the directory"
command: chmod 777 -R /home/
become: true
become_user: root
There's also --ask-become-pass switch for ansible-playbook cli to query user for sudo password.
You can add the ansible_become_pass variable to specify the become password in your playbook.
More details can be found here:
http://docs.ansible.com/ansible/latest/become.html
I am writing an Ansible playbook to automate a series of sudo commands on various hosts. When I execute these commands individually in puTTY, I have no permission problems, as I have been granted proper access. However, when I attempt to create a playbook to do the same thing, I am told
user is not allowed to execute ... on host_name
For example, if I do $ sudo ls /root/, I have no problem, and, once I enter my password, can see the contents of /root/
In the case of my Ansible playbook ...
---
- host: servers
tasks:
- name: ls /root/
shell: ls /root/
become: true
become_method: sudo
...I then get the error mentioned above.
Any ideas why this would be the case? It seems to be telling me I don't have permission to run a command that I otherwise could run in an individual puTTY terminal.
[ ] automate a series of sudo commands on various hosts. When I execute these commands individually [ ]
Any ideas why this would be the case?
Sounds like you configured specific commands in the sudoers file (unfortunately you did not provide enough details, fortunately you asked for "ideas" not the real cause).
Ansible shell module does not run the command you specify prepended with sudo - it runs the whole shell session with sudo, so the command doesn't match what you configured in sudoers.
Either allow all commands to be run with elevated privileges for the Ansible user, or use raw module instead of shell.
I have an ssh access to the box but to run certain commands I need to do sudo su - and enter the password. Then I can run all the commands under that user.
How can i achieve this ansible. I tried become and sudo nothing worked for me.
Can someone provide me a working example?
this is what working for me ...
become: yes
become_method: sudo
become_user: myuser
become_flags: 'su -c'
Ansible uses the become directive to control privilege escalation.
If you're using sudo su -, you're using sudo to raise your privileges (and su - merely launches an interactive shell). become_method should be set to "sudo".
Since you aren't using password-less sudo, you need to tell Ansible that you will be supplying a password. You can do this in a config file with ansible_become_pass, but a much more secure method is to invoke ansible with --ask-become-pass.