How to share/persist a SSH connection from a shell script that runs multiple commands

I have a shell script that connects via SSH to the same host (my-server) and runs a variety of commands mixed throughout the script. For example:

ssh -o ConnectTimeout=3 -o ConnectionAttempts=3 user@my-server "foocommand here"

mkdir -p /path/here
touch service.conf
...

ssh -o ConnectTimeout=3 -o ConnectionAttempts=3 user@my-server "barcommand here"

mkdir -p /other/path/here
touch /other/path/here/service.conf
...

ssh -o ConnectTimeout=3 -o ConnectionAttempts=3 user@my-server "darcommand here"

And so forth. The problem is each SSH connection open and handshake takes a bit of time as the server my-server is geographically far away from the running script.

Is there a way to speed up this process and prevent opening a new SSH connection for each required command? Anything like http keep alive for SSH?


Solution 1:

Yes, you can set up ssh to keep a persistent connection to a remote server. This is done with the ControlMaster, ControlPath and ControlPersist options.

A sample configuration (place in $HOME/.ssh/config):

ControlMaster auto
ControlPath ~/.ssh/sockets/%C
ControlPersist 600

Setting ControlPath enables connection sharing; while an ssh connection to a remote host is open other ssh connections to the same user/host will be multiplexed over the connection.

Setting ControlPersist allows the connection to remain active for a period of time after the last ssh session exits.

Setting ControlMaster to auto allows ssh to reuse an existing connection or create a new connection if necessary.

See the ssh_config(5) man page for a detailed explanation of these options.