Open SSH is possibly the single most important tool in my software stack.

It's how I connect to the development & live servers that I do all my work on, sure. But it's more than that. It's the transmission medium for git, which makes it vital all on its own. It's how I move files around. It's how I work from home or the office without any real interruption. It's security, and it's convenience, and it's cloud-like delocalisation all rolled into one.

Most people don't realise just how versatile a tool it is. So this is one of the more comprehensive pages.

The .ssh directory in your home folder is very important for the functionality - one thing in particular to watch for is that the permissions must always be 700 - YOU should have full access to the folder, but nobody else must be able to read OR write OR execute anything in your .ssh folder - this leads to many problems that give no useful warnings. Check your permissions!

So, first off - you have an SSH session set up to a server, and then you want to have a second connection (I generally have at least four connections to one server running) It's annoying to have to keep entering a password when it should know damn well who you are, right?

Well, you don't have to, because once you've got one auth done, you can have SSH share that single authorised channel with as many sessions as you care to use! In your .ssh/config put:

ControlMaster auto
	ControlPath /tmp/ssh_mux_%h_%p_%r

Now you'll only ever get asked for your password the first time. All other connections are free. Except.. if you log out of a server and then suddenly remember there's something else you had to do.. you have to start at square one. Unless, of course, you have SSH not just share your sessions, but remember them and keep them alive a little longer than your sessions for just such an emergency!

ControlPersist 5m

That one line is all you need to keep your SSH connection open for five more minutes. No problems with having to log back in within moments of logging out - you can keep your connection open for HOURS if you want.

Now that's great. Except you still have to enter a password ONCE. And that can be annoying. So what about fixing that little issue and just not having to bother with passwords?

Easily done, courtesy of the magic of keys and key forwarding.

Now, the amount of security you keep in your keys varies by situation - it's up to you whether you think it needs a passphrase or not. If your home partition is encrypted, or you're on a machine that's in a secure location, I fail to see any benefit in having a passphrase. But it's up to you. So:

 $ ssh-keygen

Follow the prompts, get yourself a shiny new key. This will get you a couple of files in your .ssh/ - id_dsa which is your private, hyper-important, keep-safe-at-all-costs key. And id_dsa.pub which is your public, give away anywhere, stick it anywhere you want it key. Do *not* get these confused!

 $ ssh-copy-id yourname@your.server.com

This gets your public key on the server you want it to be on. It's basically a simpler way of doing it than the alternative of scp'ing it to the server and appending it to the authorized_keys file.

Now when you try to ssh to a server, you don't need to give it your password. Instead you give it nothing and just log in (if you have no passphrase) or you give it your passphrase. You might think that exchanging a password for a passphrase isn't a big leap ahead. BUT you'd be wrong, because modern Linux installations step in at this point: They remember your passphrase for you, so you only have to enter the passphrase once per login. Much better! But I still rarely bother with passphrases, too much hassle. But I only use keys on my secure office machine or my encrypted-home-partition home PC. YMMV.

Next up, we have what some people don't even realise is a problem, but I do so often that I couldn't live without the functionality: Connecting to a second remote server via the first remote server. Without needing another password, OR needing your private key to be copied everywhere.

What you do is, you tell SSH to not just USE your private key, but forward it - this way, first you make a connection from A to B. This uses your key. Then when you try to connect from B to C, your key gets forwarded from A, via B, to C. So no need for a password or passphrase on EITHER server. So long as you've copied your public key to both servers, of course.

 ForwardAgent yes

You could just use ssh -A for the same thing, but it's too much typing. And we don't like excessive typing!

That's why we put a few useful entries into our .ssh/config file. Because ssh by default will use your current username when connecting to another server, so you have to specify both name and server. But you don't want to use a full server name all the time, you want it shorter. For instance, on my home machine I use 'dominic' as my username; but on my work machine I'm 'djh'. And I don't want to be always typing ssh djh@devel.work.com for no reason. It'd be nice if I could just type ssh devel and SSH would just work out the rest. And that's what I do, by using the config entries:

Host devel
	    HostName devel.work.com
	    User     djh

Simple as that!

I think that's about as good as we're going to get our simple SSH connection: We just have to give some indication of what server to connect to, and we get as many connections as we want, without any need for domain names, user names, passwords.. we don't even get slowed down by the auth process since we're sharing the session.

But we're nowhere near done with what SSH can do yet!

Tunnels are a hugely useful part of my use of SSH. I first came across this when I was working somewhere that routed all its internet traffic through Switzerland. Bit of a problem because so many websites would detect this, set their language to German, and offer no obvious way of getting it back to English. So I routed my connection via SSH to my home PC.

How to do this? The command is basically of the format connect to this server and link my local port X through the SSH connection to that server's port Y

 ssh remote -L 8080:localhost:80

This will connect you to the remote server, and allow any traffic pointed at your local port 8080 to go to their port 80 (usually their webserver).

Using a reverse tunnel can also be very helpful - if you have a computer, such as a typical office PC, that can access the internet but not be accessed from the internet, for instance.

 ssh -R 12345:localhost:22 remote -N

This will connect you to the remote server and create a tunnel, but this one will allow anyone connecting to the remote server's port 12345 to actually connect to your machine's port 22 - which is the ssh port. So with this tunnel running, you can SSH to your machine via the remote server from anywhere that can access that server.

But what about uses that are less command-line focussed?

Well, for one thing, courtesy of X11's server-client model, you can run most Linux apps on a different server from the one they're displaying on. And OpenSSH supports forwarding of X11 traffic:

 ForwardX11 yes

Add that to your config and, so long as the remote server supports it, you can now SSH to it and simply run the application you're interested in - I typically want 'gitk', there was a time I'd run Pidgin too - and it'll simply work, altho possibly a little slower than you'd ideally like.

Then there's manipulating files. There's the direct approach - text editor in an SSH session. There's the indirect methods - anywhere you can SSH to, you can usually sftp or scp files to & from. But a more convenient & yet less well-known command is sshfs

The syntax is simple enough:

 sshfs remote:folder/ local_folder/ 

This will mount the 'folder' on the 'remote' server on the 'local_folder' on your own machine. It can then be accessed exactly like any other part of your file system - via your own file manager, photo editor, text editor, web browser, whatever. Very useful - particularly for a remote folder full of photos that you'd like to view all the thumbnails of, I find.

Another way in which sshfs can really smooth things out is if you're on computer A and you want to easily move files from computer B to computer C: Simply use sshfs to mount B and C's folders onto your local A drive. Then you can drag & drop files using your favourite file manager to move things from B to C - a complex networked file transfer made to be as simple as moving a file around on your local PC. And completely secure, too.

Lastly: Occasionally, I find I want to edit a remote file without quitting my text editor. Since vim is the best text editor, this is easily possible:

 :sp scp://user@server/path/to/file

And vim takes care of accessing the remote file for you. Clever, innit?