Getting Comfortable With SSH
jcsalterego.github.com
jcsalterego.github.com
1. The security implications. Without a passphrase, anyone who manages to snare a copy of your private key can use it to access any servers where you've authorized it with no further credentials needed. Not good. Using a passphrase turns SSH auth into a poor man's two factor system: what you have (the key file), and what you know (the passphrase).
2. It breaks agent-forwarding, which is the system that gives you the ability to SSH onwards from the remote machine to other machines without (again) being asked for your password. This has practical implications when using SSH to drive things like application deployment over git, when you have to ssh onward from the server to your git repository. Doing things this way sidesteps the awkward use of deploy keys, and is actually easier to set up and use as well as being more secure. With agent forwarding, there's no need to keep your private key anywhere except your 'home' machine, and yet you get the same benefits your would if you had it everywhere.
The annoyance of having to type in your passphrase every time is greatly lessened by the use of a key agent on your 'home' machine. OS X has provided a key agent since 10.5 I believe, and stores the passphrase in your Keychain (you know you're doing things right if an OS X dialog box prompts you for your passphrase when running SSH in the terminal). Gnome has one built in as well, and ssh-agent is always around for people who want to roll their own.
If there's interest, I'll write up a blog post about how to get this stuff set up. It's not really easily discoverable stuff, but it _is_ really simple and useful once you get it up and running.
I haven't taken the time to figure out key agent -- for shame! -- although I would be interested in a write-up.
I've been using gpg-agent with a smartcard for ssh authentication for the past six months or so. It's the way, the truth, and the light.
Real two-factor authentication. The key can't be compromised without trying to physically take apart the chip on the card and somehow access the internals. Three wrong password attempts and the thing locks. Three wrong attempts with the admin unlock code and the card self-destructs. So even if I lose the card or someone jacks it, it can't be brute forced.
(Yes I don't need that level of security, and I'm not even being paranoid; it's just neat. Makes me feel like James Bond or Batman or some shit like that every time I ssh somewhere. Yes I'm that lame... )
And since it's still using a standard RSA key for ssh authentication, I don't need to install anything special like experimental pam modules, on the host machines. Just copy the public key into authorized_keys. That's nice since I don't have full admin rights on a lot of my host machines.
Basically you either get a card and reader:
http://shop.kernelconcepts.de/product_info.php?cPath=1_26...
Or get an all-in-one cryptostick:
http://www.privacyfoundation.de/crypto_stick/crypto_stick_en...
And setup your gpg keys on there, either by generating them directly on the card or transferring existing keys. These are simple commands documented elsewhere. In addition to the normal signing and encryption keys, you also generate an authentication key.
Then 'ssh-add -L' will spit out your public key in ssh format to copy on the host machines as usual.
After that you just make sure that you'll use gpg-agent instead of ssh-agent. The man page for gpg-agent shows you what you'll want to add to .bashrc.
Then when you ssh into a machine, gpg-agent will take over, pop up a little dialog called pinentry, you enter your code, and you're good. When you go to lunch, remove card, and ssh authentication with that key no longer works.
If you're like me, however, you'll use both keychain and ControlMaster (for the increased negotiation speed) :)
How does it break agent forwarding?
I haven't tried but don't see why that should require a password on the private key.
ssh (the command) can access the material in your private keys in one of two ways, either by direct file access itself (in which case it will always ask you for a passphrase if there is one protecting the key in question), or else via an intermediating ssh-agent process. Roughly speaking, ssh does something like the following when looking for key material:
if private key file exists and has no passphrase on it
use it directly (and implicitly do not forward the agent)
else if ssh-agent is running
ask the agent for the key (and forward the agent)
else
ask the user for a passphrase ourselves (and implicitly do not forward the agent)
end
The end result of all this is that if you have an unprotected key, ssh doesn't talk to your local agent at all, and so obviously can't forward it.I'm glad he did mention my favorite config file option for setting the username:
Host example.com
User = someweirduser
That way I don't have to remember to "ssh someweirduser@example.com" because some client set up a weird user for me--I just "ssh example.com" instead.With aliases (and zsh completion support for aliases), I can do "ann<tab>" which saves me even more time.
It won't be long before all I have to type is tab :)
Host example.com
User someweirduser
Another subtle point about SSH config -- only the first matching entry (in top-to-bottom order) for a given parameter is taken from .ssh/config. If you have multiple Host entries that match for a given hostname, the first matching User, Port, etc, entry will be the one that ssh uses. # multiplex connections to one host
ControlMaster auto
# where is that file
ControlPath ~/.ssh/master-%r@%h:%p
Other useful things in my .ssh/config, check the manpages before you use them: # use compression
Compression yes
# really really compress it
CompressionLevel 9
# forward X stuff
ForwardX11 yes
# yes, really forward X stuff
ForwardX11Trusted yesThere's a good chance I was just doing it wrong™ though.
The way I usually do it is by opening something over TRAMP before opening any other ssh windows. That way, Emacs will handle the connection maintenance and I don't really need to see that it's up. If it dies, I just try saving something and it'll re-establish the connection.
If you don't use Emacs, you can always just start a dummy connection first and minimize/disown it.
Good tip about TRAMP, although I tend to exit out of my emacs sessions frequently. For my long running ssh tunnels, I just screen them.
I'd rather use ssh-agent for day to day work but this is a useful trick for scripting.
So, thanks for using RSA in the article!
EDIT: I just did some digging. Apparently DSA cannot be used to encrypt. One more reason to keep using RSA, I suppose.
The problem with DSA is that you can only have a key size of 1024 bits per the original standard. That's starting to get a little weak these days. (Keep that in mind if youi're using PuttyGen to make your keys!) This has since been changed, some systems use "dsa2" and higher bit counts, but it seems OpenSSH doesn't directly support that, at least according to the man page.
Anyway, the new version of OpenSSH just got ECC, which seems to be the future of public/private key encryption. So soon people will be talking trash on RSA. (I kid...)
An ssh session's escape sequence is "<Enter><tilde>", which if you refer as "<X>", you can do the following:
1. Kill an unresponsive ssh session: <X><period>.
2. Enter an ssh command line, to open new forwarding ports among others: <X><C> Then enter <question-mark> for help.
Seems kind of weird in the tunnel section that the -D flag was not mentioned which creates a dynamic tunnel that can go to multiple hosts when set up as a socks proxy in a web browser.
"ProxyCommand ssh <gateway_machine> nc %h %p"
You can do this by adding the above line in the relevant place in ~/.ssh/config, or on the command line like so: ssh -o "ProxyCommand ssh <gateway_machine> nc %h %p" user@destination_machine ProxyCommand ssh -W %h:%p <gateway_machineIt's from a series on setting a a Linus VPS for noobs, and I found it indispensable. My only problem is that my Linode runs so trouble free, that I rarely need to go in and mess with it, so even though I've been running a VPS for a year, I still have a limited knowledge of Linux administration.
Github compares it to leaving your password in a file on your computer for attackers to find, but it's MUCH worse than that. Such a password file could be anywhere on your computer and an attacker would have to search for it and may never actually find it unless it was clearly labelled.
SSH keys are defined in your SSH config file and attackers know exactly where that lives. Using a passphraseless ssh key is more like leaving your password on a sticky note attached to your monitor.
This article is spreading bad advice here to users who don't understand why, and the author should update his post and retract it.
Can you give a concrete example of a scenario in which an attacker will be able to read my SSH config file but not be able to get into my account? Suppose the SSH config file is not backed up.
I am not saying you are wrong about the need for a passphrase, BTW.