So I use ssh a lot. And this is one damn powerful little program. I decided to write up a log of some of my favorite ssh tricks.
Using ssh as a proxy server (to avoid your company’s/country’s anal probeware)
SSH has a built in SOCKS proxy that you can use in any program that can run over a SOCKS proxy. This includes Firefox (really, all browsers), Thunderbird, Pidgin/Adium (as well as almost all other IM clients like Google Talk, AIM, etc) and a ton of other networking programs we all use. Using SSH with the -D flag lets you create a dynamic ssh tunnel that acts as a SOCKS proxy, and sends all your traffic from the endpoint of your ssh connection.
To run ssh as a proxy, you need to run it like this:
ssh -D 127.0.0.1:3128 someserver.com
This command says you want to run a dynamic port forward, and it should be available on your local computer on port 3128 (default for SOCKS). All traffic that runs through this will appear to be coming from someserver.com (where you need to have an ssh account). Further, all traffic that you send through this tunnel will enter the tunnel without ever leaving your box, travel over that tunnel using ssh’s crypto, then exit at it’s endpoint where it can connect to whatever you want it to connect to. Return traffic follows the same path but in reverse. This is a great trick not only for avoiding firewalls (so long as your firewall does allow port 22 traffic), but also for surfing the web on any network that you don’t trust. Instead you can browse the web/read your email from a server you control and trust by doing all your networking via an encrypted ssh proxy.
To configure Firefox to use this crypted tunnel, click on Edit->Preferences, and select Advanced. From there, under Connection, click on Settings. You will want to select Manual proxy configuraion. Leave everything blank except SOCKS Host: localhost and Port: 3128. Check SOCKS v5. If you want to be able to access any resources that are on your local network without using the proxy, enter the local addresses or networks into the No Proxy For: box.
Using a single connection (and only having to enter in the password once)
If you want to be able to make connections to a box, and are sick of typing in the password multiple times for multiple connections, you can use ControlMaster. This allows you to have multiple ssh terminal sessions shared over one connection. This means that you only establish one connection, and one consequence of that is you also only need to do auth once when you establish the connection. You can enable this by editing ~/.ssh/config and adding *:
One nice side effect of this is that you can do an ls ~/.ssh and see exactly which boxes you are connected to presently.
Using multiple ssh keys transparently
When I started at my present job, everyone was using keychain to manage the large number of ssh keys they had to deal with from our various servers. You don’t need a key manager to transparently utilize multiple ssh keys. Once again pop open ~/.ssh/config, and now instead of workign with the Host * section, you can create sections for each class of server you access (or individual servers). If you have multiple ssh keys that need to be used on multiple servers, you can avoid using -i and instead add a section for a class of server, and declare the ssh key inside of that via IdentityFile. Example:
Now, whenever you ssh to any box in the staging subdomain, it will use the staging key, and when you ssh to any box in the production subdomain, it will use the production key.
Some firewalls regularly snip idle connections. If you regularly find ssh sessions that you have left idle for a while to be unresponsive when you come back to them you are suffering from this. Not only is it irritating to lose your connection, but you may even find the whole terminal unresponsive, forcing you to close the terminal as well. Well, ssh config has an answer for you for this as well.
ServerAliveInterval is normally off, but when you turn it on, ssh will start sending a packet every n seconds to try to keep the connection open. Even better, now that it’s testing, if the connection truly did go away without being closed, SSH will automatically close the session if 3 of these keep alive packets go unresponded to. (you can set that to a different number by setting ServerAliveCountMax). This means that even when connections get snipped, you won’t come back to find an unresponsive terminal. Either the connection will be alive, or the connection will have closed, none of these unresponsive zombie connections.
Defaulting your remote user
Few people are lucky enough to have the same username on all the servers they regularly visit. Just as you can set the identity file on a per domain basis, you can also set username:
Now when you ssh to somedomain.com, unless you specify the username at the prompt (firstname.lastname@example.org) it will use foo. This overrides the default of using your logged in username.
Do you have a lot of domains you ssh to that you wish you had shorter names for? Do you have some things that you ssh only to via IP address? Both of these can be solved with the HostName directive. For example, if your gateway accepts ssh traffic, and your internal domain doesn’t use dns, you can use ssh config to give in an alias for ssh.
Now it’s as simple as typing
ssh router to get to the gateway. This trick works with ip addresses or dns names.
Executing remote commands with ssh
Sometimes you only need to get a small piece of information from a server, and don’t want to bother with a full ssh session. Sometimes you may want to have a process that goes out to a server and runs a command as a part of a bigger script. Either way, you can use ssh to run individual commands on other boxes, and get the results on stdout and stderr. Give this a try:
devon@chronos ~ $ ssh evilsoft.org "uptime"
14:00:23 up 7:38, 1 user, load average: 0.84, 0.34, 0.22
SSH is a powerful toolkit, and I have only scratched the surface of it’s possibilities. Spend some time reading
man ssh_config and you’ll be amazed at some of the incredibly cool stuff in there for you to find.
* note, you only need one Host * section in your ssh config. All the variables I am discussing can be consolidated into one Host * section.