Sharing Multiple SSH Sessions over the Same Network Socket

Featured image for sharing metadata for article

At Capital One, we deploy our services to the AWS Cloud, where I will sometimes need to SSH onto a development instance to debug using log files or by attaching a debugger.

Although I am a big fan of using tmux for creating multiple windows on a given session, I'm unable (and/or unwilling) to install it any time I'm needing to debug. This means that I'll have tmux running on my local machine, and then have multiple, separate, SSH sessions to the remote.

Our instances are locked down by using Active Directory logins, so each time I connect to an instance I need to put in my password, which slows me down as it's quite a long one! Sometimes I'll log in, and then realise after some debugging I need to re-connect with some SSH port forwarding, i.e. to access the HTTP server locally.

However, I found recently that there's the ability in OpenSSH to share a network connection, which means that after the initial connection, it can reuse it for speed of connecting and sending data. Even more conveniently this includes authentication details, which means on a repeat connection, I don't need to supply my Active Directory password.

For example, assuming that my instances in a development environment were served on IP ranges beginning with 10.5., I could add the following configuration:

Host 10.5.*
	ControlMaster auto
	ControlPath ~/.ssh/sockets/%r@%h-%p
	ControlPersist 120

(Note that you'll need to mkdir -p ~/.ssh/sockets the first time you add this config)

You'll notice that I've used an intentionally low persist timing of only 120 seconds. This is mostly due to the potentially short lived lifecycle for an instance, as a new instance (from another team) could well be spun up with the same IP as the instance I was using before. By keeping them alive for only 2 minutes, I have a good window of time to "remember" to want to come back and use the instance, as well as not being so long that I risk trying to reconnect to an old instance, which has since had its IP recycled.

This configuration then will create sockets with names like jamie@10.5.1.2-22 or root@10.5.1.4-55222.

When performing a login, the flow is the same, but creates a Shared connection and a socket:

local $ whoami
jamie
local $ ls ~/.ssh/sockets
local $ ssh root@10.5.1.2
Enter your password:
remote $ whoami
root
remote $ exit
Shared connection to 10.5.1.2 closed.
local $ ls ~/.ssh/sockets
root@10.5.1.2-22

Now, when I log in, with the socket still active:

local $ whoami
jamie
local $ ls ~/.ssh/sockets
root@10.5.1.2-22
local $ ssh root@10.5.1.2
remote $ whoami
root
remote $ exit
Shared connection to 10.5.1.2 closed.
local $ ls ~/.ssh/sockets
root@10.5.1.2-22

And notice how here I didn't need to specify my password, as the network connection was still active.

We can also see the huge differences in speed of handshake overhead:

local $ ls ~/.ssh/sockets
# on the first connection
local $ time ssh root@10.5.1.2 whoami
root
ssh root@10.5.1.2 whoami  0.03s user 0.00s system 4% cpu 0.637 total

# on a following connection
local $ ls ~/.ssh/sockets
root@10.5.1.2-22
local $ time ssh root@10.5.1.2 whoami
root
ssh root@10.5.1.2 whoami  0.00s user 0.00s system 7% cpu 0.083 total

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #ssh #openssh #command-line.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.