Ssh – How to make Ansible use password if key was rejected

ansibleauthenticationssh

My new server instances are configured to login on root via ssh with password. I want my Ansible playbook to reconfigure it to use keys instead and disable root login with password on first run, so I need something like this:

  • try to login with key
  • if can't login with key:

    • login with password
    • add key to authorized_keys
    • disable root login with password
    • optionally reconnect using key
  • do other tasks

How can I accomplish that?

EDIT: To be clear, I'm not asking how to add key or disable root, that's just for context. I'm asking how to fallback to password if it couldn't authenticate with key. With --ask-pass or ansible_ssh_pass set, Ansible won't even try to use public key authentication

Best Answer

You could try the PreferredAuthentications option, setting it to publickey,password. The default includes these in this order, along with other options, so ansible is presumably setting this. Adding it via -o or the client ssh_config may prevent this.

You may be able to use a wrapper script. For example, with this in key_or_password.sh and a pass.sh that gives the password, running bash key_or_password.sh root@host will try a publickey followed by a non-interactive password login.

export DISPLAY=dummy:0
export SSH_ASKPASS=$PWD/pass.sh
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"

The log indicates which method succeeded with, e.g.

debug1: Authentication succeeded (publickey).