[TriLUG] SSH security

Igor Partola via TriLUG trilug at trilug.org
Thu Sep 3 13:54:21 EDT 2015


So this should probably be a blog post, but I'll just post it here for now.
Since there was some discussion on here about ssh, ssh keys, etc. let me
share some of my hard-acquired experience in this area:

First, always use ssh keys. One of the first things you want to do is
disable password-based logins. If you are not convinced that this is a good
idea do `tail -f /var/log/auth.log` and take a look at all the bots trying
to pick weak passwords on any Internet-connected host with sshd running. To
disable password-based logins do this in /etc/ssh/sshd_config:

    ChallengeResponseAuthentication no
    PasswordAuthentication no
    UsePAM no

To generate a key for yourself, do this:

    $ ssh-keygen -t rsa

If you live in the future (that is use newish distros), you can use ECDSA
instead of RSA and get a smaller key:

    $ ssh-keygen -t ecdsa

RSA will work everywhere, whereas ECDSA will not work with old distros.
ECDSA may be more secure and is faster to use, but (1) there is no evidence
that a 2048 bit RSA key is weak, and (b) you'd need a really slow box to
feel any difference.

Passphrase-protect your key and keep it only on machines you physically
use. I don't believe in having a separate key for each machine. My work
laptop and my home computer have the same private key. I have physical
access to both and have no reason to trust one of them more than the other.
Protecting it with a passphrase means it's secure at rest (assuming the
passphrase is long enough).

Use gpg-agent or ssh-agent. gpg-agent can store ssh keys as well as private
gpg keys, so it is slightly easier. I am not going to go into details on
how to get ssh or gpg agent running since this varies from OS to OS and
sometimes from distro to distro. Suffice it to say, it is generally well
documented and sometimes is already configured for you.

Next, you can forward your ssh-agent connection to a new host. Here is an
example (remember only my work laptop has the rsa_id file here):

    igor at work-laptop $ ssh -A remote-host-a
    igor at remote-host-a $ ssh remote-host-b
    igor at remote-host-b $

When going from remote-host-a to remote-host-b I don't have to enter any
passwords. In fact, I can have password authentication disabled on both
remote hosts and this would work. Why? Because the -A option tells ssh to
create a UNIX socket on remote-host-a that is then connected, through my
ssh session, to the ssh-agent socket running on my laptop. Beautiful, right?

If you don't want to remember to specify -A every time, you can create/edit
your ~/.ssh/config and add the following:

    Host *.example.com
        ForwardAgent yes

There is a security issue with the above setup. If remote-host-a was
compromised and someone got root access on it, they can interact with my
ssh-agent UNIX socket. This is called ssh agent hijacking. If they do that,
they then may log into remote-host-b or any other host I have access to.
Because of that, it's best to not forward your ssh-agent to any host you do
not trust. Note that it's not as bad as the attacker actually getting your
private key. They can only log into these other servers while you have an
ssh session open to remote-host-a. See
http://www.clockwork.net/blog/2012/09/28/602/ssh_agent_hijacking for
details.

To mitigate ssh agent hijacking, ssh-add (1) has a -c option. When you add
a key with -c, every time your private key is used a confirmation program
will be executed first. By default this program is located at
/usr/libexec/ssh-askpass. If it returns 0 the key usage is allowed,
otherwise it is denied. You can write a custom script to log the key usage,
display a popup warning about it in your notification tray, or even pop up
a Yes/No dialog. I did the latter for OS X here:
https://github.com/ipartola/mac-ssh-confirm.

Lastly, I really don't like entering passwords into remote hosts. You never
know if someone compromised remote-host-a and replaced /usr/bin/sudo with a
script that transparently calls real sudo but also emails the attacker your
password. Let's be honest, almost nobody has a different random password
for all the servers they have access to. To fix that I like to use
pam-ssh-agent-auth (https://github.com/cpick/pam-ssh-agent-auth).
Basically, I authenticate to the remote host using my private key. It's not
passwordless sudo because I have to prove to the remote host that I have
the private ssh key that corresponds to the public key listed in my
~/.ssh/authorized_keys, but as long as I forwarded my ssh-agent to the
remote host I don't have to enter my local password. I often do keep a
random password as a backup, but now I can just store it on some keychain
instead of having to memorize it.

There are many more topics to cover here, such as Certificate Authority
based client and server ssh keys, monkeysphere, etc., but this is hopefully
enough to give you a taste of what you can do to make your life easier and
more secure with ssh.

Igor


More information about the TriLUG mailing list