SSH magic: Authorize only once for multiple ssh/scp invocations
OpenSSH has a nice feature that makes it possible to open one "master connection", which can be shared by multiple subsequent ssh/scp/sftp "slave connections". The advantage is that you need to supply password only when opening the master connection and thus you can easily perform a sequence of remote commands without constant re-authentication. Let's see how to do it in such a way that it can be used in a script.
The options have the following meaning:
You close the connection by sending the control command exit to the socket:
Notes:
It should be noted that at least some older versions of OpenSSH have the limitation that slave connections cannot set up port forwarding.
See the ssh manpage and the ControlMaster section on ssh_config for details.
1. Open the master connection
We will open an SSH connection that sets up the shared channel and puts itself into the background when authenticated and does nothing else:
SSHSOCKET=~/.ssh/myUsername@targetServerName
ssh -M -f -N -o ControlPath=$SSHSOCKET myUsername@targetServerName
The options have the following meaning:
- -M instructs SSH to become the master, i.e. to create a master socket that will be used by the slave connections
- -f makes SSH to go into the background after the authentication
- -N tells SSH not to execute any command or to expect an input from the user; that's good because we want it only to manage and keep open the master connection and nothing else
- -o ControlPath=$SSHSOCKET - this defines the name to be used for the socket that represents the master connection; the slaves will use the same value to connect via it
2. Open and close other connections without re-authenticating as you like
Now you can do as many ssh/scp operations as you like and you won't be prompted for a password. You only always have to provide the command with the same ControlPath, which we ensure by having stored it into the variable SSHSOCKET:
ssh -o ControlPath=$SSHSOCKET myUsername@targetServerName "echo 'Hello from the remote server!'; ls"
...
scp -o ControlPath=$SSHSOCKET myUsername@targetServerName:remoteFile.txt ./
3. Close the master connection
You likely don't want to keep the master connection open forever. And it's better to close it properly beause otherwise the socket file would not be deleted and would prevent the master connection from opening in the future.You close the connection by sending the control command exit to the socket:
ssh -S $SSHSOCKET -O exit myUsername@targetServerName
Notes:
- This time time we use -S instead of "-o ControlPath=" because we intend to use the socket for controlling the master SSH instance
- -O <command name> is used to send a command to the master SSH instance; the commands allowed are "exit" and "check"
Conclusion
This is a neat way how to execute multiple ssh/scp/... commands while only supplying a password once. There are also other ways how to do it, such as putting you key into the ~/.ssh/authorized_keys at the host or using the ssh-agent and ssh-add.It should be noted that at least some older versions of OpenSSH have the limitation that slave connections cannot set up port forwarding.
See the ssh manpage and the ControlMaster section on ssh_config for details.