How to set ssh to try not only port 22 but secondary port every time?

You could wrap a shell script around ssh but ssh itself will not do it.

One way using a bash function is this (put into ~/.bashrc):

function ssh() { command ssh -p 22 "$@" || command ssh -p 5492 "$@"; }

By the way, it is recommended to use root-reserved ports for system services like ssh in order to avoid users from having a process that listens on, say, port 5492. They may otherwise play man in the middle and possibly capture login data. So, use a port < 1024.


ssh itself can do this via Match documented in ssh_config(5) though the documentation is somewhat sparse on examples. This form may be suitable if one wants to push the complexity into the SSH configuration though is restricted by the limitations of the ssh_config(5) syntax and may require some fiddling with for the desired outcome. Notably the custom port can either not be set or can be set wrongly from the previous Match attempt. This is why, below, it is set twice when tested for, or once for the default, and is not set when establishing the canonical defaults.

# here we set the defaults for the host (no port!)
Match !canonical host testhost
  CanonicalizeHostname yes
  Hostname 192.0.2.42
  IdentityFile ~/.ssh/id_blahblah
  ...
# port available?
Match canonical host 192.0.2.42 exec "is-ssh-up %h 2222"
  Port 2222
# or the default port
Match canonical host 192.0.2.42
  Port 22

is-ssh-up merely checks whether something responds on the given port and might look like

#!/usr/bin/env expect
package require Tcl 8.5
if {[llength $argv] < 2} {
   puts stderr "Usage: is-ssh-up host port"
   exit 1
}
puts stderr "is-ssh-up: DEBUG trying $argv"
set socket [socket -async [lindex $argv 0] [lindex $argv 1]]
chan event $socket readable [list exit 0]
after 3000 [list exit 1]
vwait godot