I'm trying to achieve the following with ansible
create a user without a password
adduser test <-- ok and works on linux machine and works with ansible
change to user test
su test <-- works on linux machine, but fails with ansible. I get
incorrect password message
copy a file from location1 to location2 as a test user and change a file content.
cp loc1/testfile.txt loc2/testfile.txt && echo "hello" > testfile.txt
---
- name: This is a hello-world example
hosts: all
tasks:
- name: create a passwordless test user
action: user name=test state=present
become: yes
become_user: root
- name: Create a file called '/tmp/testfile.txt' with the content 'hello' using test user.
copy:
content: hello
dest: /tmp/testfile.txt
owner: test
group: test
become_user: test
primary conditions:
at a moment of execution the file testfile.txt is already created on linux machine and has a group root and user root. I want to override the file and assign different user and group.
I've tried various combination, including
copy:
content: hello
dest: /tmp/testfile.txt
owner: test
group: test
become: yes
become_user: test
copy:
content: hello
dest: /tmp/testfile.txt
owner: test
group: test
become: yes
become_user: test
become_method: su
copy:
content: hello
dest: /tmp/testfile.txt
owner: test
group: test
become: yes
copy:
content: hello
dest: /tmp/testfile.txt
owner: test
group: test
become_user: test
become_method: su
always getting a message about the password being incorrect. The awkward moment is that test user has no password
What am I doing wrong?
Updates:
Tried this
How to achieve sudo su - <user> and run all command in ansible <-- does not work
Found an answer - it is not possible
https://devops.stackexchange.com/questions/3588/how-do-you-simulate-sudo-su-user-in-ansible
What is the point?
to cite from Quora (source: https://www.quora.com/What-is-advantage-of-creating-passwordless-user-in-Linux)
I presume you mean processes such as a webserver, running as the
"apache" user with a locked password (shadow entry of '!!').
This is for security, in case a vulnerability is discovered in the
server code. Prior to the year 2000 or so, it was common for servers
to run as the root user, particularly as this privilege is required to
open network sockets on privileged ports (below 1024), such as 53
(DNS) or 80 (HTTP). As I recall, high-profile breaches of the bind and
sendmail servers caused developers to re-think this strategy. Since
then, services are started with root privilege, the socket opened, and
then privilege is dropped to a non-privileged user ID such as "apache"
or "named". This needs no password, since it is never intended that
anyone login. Rather, a process running as root executes a setuid()
system call to change effective user ID to this user. In the event of
a security breach, an attacker will be limited to the access lists of
this user; for instance, a vulnerable CGI script on a webserver would
be able to access the /tmp directory as the "apache" user, but be
unable to read /etc/shadow for instance, or to write an extra user
into /etc/passwd or modify system binaries in /sbin.
To avoid what is described in "password not being accepted for sudo user with ansible":
fatal: [testserver]: FAILED! => {"failed": true, "msg": "Incorrect su password"}
You might try using sudo, assuming you have given test user sudo rights:
# Debian systems (Ubuntu / Linux Mint / ElementryOS), add users to the sudo group
sudo usermod -aG sudo username
# On RHEL based systems (Fedora / CentOS), add users to the wheel group
sudo usermod -aG wheel username
Then:
become_user: test
become_method: sudo
Laucnhed with:
ansible-playbook -i inventory simple_playbook.yml --ask-become-pass
And enter the root password
Related
I want to use the ansible module synchronize with using a private_key.
When issuing the following command, everything works fine:
localuser$ rsync -rltDvzu --delete -e ssh . remoteuser#rsync.cloud.com:/users/remoteuser/
Here is my playbook the achieve the same, executing as root:
- name: Synchronization of src on the control machine to dest on the remote hosts
synchronize:
src: /raid5/Pictures/
dest: rsync://remoteuser#rsync.cloud.com:/users/remoteuser/
recursive: yes
private_key: /home/localuser/.ssh/id_rsa
set_remote_user: no
copy_links: no
times: yes
checksum: yes
rsync_opts: -e "ssh"
Doing this, the password prompt shows up.
I've tried the following:
toggling set_remote_user --> Password prompt shows up
set_fact, ansible_user to localuser or remoteuser --> Password prompt shows up
extending rsync_opts with -i and the path to my private key --> Error message: No such file or directory
UPDATE TO THE PLAYBOOK
become: yes
become_user: localuser
still the password prompt shows up.
It seems that in the first case, you are not root, and in the second, you are. So the ssh bi-key used is not the same in this 2 cases, is it ?
I am running below playbook. which will login to the server using ec2-user but mysql-java-connector will be installed, my test1 user.
---
- hosts: cluster
become: yes
remote_user: ec2-user
tasks:
- name: Create test1 User
user:
name: test1
password: '$6$jQX0JQzf8GB$NI/Pv1rMLyxWYaFCGNsbrun3sfn5bXSzg89Ip.ga2yf3n7hhrjiPsEo5IChIA7X8xVxnuZzm2sWA7IRM6qZOR0'
state: present
shell: /bin/bash # Defaults to /bin/bash
system: no # Defaults to no
createhome: yes # Defaults to yes
home: /home/test1
- name: Add users to sudoers
lineinfile:
dest : /etc/sudoers
state: present
line: 'test1 ALL=(ALL) NOPASSWD: ALL'
- name: Install mysql java connector
become_user: test1
become_method: sudo
yum: name=mysql-connector-java state=present
Gets below error:
fatal: [xxx.xxx.xxx.211]: FAILED! => {"changed": false, "msg": "You need to be root to perform this command.\n", "rc": 1, "results": [""]}
Same error, you should include become and become_user. In some cases add become method. More
- hosts: somehost
name: Install something
become: yes
remote_user: yourname
become
set to yes to activate privilege escalation.
become_user
set to user with desired privileges — the user you become, NOT the user you login as. Does NOT imply become: yes, to allow it to be set
at host level. Default value is root.
Add ansible_user=Your-User and ansible_become=true in /etc/ansible/hosts file to remove this error:
You need to be root to perform this command
Replace become_user: test1 to become_user: root (or delete this line, because become_user is root by default).
Please read Understanding privilege escalation for more information.
is there any mechanism that checks if the SSH/SUDO password is correct? When deploying a playbook across the whole environment, after putting in the wrong password, ansible runs on all hosts with the wrong password, it fails and my LDAP/AD account is locked out.
Since, as it turns out, Ansible does not seem to have this functionality, I decided to create a workaround myself:
in site.yml, I added a role that only runs on one server and has 1 or optionally 2 tasks in it. The first one checks if login itself works, the second one checks if sudo works.
- name: Check ssh password first
command: echo "ssh password correct"
changed_when: false
- name: Check sudo password first
command: echo "sudo password correct"
become: yes
changed_when: false
As a good workaround, I usually put this in site.yml:
- hosts: all
gather_facts: false
tasks:
- name: site.yml | Check if Password is correct
become: true
command: echo "PW is correct"
run_once: true
tags:
- always
That task will run always, no matter what tags you start the playbook with and will check if the ssh/sudo password works on one host before hammering all your servers with login requests.
ansible 192.168.1.115 -s -m shell -a "echo -e 'oldpassword\nnewpassword\nnewpassword' | passwd myuser" -u myuser --ask-sudo-pass
I would like to update existing user with new password, I had tried this command, but it doesn't work
appreciate any Tips !
You can leverage the user module to quickly change the password for desired account. Ansible doesn’t allow you to pass a cleartext password to user module so you have to install a password hashing library to be leveraged by Python.
To install the library:
sudo -H pip install passlib
Then simply exexute your command:
ansible 192.168.1.115 -s -m user -a "name=root update_password=always password={{ yourpassword | password_hash('sha512') }}" -u myuser --ask-sudo-pass
Hope that help you
Create your shadow password (linux) with
python -c 'import crypt; print crypt.crypt("YourPassword", "$6$random_salt")'
create
update_pass.yml
execute your ansible-playbook with sudoer (bash)
ansible-playbook update_pass.yml --become --become-method='sudo' --ask-become-pass
Update password for a list of hosts using dynamic variables:
In your inventory file set a variable (pass) as the following:
ip_1# ansible_user=xxxxxx ansible_ssh_pass=xxxx ansible_sudo_pass=xxx pass='aaaa'
ip_2# ansible_user=xxxxxx ansible_ssh_pass=xxxx ansible_sudo_pass=xxx pass='bbbb'
Now in the playbook we make a backup of the shadow file and set cron task to restore the shadow file in case something went wrong than we update the password:
- hosts: your_hosts
gather_facts: no
tasks:
- name: backup shadow file
copy:
src: /etc/shadow
dest: /etc/shadaw.org
become: yes
- name: set cron for backup
cron:
name: restore shadow
hour: 'AT LEAST GIVE YOURSELF ONE HOUR TO BE ABLE TO CALL THIS OFF'
minute: *
job: "yes | cp /tmp/shadow /etc/"
become: yes
- name: generate hash pass
delegate_to: localhost
command: python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt('{{pass}}')"
register: hash
- debug:
var: hash.stdout
- name: update password
user:
name: xxxxxx
password: '{{hash.stdout}}'
become: yes
Now we create a new playbook to call off cron task we use the new password for authentication and if authentication failed cron will remain active and restore the old password.
hosts file:
ip_1# ansible_user=xxxxxx ansible_ssh_pass=aaaa ansible_sudo_pass=aaaa
ip_2# ansible_user=xxxxxx ansible_ssh_pass=bbbb ansible_sudo_pass=bbbb
the playbook:
- hosts: your_hosts
gather_facts: no
tasks:
- name: cancel cron task
cron:
name: restore shadow
state: absent
!!Remember:
pass variable contain your password so you may consider using vault.
Give yourself time when setting cron for backup to be able to call it of (second playbook).
In worst case cron will restore the original password.
You need to have passlib installed in your ansible server.
I am trying to copy a file in to /etc. But I am getting "msg: Destination /etc not writable" when i run the playbook. Here is my Playbook task part. Really Appreciate your help.
tasks:
- name: copy rsyslog
sudo: yes
copy:
src: /home/nandakumar.nachimuth/playbooks/rhn_check/rtest.conf
dest: /etc/rtest.conf
owner: root
group: root
mode: 0755
ignore_errors: yes
Error
msg: Destination /etc not writable
Note:I have provided the ssh and sudo pass while running the Playbook.
Instead of using sudo with your tasks, try adding become: yes with your playbook
example
- hosts: all
become: yes
Also, make sure that you are really entering the sudo password instead of the user password.
You need to reconfigure sshd to allow your user to switch to use sudo without password. To do that you will have to fire up sudo visudo and then change the line with your user to look like this:
your_username ALL=(ALL) NOPASSWD: ALL
And that will do the trick.
The user should have root permissions.
I think this should help. My issue was though user1 has root permissions i was getting unable to write error, Just by placing "become: yes", I get rid of this error.
- hosts: analytics
user: user1
become: yes
become_user: root
gather_facts: yes
roles:
- name: xxxxx
You need to specify sudo after user with hosts
example:
-hosts: abc
user: xyz
sudo: yes
This will work for you.