There are a ton of ssh tips out there, and I thought that I surface 3 of them. Here are 3 ssh tips that I’ve learned over the years. Hope you find them useful 🎉

SSH Agent and Forwarding Keys

Typically when you when ssh into a server with a key other than your default key, you must specify the path to your key with the -i option like so:

ssh -i ~/.ssh/demo/id_rsa-1 ec2-user@

Instead of having to specify the -i /path/to/ssh/key option repeatedly, you can use ssh-agent. With ssh-agent you can load your keys into memory with its ssh-add command. Ssh will automatically use the keys in memory. Here’s an example with a test server:

$ ssh-add -l
The agent has no identities.
$ ssh ec2-user@ # no keys in memory
Permission denied (publickey).
$ ssh-add ~/.ssh/demo/id_rsa-1
$ ssh-add -l
2048 SHA256:rK4MapkeuF5tDxcETK7JuYwq1EqiJTj3tc6so9Ei6fU /Users/tung/.ssh/demo/id_rsa-1 (RSA)
$ ssh ec2-user@ # do not have to use the -i flag
[ec2-user@ip-10-11-100-122 ~]$

You can load as many keys into memory and ssh will try them consecutively until you get into the box. One thing to watch out for though is that some servers are configured to block you after 3 rapid unsuccessful attempts. I only keep 3 keys in memory for this reason. Also, to delete keys from memory:

$ ssh-add -D
$ ssh-add -l
The agent has no identities.

Lastly, when using ssh-agent, it is useful know about the -A flag. This option forwards your keys in memory to the remote server you are accessing. This saves you from having to copy and paste the key onto that remote server if you want to then hop from that remote server to another server using the same keys. Let’s go inception on the server:

$ ssh -A ec2-user@ # first hop
$ ssh-add -l # your keys have been forwarded and are in memory
2048 2f:d6:4c:4b:db:a0:8a:e8:c2:f3:2f:3b:84:3a:60:21 /Users/tung/.ssh/demo/id_rsa-1 (RSA)
$ ssh ec2-user@ # second hop

Note: The ssh agent usually starts up automatically with most ssh clients but sometimes it doesn’t. If you get an “Could not open a connection to your authentication agent” error. Running this will start the ssh-agent up:

eval $(ssh-agent)

Note: If you’re using fish shell:

eval (ssh-agent -c)

SSH Tunnel for local development

When you are developing, it is useful to have a publicly accessible url to test. For example, you may want to see what the your website looks like on an iPhone. You can achieve this with an ssh tunnel. An ssh tunnel forwards a port on a server to a port on your local machine. Here’s an example that forwards port 9000 on the server to my local machine’s port 4000.

ssh -f -N -q -R 9000: ec2-user@

Now I can hit, and it’s the same as hitting http://localhost:4000 😁 I can use that remote endpoint to see the website on my phone and any saved changes get reflected immediately, no deploy required.

Note, for this to work you need to unblock the firewall rule for port 9000 and need Gateway=yes configured in /etc/ssh/sshd_config on the server. If you do not have access to a server to do this, there are other options like ngrok or finch. They do the same thing, except as a paid service.

You also might want to go the other way around. That is you want your local machine to forward to a remote machine that is running a server locally. Instead of starting that server up, whitelisting the security group, and making it accessible to world, just forward to it. Here’s that command:

ssh -L 8001:

That forwards 8001 from your machine to the remote machine. You can visit http://localhost:8001 as if you were within the remote server itself.

Escaping from a Dead Terminal

The final trick shows you how to escape from dead terminal hell. If you find yourself stuck in a dead terminal session and everything you type refuses to register. Instead of closing the whole terminal window, you can use the ~ . escape sequence. When you type ~ . (“tilde” and “period”) ssh will disconnect you even when the connection is dead.

Hope you found these tips helpful 😁