3

I have setup a few GNU/Linux (Ubuntu and Amazon Linux) servers to prompt for Time-Based OTP using google-authenticator module for PAM and the keyboard-interactive:pam SSHD authentication method. I'm struggling to get ansible to prompt me for the OTP. The --ask-pass flag asks for the password before making the connection and passes it when making the connection. What I need is for ansible to just pass on the OTP request from SSHD on the servers to my shell. Is there a way I can do that?

Currently, ansible does not reliably pass on the response back to the server.

➜  ansible git:(master) ✗ ansible -m ping amazon1 --inventory-file=./ansible_hosts
Verification code: <I QUICKLY ENTER THE OTP HERE>
amazon1 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}

sshd_config on amazon1

...snip...
UsePAM yes
PubkeyAuthentication yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive:pam
...snip...

pam config on amazon1

#%PAM-1.0
auth        required        pam_sepermit.so
auth       required     pam_google_authenticator.so
...snip...

Normally, SSH works like this:

➜  ansible git:(master) ✗ ssh amazon1
Verification code:
Last login: Sun Mar 12 04:32:37 2017 from ip-10-0-1-23.ec2.internal
[admin@amazon1 ~]$

I know I can exclude a specific user from being prompted for OTP in sshd_config. I do not want to do that, however. I hope I'm not missing an obvious ansible flag for this. Thanks in advance.

eternaltyro
  • 262
  • 2
  • 14

2 Answers2

3

As already pointed out 2-factor authentication is currently not supported by Ansible.

There seem to be two options to workaround this caveat:

  1. disabling two-factor authentication for the Ansible user

I'm working around this with duo auth by excluding the ansible user's group in pam_duo.conf and login_duo.conf, and then setting the following in sshd_config:

Match User ansible  
    AuthenticationMethods publickey

So effectively disabling two-factor authentication for the Ansible user.

  1. using a bastion host

I finally implemented something similar to this: http://blog.scottlowe.org/2015/12/24/running-ansible-through-ssh-bastion-host/

I open up the initial connection to the host which has 2FA, then in another window run something like:

ansible-playbook thing.yml --ssh-common-args='-o ControlPath=~/.ssh/connshare'

Take a look at the discussion in this github issue.

Henrik Pingel
  • 9,380
  • 2
  • 28
  • 39
  • Unfortunately, our bastions are ephemeral and don't have OTP enabled. It's the server behind the bastion that has OTP enabled. This makes it difficult to use `ControlPath` – eternaltyro Mar 14 '17 at 15:51
  • Ah, ok, I see. I wouldn't wonder too much if it turns out that such a setup is not possible with Ansible. Have you checked if running Ansible in `pull mode` is an option for you? [Ansible pull example](https://github.com/ansible/ansible-examples/blob/master/language_features/ansible_pull.yml) – Henrik Pingel Mar 16 '17 at 07:48
  • thanks, that seems interesting and useful. I'll check that out. – eternaltyro Mar 19 '17 at 08:55
  • Even with a "nullok" in the google_authenticator PAM config, the ansible git module will fail as it won't accept even an empty keyboard-interactive challenge. Workaround 1 worked well for me. Thanks! – Ville Laurikari Mar 09 '18 at 08:21
2

No, Ansible does not want to support that, as discussed in the github issue(s):

Yep, not something we're immediately planning to support.

You should really consider SSH keys.

Jakuje
  • 9,715
  • 2
  • 42
  • 45
  • I have setup SSH keys already. OTP is in addition to SSH Key authentication. `AuthenticationMethods publickey,keyboard-interactive:pam`. Thanks. – eternaltyro Mar 14 '17 at 12:14
  • Yes, that was just quote from the above issue. Having keys (with passphrase) should be good enough. – Jakuje Mar 14 '17 at 12:17