Tighter SSH Security with Two-Factor Authentication

How to set up two-factor authentication using a USB pendrive and ssh-agent for root logins.

Example 3: Tightening Up

We need to close a potential vulnerability before using this system
in the wild.

Using ssh-agent and agent forwarding allows the remote SSH server to
query the private key stored on your local computer. However, if you use
this system to log in to multiple computers, an intruder on one machine
can
potentially highjack those keys to break in to another machine. In that
case, this system could be more dangerous than one using static passwords.

To illustrate the problem, let's expand our example network from two to
three nodes by adding machine3 to the mix. Create key pairs for both bob
and root on machine3, as described in Examples 1 and 2, and add root's
private key to ssh-agent on machine1.

Now, ssh to machine3 as bob using the agent-forwarding option -A. Run
ssh-add -l, and you can see the public keys for
both machine2 and machine3:

In this example, ssh-agent on machine1 caches the private keys for
machine2 and machine3. This single agent allows us to log in as root on
either computer. However, using the single agent also potentially allows an intruder
on machine2 to log in as root on machine3 and vice versa. This
is not good.

Fortunately, we can fix this problem by using the ssh-add -c option; we
can add additional security by using individual ssh-agent instances to
store one root key for each remote machine. The -c option tells ssh-agent
to have the user confirm each use of a cached key. Devoting one ssh-agent
instance per host prevents any as yet unknown ssh-agent vulnerability
from
exposing one machine's key to another.

Using the ssh-add confirm option is easy; simply set the -c option
whenever adding a key to ssh-agent. Let's give it a try. Start two agents
on machine1, specifiying predefined sockets:

Checking your keys on machine2 and machine3 reveals only the root key for
that machine. In the previous example, by using a single ssh-agent,
you would have seen the keys for both machine2 and machine3.

Using separate ssh-agent instances for each machine you log in to requires
more work.

Resetting the SSH_AUTH_SOCK variable every time you want to log in to
another machine is impractical. To simplify the process, I've written
a simple script tfssh (two-factor ssh) to simplify the process. Its
syntax is:

tfssh [username@]host [keydir]

The script [Listing 1 on the LJ FTP site at ftp.linuxjournal.com/pub/lj/listings/issue152/8957.tgz] starts ssh-agent when necessary, sets
the environmental variable, adds the root keys to ssh-agent and logs
in to the remote machine as the user. You also can tell tfssh to look in
an arbitrary directory ([keydir]) for its keys and also set a key
timeout for the key cache.

Comment viewing options

Agree with Nicholas above. An ssh key + "passphrase" is indeed, not "two-factor" because, as he mentioned, the presence of a passphrase is never validated on the server.

Furthermore, an ssh key (something you have) which is stored onto a USB thumb drive (something you have) is still, technically speaking, single factor authentication. Much like requiring multiple "chained" passwords is still single-factor authentication.

A possible workaround is to use an SSH key which "forces" a command of "sudo /bin/login". By doing so, one would first authenticate with the SSH key (something you have), and then need to authenticate through the "regular" PAM stack (Something you know.) This has the added bonus that the "pam stack" authentication would enforce other rules such as password complexity, fail counts, and so forth.

RSA key authentication is a single factor authentication. The server only verifies your RSA key, which is the only authentication factor. The key's passphrase is only relevant for protecting your private key in your client machine. You can set empty passphrase, the server doesn't care.

The authentication would have been two factor, if the server verified both the key and a static password independent of the key.