That bag of SSH tips and tricks
Here is a quick set of SSH tips that will immeasurably improve your efficiency as a developer or an engineer:
1. Use SSH keys
SSH can automate logins with SSH keys. You will almost never have to deal with passwords once you start using SSH keys. First up, generate a set of public/private key:
ssh-keygen -t rsa
You will be asked for a passphrase. Enter a long-ish phrase you will definitely remember, you will need it when using the SSH key. This creates two files in your home directory, within the .ssh/ subdirectory:
~/.ssh/id_rsa and ~/.ssh/id_rsa.pub
Now, copy them over to your server as follows (clearly, replace username and server with your username and server):
ssh-copy-id username@server
Now, if you SSH into your server, it will prompt for a password to unlock your local private key (id_rsa). To have it cache your password, run:
ssh-add ~/.ssh/id_rsa
With this, you will only be asked to enter your password once for any number of SSH logins to the server.
2. Run the SSH daemon on non-standard ports
This is a common trick. Imagine a scenario where you’re in a foreign network environment which is blocking all outgoing network traffic except those through HTTP (port 80) and HTTPS (port 443). How can you SSH out?
Easy peasy, edit sshd.conf (which should be in /etc or /etc/ssh) and add the following Port directive:
Port 443
Note that multiple Port directives can co-exist, so it may be helpful to keep port 22 running in addition to port 443. Restart the SSH daemon, and ssh to your server by specifying the port:
ssh username@server -p 443
Thus, you’d happily have broken out of the restrictive network environment. With SSH tunnels, this means that you can tunnel any TCP traffic easily despite draconian network policies. Win!
3. Keeping secure through encrypted SSH tunnels
You can proxy traffic from your machine through a secure encrypted SSH tunnel. On your machine, run:
ssh -D 8888 username@server
This sets port 8888 on your machine as the proxy port. So, in your web browser, IM client, IRC client or any other TCP client, set SOCKS5 proxy to localhost:8888. For FireFox, I use QuickProxy which works really well for turning proxies on/off quickly.
And voila, the proxying Just Works(tm)!
4. Accessing closed networks through reverse SSH tunnels
A common scenario is that you have your application running within somebody else’s network environment and their network administrators are either too incompetent or too lazy to allow remote SSH access to the machine running your application. If you get permission from the network administrator, you can build a tunnel from the machine in the closed network environment to your server, and use that tunnel to gain access from an external location.
Let’s refer to this machine in the closed network environment as remotemachine, with a valid username called remoteusername (not very creative, are we? :)). Well, on remotemachine, run:
ssh -R 10002:localhost:22 username@server
This binds port 10002 on your server such that any SSH connections to that port are tunnelled to port 22 on the machine. On your server, to access the machine, run:
ssh machineusername@localhost -p 10002
This forwards the SSH request from your server to remotemachine, attempting to authenticate with machineusername. With SSH keys and autossh (see below) to restart the tunnel if it dies, you will have access 24×7.
5. Keeping SSH tunnels alive
Modern day firewalls are ridiculously pesky, and often, zealous (and clueless) network administrators tend to set timeouts for idle TCP sessions. SSH offers some help here. The ServerAliveInterval in ~/.ssh/config set a timeout interval in seconds after which if no data has been received from the server, SSH will send a message through the encrypted channel to request a response from the server. This, effectively, keeps the SSH session (or specifically: tunnel, as the case may be) alive.
Host *
ServerAliveInterval 60
This setting works well with autossh, noted below.
6. Using autossh to auto-reconnect SSH sessions
autossh is a program to start a copy of SSH and monitor it, restarting it as necessary should it die or stop passing traffic. It’s available on most Linux distributions, as well as FreeBSD/OpenBSD.
It’s easy enough to run. A simple plain vanilla SSH session can be run as follows:
autossh -M 10000 username@server
That is all there is to it! If your network connection reconnects (a common enough occurence for me, when I leave office and go back home), autossh will detect this and reconnect accordingly. It’s worth describing the -M monitoring parameter: autossh will set up forwards so that it can send data on port 10000 and receive it back on 10001.
7. Forwarding Goodness
Suppose you wished to tunnel encrypted email, such that your email application would connect port 110 (POP3) on your laptop, and that the data is automatically sent to your server’s port 110, over an encrypted SSH tunnel. This is easily achived by the -L parameter:
ssh -2 -N -f -L 5110:localhost:110 username@server
-2 specifies to use version 2 of the SSH protocol (you shouldn’t be using anything older). -N specifies that no remote command should be executed as we’re just forwarding ports. -f specifies that SSH should to go to background. With this, I then set my email client to connect to port 5110 on my laptop, and it is automatically forwarded to port 110 on the server.
We can get funky with this. To expand on point 4 (accessing closed networks through reverse SSH tunnels), suppose you wished to have an application (for example, a web browser) on your computer to connect to service on the remotemachine (for example, a webserver). We have a reverse SSH tunnel set up. Next up would be to run the following on server:
ssh -L 12345:localhost:80 remoteusername@localhost -p 10002
This binds port 12345 on server to port 80 on remotemachine. Then, on my laptop, I run:
ssh -L 12345:server:12345 username@server
This forwards data on port 12345 on my laptop to port 12345 on the server, which in turn forwards it to port 80 on remotemachine.
8. Running remote commands
This is a simplest trick that a surprisingly number of people don’t know (smack yourselfs!). Run a remote command on the server by:
ssh username@remote “command”
Yep, it’s that simple and it can be used very effectively in shell scripts to manage multiple remote servers!
9. Backing Up
Backups are one of those things we don’t do, because its so darn annoying to schedule, backup and store it somewhere. Fortunately, with ultra-cheap disks, it is appropriate to set up a backup server and ridunculously easy to schedule backups with cron, SSH and tar:
tar zcvf - /home/ditesh | ssh username@server “cat > backup.tgz”
Add a wee bit bash scripting and the backups can be properly ordered by date and executed by cron. This approach is actually faster then using scp and ssh -C (-C enables transparent SSH compression).
4 Comments