1

Ansible uses OpenSSH as the bottomed network communicative implementation, but does it support multi-hop login?

I mean, if Ansible can login a server directly, but can it log in server_a then from server_a login server_b for config the server_b?

5

I do not know how Ansible uses OpenSSH.


But OpenSSH itself supports "multihop logins".

Since OpenSSH 8.0, you can use -J (jump) switch like:

ssh -J user1@host1.example.com user2@host2.example.com

With older versions (but at least 7.3) you can use ProxyJump directive:

ssh -o ProxyJump=user1@host1.example.com user2@host2.example.com

As @GordonDavisson commented, with even older versions (but at least 5.4), you can use ProxyCommand directive and -W switch:

ssh -o ProxyCommand="ssh -W %h:%p user1@host1.example.com" user2@host2.example.com

With even older versions, you can use nc command instead of the -W:

ssh -o ProxyCommand="ssh user2@%h nc host2.example.com 22" \
    -o HostKeyAlias=host2.example.com \
    host1.example.com

All the above options are covered in more details in Wikibooks article OpenSSH/Cookbook/Proxies and Jump Hosts.


Another options is to use port forwarding (-L switch). But that involves two ssh instances. I'm not sure if that's possible with Ansible.

  • 1
    For versions 5.4 through 7.2, you can use netcat mode: ssh -o ProxyCommand="ssh -W %h:%p user@host1.example.com". For versions even older than that, if there's a netcat` (or nc or...) binary on the jumphost, you can use that explicitly. – Gordon Davisson Oct 1 '19 at 17:25
  • @GordonDavisson Thanks. I've added that to my answer. – Martin Prikryl Oct 2 '19 at 7:17
1

For older Ansible versions you had to do it in the general SSH config as described in Martin Prikryls answer. New versions have Ansible specific config as described in the general FAQ

How do I configure a jump host to access servers that I have no direct access to?

You can set a ProxyCommand in the ansible_ssh_common_args inventory variable. Any arguments specified in this variable are added to the sftp/scp/ssh command line when connecting to the relevant host(s). Consider the following inventory group:

[gatewayed] foo ansible_host=192.0.2.1 bar ansible_host=192.0.2.2

You can create group_vars/gatewayed.yml with the following contents:

ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user@gateway.example.com"'

Ansible will append these arguments to the command line when trying to connect to any hosts in the group gatewayed. (These arguments are used in addition to any ssh_args from ansible.cfg, so you do not need to repeat global ControlPersist settings in ansible_ssh_common_args.)

Note that ssh -W is available only with OpenSSH 5.4 or later. With older versions, it’s necessary to execute nc %h:%p or some equivalent command on the bastion host.

With earlier versions of Ansible, it was necessary to configure a suitable ProxyCommand for one or more hosts in ~/.ssh/config, or globally by setting ssh_args in ansible.cfg.

This way you have a very Ansible-esque way of setting up SSH bastion hosts only where needed, together with any other special SSH settings (like keys, users, etc).

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.