Ansible Ad-hoc commands requests vault passwords - ansible

This afternoon when running ansible ad-hoc commands I've started to be prompted for the vault passwords.
The process shouldn't need this and this was never required before.
I'm just running something like
ansible prod_servers -m shell -a "ls -al /var/logs/" --sudo
I can just provide the password and the command works, but it's driving me crazy.
We're using ansible 1.8.4 (don't ask) :(

Check for vaulted files under group_vars/host_vars in your inventory – this should be the only reason why password prompt may appear for ad-hoc commands.

Related

"sudo ansible-playbook" command fails even with --user option

I've a user foo which is able to do passwordless ssh to A(self) and B. The playbook requires sudo access inside which I'm escalating with become and the below command is working fine.
ansible-playbook -i ../inventory.ini --user=foo --become --become-user=root echo_playbook.yml
But the above command is part of a shell script which doesn't have permission for foo. So when I use sudo to trigger that shell script, ansible is saying host unreachable. So I tried the ansible command with sudo as shown below and same. It showed host is unreachable.
sudo ansible-playbook -i ../inventory.ini --user=foo --become --become-user=root echo_playbook.yml
I agree that sudo is escalating the ansible-playbook to root. But I'm also providing the --user to tell ansible that "foo" user needs to be used for ssh.
Basically to access the playbook I need sudo. To connect to other servers I need foo user. To execute the actions inside the playbook (commands in playbook) I need sudo again (which I am using become for).
Am I doing anything wrong? Can anybody tell me the exact command for the ansible-playbook for the above scenario where ansible-playbook needs to run as sudo ansible-playbook?
I'm not entirely clear on exactly where you're stuck. I don't think you're confused between the remote user and the local user. If the playbook works as foo, and from what you describe, I can only guess that ~foo/.ssh/id_rsa or another automatically provided key authenticates foo. But you can generate a key for any user and allow it access to the remote foo if you'd prefer. Or, you can run the playbook as another user. It's up to you. The only thing that won't work is relying on the environment or configuration of particular users and then not providing it.
the above command is part of a shell script which doesn't have permission for foo.
What I'm hearing is that:
a user foo can successfully run ansible job
a script runs (under root?) that cannot run the ansible job
If you're happy with how ansible works for the foo user, you can switch to the foo user to run the ansible:
sudo -u foo ansible-playbook ...
If the script runs as root, sudo will always succeed. Otherwise, you can configure sudo to allow one user to access another for one command or more.

Ansible root/password login

I'm trying to use Ansible to provision a server and the first thing I want to do is test the ssh access. If I use ssh directly I can log in fine...
ssh root#server
root#backups's password:
If I use Ansible I can't...
user#ansible:~$ ansible backups -m ping --user root --ask-pass
SSH password:
backups | UNREACHABLE! => {
"changed": false,
"msg": "Invalid/incorrect password: Permission denied, please try again.",
"unreachable": true
}
The password I'm using is correct - 100%.
Before anyone suggests using SSH keys - that's what part of what I'm looking to automate.
The issue was caused by the getting started documentation setting a trap.
It instructs you to create an inventory file with servers, use ansible all -m ping to ping those servers and to use the -u switch to change the remote user.
What it doesn't tell you is that if like me not all you servers have the same user, the advised way to specify a user per server is in the inventory file...
server1 ansible_connection=ssh ansible_user=user1
server2 ansible_connection=ssh ansible_user=user2
server3 ansible_connection=ssh ansible_user=user3
I was provisioning a server, and the only user I had available to me at the time was root. But trying to do ansible server3 -user root --ask-pass failed to authenticate. After a couple of wasted hours I discovered the -user switch is only effective if the inventory file doesn't have a user. This is intended precedence behaviour. There are a few gripes about this in GitHub issues but a firm 'intended behaviour' mantra is the response you get if you challenge it. It seems to go against the grain to me.
I subsequently discovered that you can specify -e 'ansible_ssh_user=root' to override the inventory user - I will see about creating a pull request to improve the docs.
While you're here, I might be able to save you some time with some further gotchas. This behaviour is the same if you use playbooks. In there you can specify a remote_user but this isn't honoured - presumably also because of precedence. Again you can override the inventory user with -e 'ansible_ssh_user=root'
Finally, until I realised Linode could provision a server with an SSH key deployed, I was trying to specify the root password to an ad-hoc command. You have to encrypt the password and this gives you a long string and this is almost certainly going to include $ in it which bash will treat as substitutions. Make sure you escape these.
The lineinfile module behaviour isn't intuitive either.
Write your hosts file like this. It will work.
192.168.2.4
192.168.1.4
[all:vars]
ansible_user=azureuser
Then execute the following command: ansible-playbook --ask-pass -i hosts main.yml --check to check before configuration.
Also create a ansible.cfg file. Then paste the following contents there:
[defaults]
inventory = hosts
host_key_checking = False
Note: All the 3 files namely, main.yml,ansible.cfg & hosts must be in the same folder.
Also, the code is tested for devices connected to a private network using Private IPs. I haven't checked using Public IPs. If using Azure/AWS, create a test VM and connect it to the VPN of the other devices.
Note: You need to install the SSHPass package to be able to authenticate with Password.
For Ubuntu: apt-get install sshpass

ssh login as user and change to root, without sudo

I have the following task for my golang code:
The command has to be run as root user on the server remotely in bash and the command output has to be fetched in a variable.
Logging over ssh as root is disabled.
sudo on the server is disabled, so I have to use 'su -' and type password
since I want to make it as automated as possible in bash, the password has to be stored inside the command
Here are the workflow actions:
Login via SSH (as unprivileged user) to remote host
Elevate to privileged 'root' user --> su -
Type the root password
run the command which root can execute
get to output to string on localhost and do some actions
I have Googled for days, but it seems that I cannot find a solution for this.
Does anyone have a solution to this?
The issue you are facing is concerning interacting with the command after it has been executing.
It is quite easy to use exec.Command for non-interactive commands.
I would recommend using Expect for interaction, or the Golang equivalent located here.

Ansible task command with credentials

I am wondering if during an Ansible task is it safe to send credentials (password, api key) in a command line task?
No one on the remote server should see the command line (and even less credentials).
Thank you.
If you are not trusting remote server - you should never expose sensitive credentials to it, since anyone having root access on that server can easily intercept traffic, files and memory allocated by you on that server. The easiest way for someone to get you secrets would be to dump temporary files that ansible creating to do it's job on remote server, since it requires only privileges of the user you are connecting as!
There is a special environment variable called ANSIBLE_KEEP_REMOTE_FILES=1 used to troubleshoot problems. It should give you an idea about what information is actually stored by ansible on remote disks, even for a brief seconds. I've executed
ANSIBLE_KEEP_REMOTE_FILES=1 ansible -m command -a "echo 'SUPER_SECRET_INFO'" -i 127.0.0.1, all
command on my machine to see files ansible creates on remote machine. After it's execution i see temporary file in my home directory, named ~/.ansible/tmp/ansible-tmp-1492114067.19-55553396244878/command.py
So let's grep out secret info:
grep SUPER_SECRET ~/.ansible/tmp/ansible-tmp-1492114067.19-55553396244878/command.py
Result:
ANSIBALLZ_PARAMS = '{"ANSIBLE_MODULE_ARGS": {"_ansible_version": "2.2.2.0", "_ansible_selinux_special_fs": ["fuse", "nfs", "vboxsf", "ramfs"], "_ansible_no_log": false, "_ansible_module_name": "command", "_raw_params": "echo \'SUPER_SECRET_INFO\'", "_ansible_verbosity": 0, "_ansible_syslog_facility": "LOG_USER", "_ansible_diff": false, "_ansible_debug": false, "_ansible_check_mode": false}}'
As you can see - nothing is safe from the prying eyes! So if you are really concerned about your secrets - don't use anything critical on suspected hosts, use one time passwords, keys or revokable tokens to mitigate this issue.
It depends on how paranoid are you about this credentials. In general: no, it is not safe.
I guess root user on remote host can see anything.
For example, run strace -f -p$(pidof -s sshd) on remote host and try to execute any command via ssh.
By default Ansible write all invocations to syslog on remote host, you can set no_log: no for task to avoid this.

How do you use ssh in a shell script?

When I try to use an ssh command in a shell script, the command just sits there. Do you have an example of how to use ssh in a shell script?
Depends on what you want to do, and how you use it. If you just want to execute a command remotely and safely on another machine, just use
ssh user#host command
for example
ssh user#host ls
In order to do this safely you need to either ask the user for the password during runtime, or set up keys on the remote host.
First, you need to make sure you've set up password-less (public key login). There are at least two flavors of ssh with slightly different configuration file formats. Check the ssh manpage on your system, consult you local sysadmin or head over to How do I setup Public-Key Authentication?.
To run ssh in batch mode (such as within a shell script), you need to pass a command you want to be run. The syntax is:
ssh host command
If you want to run more than one command at the same time, use quotes and semicolons:
ssh host "command1; command2"
The quotes are needed to protect the semicolons from the shell interpreter. If you left them out, only the first command would be run remotely and all the rest would be run on the local machine.
You need to put your SSH public key into the ~/.ssh/authorized_keys file on the remote host. Then you'll be able to SSH to that host password-less.
Alternatively you can use ssh-agent. I would recommend against storing the password in the script.
You can use expect command to populate the username/password info.
The easiest way is using a certificate for the user that runs the script.
A more complex one implies adding to stdin the password when the shell command asks for it. Expect, perl libraries, show to the user the prompt asking the password (if is interactive, at least), there are a lot of choices.

Resources