23

I am writing an SSH config file and want to perform a bit of logic. For example:

Host myhost1
    ProxyCommand ssh -A {choose randomly between [bastion_host1] and [bastion_host2]} -W %h:%p

Is it possible to achieve the above using (bash?) variables? Thanks!

Bob Risky
  • 805
  • 1
  • 9
  • 22

4 Answers4

17

Your ProxyCommand can be a shell script.

host myhost1
    ProxyCommand $HOME/bin/selecthost %h %p

And then in ~/bin/selecthost:

#!/usr/bin/env bash
    
hosts=(bastion1 bastion2)
    
onehost=${hosts[$RANDOM % ${#hosts[@]}]}
    
ssh -x -a -q ${2:+-W $1:$2} $onehost

Untested. Your mileage may vary. May contain nuts.

Per comments, I've also tested the following, and it works nicely:

host myhost1 myhost2
    ProxyCommand bash -c 'hosts=(bastion1 bastion2); ssh -xaqW%h:22 ${hosts[$RANDOM % ${#hosts[@]}]}'

Of course, this method doesn't allow you to specify a custom port per host. You could add that to the logic of a separate shell script if your SSH config matches multiple hosts in the same host entry.

Michael
  • 8,362
  • 6
  • 61
  • 88
ghoti
  • 45,319
  • 8
  • 65
  • 104
  • 1
    In this script, the `$onehost` variable is set by selecting a random array element from a bash array. Your ProxyCommand is executed by your shell, so as long as your shell is bash, I don't see why you couldn't include the entire functionality of this script on a single line, though I haven't tried it. I answered this way because I don't know that you're using bash as your default shell. (On my system, I use bash for programming, but tcsh is my default shell.) – ghoti Nov 03 '15 at 15:05
  • 4
    "May contain nuts" Gave me a laugh! – UrLicht Feb 19 '18 at 18:59
  • Would you be able to point out [what I'm doing wrong here](https://stackoverflow.com/q/55579583/241211)? – Michael Aug 11 '20 at 19:58
  • 1
    Upvoted for nut warnings too. Six year old answers still fresh! – Scott Corscadden Jan 27 '21 at 15:10
10

In ~/.ssh/config you cannot have much logic, and no Bash. The manual for this file is in man ssh_config, and it makes no mention of such feature.

What you can do is create a script that will have the logic you need, and make your ssh configuration call that script. Something along the lines of:

ProxyCommand ~/bin/ssh-randomly.sh [bastion_host1] [bastion_host2]

And write a Bash script ~/bin/ssh-randomly.sh to take two hostname parameters, select one of them randomly, and run the real ssh command with the appropriate parameters.

Michael
  • 8,362
  • 6
  • 61
  • 88
janos
  • 120,954
  • 29
  • 226
  • 236
7

No; .ssh/config is not processed by any outside program. You'll need a shell function along the lines of

ssh () {
    (( $RANDOM % 2 )) && bastion=bastion_host1 || bastion=bastion_host2

    command ssh -A "$bastion" "$@"
}
chepner
  • 497,756
  • 71
  • 530
  • 681
0

This can be handled within ssh config by using a helper app. For example,

Host myhost match exec "randprog"
     hostname host1
Host myhost
     hostname host2

and then randprog will randomly return 1 or 0 (0 will match the first line, giving host1).

Malcolm
  • 61
  • 1
  • 2