Multi-hop Transport

[ ssh(1), ssh_config(5), SSH Productivity Tips ]

You sometimes have hosts for which you want to maintain configuration versioning (using Hippo) but the client cannot connect directly to your aggregate repository (central-host.)

To get our configuration files from the client to the final-destination, we must pass-through an intermediary/bastion host. We want to be able to copy the configuration from the client host through the intermediary.

[ Client ] |---ssh---> [ Bastion ] >>---ssh---> [ Destination ]

This guide discusses multi-hop ssh, where we proxy the ssh transport through an intermediate (or bastion) host.

  1. Configuration
  2. Verification
  3. Shortcuts

1. Configuration

Because we use git/hippo to push to a URL that is using SSH as the default transport, we can use SSH's aliasing and proxying features to simplify our command-line, such that we can hippo push updates to a URL that we are not directly connected to. The SSH transport's alias is used to reference a tunneled (proxied) connection through the bastion (intermediary) host.

We set up our SSH Alias (tunnel) such as in the following configuration:

In your ~/.ssh/config file add a section as follows:

Host DestinationAlias
    ProxyCommand ssh -Aq IntermediateHost nc -w 10 %h %p
    Hostname DestinationHost
    ForwardAgent no
    ForwardX11 no

Where the above options are discussed below:

Config Entry More Information
DestinationAlias The alias we will use in our ssh user@hostname command-line for connecting to the host behind the intermediate host.
IntermediateHost The DNS or IP Address for you Bastion Host
nc -w 10 %h %p The nc(1) (or netcat)
DestinationHost The final target host.

With the OpenSSH 5.4 release, OpenSSH provides the -W 'netcat mode' to 'route connections via intermediate servers'

'netcat mode' to

Host DestinationAlias
    ProxyCommand ssh -W %h:%p IntermediateHost
    Hostname DestinationHost
    ForwardAgent no
    ForwardX11 no

2. Verification

We can now confirm (and accept ssh prompts) to the above hosts with standard ssh connections:

  • make sure we can connect to the IntermediateHost
  • on the IntermediateHost, make sure you can connect to the DestinationHost
$ ssh -Aq IntermediateHost

Welcome ...

Verify that the connection is successful on the IntermediateHost.

From the IntermediateHost, verify the connection is successful to the destination host:

$ ssh DestinationHost

Welcome ...

The above verifies that the steps from our client to the destination host, is succesfully stepped through.

  • make sure we can connect to the DestinationHost directly (with ProxyCommand creating a through tunnel for us)
$ ssh DestinationAlias

If things work correctly, you should get a prompt that this is a new host, and whether to accept the host ssh signature.

Accept, and you can now push or pull to the destination host, using the assigned shortcut name.

$ hippo push DestinationAlias:repo_path master
Command-Line Entry More Information
repo_path The full path on the remote host to the repository

3. Shortcut

The above example show that we have to explicitly enter the full repository path (for the GIT/Hippo repo) at the destination host. This can lead to a number of typing errors if you are versioning a large number of hosts. Fortunately, Git's shortcuts to resolve the URL. We can use this to standardise our command-line for all hosts.

File extract: ~/.gitconfig


[branch "master"]
    remote = origin
    merge = refs/heads/master

[remote "origin"]
    url = DestinationAlias:repo_path
    fetch = +refs/heads/*:refs/remotes/origin/*

The DestinationAlias is resolved by SSH using ~.ssh/config and we can now use the same command-line on all hosts to push updates to the central repository.

$ hippo push origin master