How to get HostName from executable script in SSH config file

ssh

I frequently need to ssh into an arbitrary computer from a particular cluster (all machines in the cluster are identical). However, the set of available machines in the cluster changes frequently, so I have a script that returns an arbitrary hostname from the cluster that is available and matches my requirements (e.g., online and running the correct OS).

Note also, that I'm using Kerberos (GSSAPIAuthentication) credential forwarding for authentication.

Right now, I ssh in using ssh `get_host`. I would like to instead execute ssh cluster. With a known hostname, this is easy with the following in /ssh/config:

Host cluster
    HostName static_host.cluster.domain.tld
    GSSAPIAuthentication yes
    GSSAPIDelegateCredentials yes

How can I select the HostName dynamically, using my script? (Or does SSH have a different method to support my desired function?) I would like to do something like the following, but it does not work:

Host cluster
    HostName `get_host`   # This does not work
    ...

Grawity showed that the ProxyCommandcan be a script that gets the hostname and forwards the ssh connection to it using netcat or socat. However, this isn't forwarding the Kerberos credentials. Help with this is appreciated as well.

EDIT:

You can't do this with Kerberos as I would like (see comments in the accepted answer). So, I'm using this script, ssh-wrapper, as an ssh alias to do dynamic rewriting on the ssh command-line argument. It's not robust, but it works for me.

#!/bin/bash

# Mapping between host aliases and dynamically-generated hostname
declare -A MAP
MAP[cluster]=`gethost`

# Find and replace on all positional args
args=$*
for key in ${!MAP[@]}; do
    replace=${MAP[$key]}
    args=`echo ${args} | sed "s/\(^\|[[:space:]]\)${key}\(\$\|[[:space:]]\)/${replace}/"`
done

# Execute using called-name if not this script
if [ "ssh-wrapper" != "`basename $0`" ]; then
    exec $0 ${args}
# Otherwise, assume ssh and execute
else
    exec ssh ${args}
fi

Best Answer

~/.ssh/config:

Host cluster
    ProxyCommand ~/bin/cluster-connect

~/bin/cluster-connect:

#!/bin/bash
socat stdio tcp:$(get_host):22
Related Question