I have some test servers running behind a bastion on Openstack. The test stack gets deleted and created often. After the stack is created I run a set of Ansible scripts to install and configure the servers. I have the process almost completely automated but I can't seem to get ssh-keyscan to work when the remote host is behind a bastion host.

This is what I have in my ~/.ssh/config

Host bastion
  User myuser
  IdentityFile ~/.ssh/private_key.pem

Host remote-host1
  User myuser
  IdentityFile ~/.ssh/private_key.pem
  ProxyCommand ssh -W %h:%p bastion

If I try to run ssh-keyscan remote-host1 I get

getaddrinfo remote-host1: Name or service not known

Running ssh remote-host1 works but it will prompt

The authenticity of host ' (<no hostip for proxy command>)' can't be established.
ECDSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)?

which I'm trying to avoid.

I know that there is a SSH option -o StrictHostKeyChecking=no and it's possible to pass this to Ansible using the ssh_args configuration option. I wouldn't want to use it though. I'm also aware that using ssh-keyscan without checking the fingerprint allows man-in-the-middle attacks. In this test environment scenario I'm willing to take the risk because only my IP is whitelisted for access.

  • Would it be an option to include SSHFP entries in your DNS at provision time? SSH clients can be configured to trust the DNS, and thus, avoid being prompted to trust the remote key explicitly. – dawud Jan 2 '17 at 14:44

Quick googling suggests that ssh-keyscan doesn't honour ssh config file and all other ssh tricks. (Although this thread is quite old).

With Ansible you can delegate keyscan task to your bastion host and then append you known_hosts file locally:

- hosts: localhost
  gather_facts: no
    - command: "ssh-keyscan {{ new_host }}"
      register: new_host_fingerprint
      delegate_to: bastion
    - lineinfile:
        dest: /root/ssh/known_hosts
        line: "{{ item }}"
      with_items: "{{ new_host_fingerprint.stdout_lines }}"

where new_host is the IP-address of created host ( in your example).


SSH to the bastion and run ssh-keyscan from there:

ssh bastion ssh-keyscan remote-host1
  • This only works if name resolution works correctly for "remote-host1" relative to the bastion. E.g. you'd probably have to set up entries in your /etc/hosts file on the bastion. – Dale Anderson Jan 22 at 23:31
  • If name resolution doesn't work correctly, you've got bigger problems. But you could also use the IP address instead of the (pseudo) host name, and add HostKeyAlias <addr> to the local ssh_config. – womble Jan 23 at 2:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.