Since I joined Charm, I’ve been working and learning more about SSH, and I thought I would share a few quick tips and tricks with you.
Forward Yubikey Agent
If you use a Yubikey (you should), you can use it in your remotes by having the key in a SSH agent and forwarding it.
To manage the agent, I strongly recommend yubikey-agent.
You can then forward it in your ~/.ssh/config like the following:
Host example.org
ForwardAgent true
And then, after SSHing you can check its working by running:
Which should list your key.
You might also want to add this to your ~/.tmux.conf, so the agent works properly on reconnect:
set -g update-environment "DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY"
setenv -g SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
You’ll also need to create a ~/.ssh/rc with the following content in your target machine:
#!/bin/bash
if test "$SSH_AUTH_SOCK" ; then
ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi
SSH runs this file when connecting, and it’ll override a local link to the agent socket, which we use as our actual SSH_AUTH_SOCK (see the tmux config above).
You can learn more about it by reading this blog post.
By the way, do not enable this to all hosts, as it might be considered insecure, especially if you are using a shared user. I only do this on a local server in my home network.
Reuse connections
If you connect and disconnect from some machines “a lot”, or, maybe, you’re using some sort of SSH application or API, you might benefit from keeping a connection open and reusing it.
You can do so by adding something like this to your ~/.ssh/config:
Host example.org
ControlMaster auto
ControlPath ~/.ssh/%r@%h:%p.sock
ControlPersist yes
This will create a Unix Socket at ~/.ssh/user@host:port.sock, and use that connection when it is available.
Eventually the server will close the connection (on its timeout), or you can force it by running:
You can also force a given max time for a socket to be alive by setting ControlPersist to a duration instead of yes, e.g. ControlPersist 60s, so it’ll be kept open for at most 1 minute.
Also worth noting that its not very safe to do this in just about any server you have access to, especially if you set ControlPath to, say, /tmp.
SSH straight into tmux
If you work into a remote machine like I do, its likely you use a multiplexer as well, like tmux for example. If that’s the case, you might want to SSH directly into a predefined tmux session to speed things up.
You can do so by adding something like this to your ~/.ssh/config:
Host example.org
RemoteCommand tmux new -A -s default
This will either attach to or create and attach to a session named default. This is what I use regularly, and it works like a charm.
Alias commonly used hosts
If you SSH into a host very often, you might want to have a shorter name for it.
A common way to go around that is with a shell alias, but you can also do so with pure SSH config.
For instance:
Host ex
HostName example.org
User foo
Port 2223
Will allow you to, instead of typing:
ssh foo@example.org -p 2223
Type:
Instead.
I particularly use this in conjunction with some previous tips in my development server, so I can simply ssh dev and get into a tmux session, with my Yubikey SSH agent forwarded, with a simple command.
Do not add testing stuff to ~/.ssh/known_hosts
I develop some SSH apps using Wish, and I usually test them locally quite a bit. This might end up cluttering my ~/.ssh/known_hosts file, also leading to key checking errors.
I prevent that by disabling strict key checking and using /dev/null as the known hosts file on localhost:
Host localhost
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
You can use globs in the Host part, so you can, for example, do the same for your company testing servers or something in that sense.
Make connections last longer
If the server has a short idle timeout, it might disconnect you sooner than you wish. You can prevent that by having your client ping the server every X time.
You can do so by adding something like this to your ~/.ssh/config:
Host *
ServerAliveInterval 60
This will ping the server every 60 seconds for all hosts.
Canonicalize hostnames
If you access multiple machines in the same TLD, you might want to enable hostname canonicalization:
Host *
CanonicalizeHostName yes
CanonicalizeFallbackLocal yes
CanonicalDomains mytld.foo.bar
That way, to SSH into host1.mytld.foo.bar, you can simply run:
It might be particularly useful for .local, so you can access other machines in your network with just their name, without the .local suffix.
Yubikey and GitHub, without touching it every time
If you find it a bit annoying that yubikey-agent asks you to touch it every time you do anything with Git, this might be helpful, although it is a bit against the principles of using a Yubikey.
In any case, here you go:
Host github.com
ControlMaster auto
ControlPath ~/.ssh/github.sock
ControlPersist 10s
ServerAliveInterval 0
This will use the ControlPersist tip we saw earlier, but instead of closing the connection after the server times it out, we explicitly tell it to last 30 seconds. We also disable the ServerAliveInterval feature.
So what happens is here:
- when you do some remote git operation, it’ll open the socket, asking you to touch the Yubikey
- if you do another operation in the next 10 seconds, it will reuse the same connection
- 10 seconds after the initial connection, the socket will be closed, and you’ll have to authenticate again
It might be useful when you do a lot of git operations at the same time, e.g. update Vim plugins.
That’s it!
That’s what I wanted to share today. Let me know if you have more tips or tricks I forgot to mention or don’t know about, I’d love to learn them!
Cheers!