Call ssh-copy-id in an Ansible playbook - How to handle password prompt? - ssh

I have two servers. I manage serverA with Ansible. serverB is not managed with Ansible. I want serverA to be able to access serverB by copying the ssh_pub_key of serverA to serverB.
This can be done manually by calling ssh-copy-id user#serverB on serverA.
I want to do this with Ansible on serverA automatically.
- name: Register ssh key at serverB
command: ssh-copy-id -i /home/{{user}}/.ssh/id_rsa.pub -o StrictHostKeyChecking=no user#serverB
Calling ssh-copy-id requires me to enter my ssh password for user#serverB, so the key can be copied.
How can I do this via ansible? I want it to ask for the user#serverB password interactively while executing the playbook. Storing the password in ansible vault is also an option. Then I still do not know how to avoid the interactive password call of ssh-copy-id though.
I also added -o StrictHostKeyChecking=no to the call because this is another interaction that normally requires user interaction when calling ssh-copy-id.

If using the ssh-copy-id command is not a restriction, you might as well try out the Ansible authorized_key module.
Then your code could look something like this:
authorized_key:
user: <user>
key: "{{ lookup('file', '/home/' + lookup('env', 'USER') + '/.ssh/id_rsa.pub') }}"

You can try sshpass tool. It would require modification of your command like this:
command: sshpass -p password ssh-copy-id -i /home/{{user}}/.ssh/id_rsa.pub -o StrictHostKeyChecking=no user#serverB
but there are other options how to provide the password -- see the sshpass(1) manual page.

Related

Is there any way for SSH to automatically insert password?

I am currently developing some work in clients and servers application and my college allows us to use their machines (linux) to host and test the apps.
My problem is that every single time I want to ssh into the machine the server prompts me to insert the password. I managed to use the information here to use a key in order to login but it still asks me for my password into the machine.
Using Putty I can save my password and login straight, is there anyway to do this using this command:
ssh -t (myUser#theSSHLink) -p 22
via Git Bash?
try:
USERHOST="myUser#theSSHLink"
cd ${HOME}
if [ ! -f ".ssh/id_rsa" ]; then
ssh-keygen -t rsa
fi
ssh $USERHOST mkdir -p .ssh
cat .ssh/id_rsa.pub | ssh $USERHOST 'cat >> .ssh/authorized_keys'
Running the above will ask for your password (from the user#host) twice. Afterwards, it shouldn't ask for a password when you try to ssh.

Ansible SSH authentication with password and private key

For security reasons and compliance, we're required to set up 2FA on our hosts. We implement it by forcing authentication with passwords AND a public key with the AuthenticationMethods setting in sshd_config. The private key is required to have a password as well.
So in order to run playbooks on these hosts, we need to be able to enter the login password and the password of the private key. I've used the -k flag together with the ansible_ssh_private_key_file option in the hosts file (or with the --private-key flag). It asks for the SSH login password but then it just hangs and never asks me for the private key passphrase. When I set the -vvvv flat I see that the key is passed correctly, but the SSH login password isn't passed with the command:
<10.1.2.2> SSH: EXEC sshpass -d10 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o Port=22022 -o 'IdentityFile="/home/me/.ssh/id_ed25519"' -o 'User="me"' -o ConnectTimeout=10 -o ControlPath=/home/me/.ansible/cp/db574551ae 10.1.2.2 '/bin/sh -c '"'"'echo ~me && sleep 0'"'"''
How can I make Ansible work with both passwords and public keys?
As stated in the Ansible Documentation:
Ansible does not expose a channel to allow communication between the user and the
ssh process to accept a password manually to decrypt an ssh key when using the ssh
connection plugin (which is the default). The use of ssh-agent is highly recommended.
This is why you don't get prompted to type in your private key password. As said in the comments, setup a ssh agent, when you'll be prompted for it:
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa
Then, after playbook execution, clear out identities so to be asked for passwords the next time:
# Deletes all identities from the agent:
ssh-add -D
# or, instead of adding identities, removes identities (selectively) from the agent:
ssh-add -d <file>
You may pack key addition, playbook execution and cleaning into one wrapper shell script.

Ansible percent expand

I have an ansible playbook which connects to a virtual machine via a non-standard ssh port (forwarded to localhost) and a different user than the host user (vagrant).
The ssh port is specified in the ansible inventory:
[vms]
localhost:2222
The username given on the command line to ansible-playbook:
ansible-playbook -i <inventory from above> <some playbook> -u vagrant
The communication with the VM works correctly, however, %p always expands to 22 and %r to the host username.
Consequently, I cannot flush the SSH connection (for the user's changed group membership to take effect) like this:
- name: flush the ssh connection
command: ssh -o ControlPath="~/.ansible/cp/ansible-ssh-%h-%p-%r" -O stop {{inventory_hostname}}
delegate_to: 127.0.0.1
Am I making a silly mistake somewhere? Alternatively, is there a different way to flush the SSH connection?
The percent expand is not expanded by ansible, but by ssh later on.
Sorry, forgot to add the most important part
Using
command: ssh -o ControlPath=[...] -O stop {{inventory_hostname}}
will use default port, because you didn't specify it on the command-line. You would have to specify also the port to "flush" the connection this way:
command: ssh -o ControlPath=[...] -O stop -p {{inventory_port}} {{inventory_hostname}}
But I don't think it is needed. Ansible should clean up the connections when the playbook ends and I don't see any different reason why to do that.

Ansible: Permission denied (publickey, password)

I'm not able to connect to a host in Ansible. This is the error:
192.168.1.12 | UNREACHABLE! => {
"changed": false,
"msg": "ERROR! SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which
will enable SSH debugging output to help diagnose the issue",
"unreachable": true }
This is my hosts file:
[test]
192.168.1.12
And this is the ad-hoc instruction:
ansible all -m ping
I'm able to connect via raw ssh.
By default Ansible try to use SSH keys. It seems that you have wrong keys. Try to use Password authentication.
ansible all -m ping --ask-pass --ask-sudo-pass
I Hope it helps.
#bigdestroyer, to setup ssh public keys use this playbook
- hosts: all
remote_user: root
vars:
authorized_key_list:
- name: root
authorized_keys:
- key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
state: present
roles:
- { role: GROG.authorized-key }
Execute this playbook with --ask-pass since you'll use it to setup public key authentication.
ansible-playbook setup_ssh.yml --ask-pass
This role will add your current user public key to remote host authorized_keys file.
NOTE
ask-pass works only one time per run so this will only work with hosts that has the same password.
I usually use -limit and execute in batches on hosts that has the same password.
For example, let's assume host1,host2 and host3 has password foo host4 and host5 bar
ansible-playbook setup-ssh.yml --ask-pass -l host1,host2,host3
provide password foo
ansible-playbook setup-ssh.yml --ask-pass -l host4,host5
provide password bar
THEN
ansible -m ping host1,host2,host3,host4,host5
You can read the role documentation here
For those that come here running Ansible 2.6, --ask-sudo-pass is now deprecated. The correct syntax is:
ansible all -m ping --ask-pass --ask-become-pass
I encountered this issue - my ssh keys weren't set up correctly. I fixed this using the following:
Make sure each machine has an ssh keys set up, using the ssh-keygen command.
ssh-keygen
Pass your public key over to the machine, using the ssh-copy-id command.
ssh-copy-id -i <location of id_rsa.pub> <ip-address of host>
This helped resolve my error, hopefully it helps!
I resolved this issue by adding --ask-pass argument

Ansible prompts password when using synchronize

I'm using ansible in the following way:
ansible-playbook -f 1 my-play-book.yaml --ask-pass --ask-sudo-pass
After this I'm asked to enter the ssh & sudo passwords (same password for both).
Inside my playbook file I'm using synchronize task:
synchronize: mode=push src=rel/path/myfolder/ dest=/abs/path/myfolder/
For each host, I'm prompted to enter the ssh password of the remote host (the same that I entered in the beginning of the playbook run)
How can I avoid entering the password when executing synchronize task?
If you have setup the ssh keys correctly on the <host>, then the following should work.
ansible all -m synchronize -a "mode=push src=rel/path/myfolder/ dest=/abs/path/myfolder/" -i <host>, -vvv
I was able to get the above working without any password prompt.