Authenticated with partial success

The What

It’s hardening time again.

Following up on my post “DNSSEC, SSH and keys.” this is another post in the series of hardening your SSH server and your server in general. Are you using password login or public keys?

1238895886504840879

Indeed. Why not both? And I am not going to recommend you that should put a password on your ssh keys (which is nice) but rather recommend real two-factor authentication: Public Key and a Password. What does it do?

 

The How

Let me show you; but I am using kerberos instead of Passwords, so your mileage might vary, but the result is the same. At first connect your client gets the offer of sending either:

debug1: Authentications that can continue: publickey,gssapi-with-mic
debug1: Next authentication method: gssapi-with-mic
[...]
Authenticated with partial success.
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Trying private key: /home/creiss/.ssh/id_rsa
[...]
debug1: No more authentication methods to try.
Permission denied (publickey).

The important bits are in bold. What happens in human readable form:

  1. The Server offers to authenticate with Kerberos or (giggle, “or”) public keys.
  2. My client, having a valid kerberos ticket, sends it to the server.
  3. The Server accepts the kerberos ticket, but is greedy and wants more (authenticated with partial success). If my kerberos ticket would not have been valid, I’d get rejected right there.
  4. I moved my .ssh folder out of the way, so there is nothing for my client to send to the server. And even thou I was authenticated with a valid kerberos ticket I get denied. I need both public keys and kerberos to access.

Let’s check what happens which a valid public keypair:

debug1: Authentications that can continue: publickey,gssapi-with-mic
debug1: Next authentication method: gssapi-with-mic
[...]
Authenticated with partial success.
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/creiss/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 535
[...]
debug1: Authentication succeeded (publickey).
Authenticated to ns1.alpha-labs.net ([46.229.47.133]:22).

This is the same as above, but my ssh private key got accepted, resulting in authentication. So I need something I know (kerberos password) and something I have (public key pair).

Again, don’t panic about kerberos. Just replace ‘gssapi-with-mit’ with ‘password‘ and you’re set. If you can, go for kerberos. It’s called the “holy grail of network administration” for a reason.

 

The Why

If you really need an answer on why hardening your remote access to your server is crucial you should reconsider the guy in charge of your security.

 

The Implementing

To implement two-factor ssh authentication, be sure you know your password and that you have a key pair which has also been added to the authorized_keys file on the target server. Add this to your /etc/ssh/sshd_config file for CentOS 6.x:

RequiredAuthentications2 publickey,password

and this for CentOS 7.x:

AuthenticationMethods publickey,password

Easy? Easy. Be careful: If you lose your client side key pair you will be unable to log in (via ssh).

 

Taking it up a notch

But the fun does not stop there– and why should it? Now you can easily connect to your favourite server and get a user shell. I am seriously hoping you’re not allowing direct remote root access. Tell me you don’t.

Of course you don’t. You’re not crazy.

We use sudo.

sandwich
In this wonderful comic by xkcd there is no further authentication for granting superuser privileges– and of course there is no such thing; it’s a comic.

We however are serious admins. We want further proof. If you have your sudo to ask for a password then turn that off. Why bother having two locks that can be unlocked with the same key? A possible attacker that got to your shell has both your public and private key pair (can happen– hey, in the office someone is sitting in front of your pc (kill him, use a Nerf gun) or your notebook has been snatched at the airport) and your password. How an attacker managed to get the latter I leave open for discussion.

So for further authentication attempts you can’t re-use any of those again. But we want it comfy.

Enter the YubiKey. A cheap security token for your keychain, cost on amazon for 50 bucks (biggest edition, you can save if you get a smaller one). You put that device in your usb port and push a button. OTP magic happens and wham, authed:

[chris@artemis ~]$ sudo su -
YubiKey for `chris': 
Last login: Wed Aug 19 21:08:26 CEST 2015 on pts/2
[artemis ~]#

I just pressed that button, no enter no nothing. And I got root.

Installing is a trivial matter, there are packages in the stock repositories for CentOS (pam_yubico) and Debian (libpam-yubico). Do an yum install pam_yubico or apt-get install libpam-yubico respectively and you’ll end up with the right package. Onward with the configuration, then!

For all flavors, edit /etc/pam.d/sudo and add, below ‘#%PAM-1.0‘, this line:

auth     sufficient   pam_yubico.so id=[api_id] mode=client authfile=/etc/yubikey_mappings

Replace “[api_id]” with your yubico api id. If you do not have one already, get one from here. The line explained:

  • auth: Well, it does authenticate you, so 🙂
  • sufficient: Satisfying this rule alone will grant access. If you want a two-factor login where you also have to type in your password, replace sufficient with required.
  • pam_yubico.so: That’s the library we apt-get’ed or yum’ed earlier.
  • mode=client: tells said library to go to the “yubico cloud”, ie, the official api servers to check. Other mode would be “challenge-response” for offline validation using YubiKeys with HMAC-SHA-1 Challenge-Response configurations. (See the man-page ykpamcfg(1) for further details on how to configure offline Challenge-Response validation.)
  • authfile: Every YubiKey needs to be mapped to one user. Actually that’s wrong. A User can be assigned one-or-many Yubi-Keys. This is the mapping.

Edit (most likely create) the file /etc/yubikey_mappings, and add a user per line:

user:yubikey_id1:yubikey_id2: [...] yubikey_idn

real life example for me:

chris:dai3Oth2uqu3o

Don’t know your YubiKeys ID? Go to the ModHex calculator and give them one OTP (go into the OTP field and press your YubiKeys button). In the resulting page your ID is the “Modhex encoded” value. Sounds way more complicated that it is. As shown, separate each of your YubiKeys with a “:”.

That’s it for sudo. Next time you login, you’ll see the YubiKey prompt. Hit the button and feel the rootness.

 

The Summary

So now (and hopefully you) can now auth securely and ascend to root by simply ssh’ing (no passwords asked, kerberos hooray). In the background kerberos tickets and ssh key pairs are exchanged all of which I never see, I am dropped right at my user shell.

And if I want root: “sudo su –” and the push of a button– and that’s all there is to it.

As always: If you need help implementing, contact me above.

-Christian.

 

Christian

Touched base with Linux back in 1995, got hooked up on it ever since. I am using Linux for both private and office for two decades. Working as a System Administrator at a medium sized hosting company I get in touch with all kinds of trouble. All of which can be solved with Linux. In my blog I am sharing solutions to problems that I had to search for myself in hope that someone else out there might find them useful.

2 thoughts to “Authenticated with partial success”

  1. Hey Christian,

    Great article but in this case, how can one automate an SFTP task to run with this two step process? I haven’t been able to find one

  2. Hey,

    Sorry for the late reply. Depends on what step you need to automate. And whether you need sudo (and yubi) or not. I am using kerberos/ssh key combination for most my logins. The TGT is retrieved by cron every 6 hours with a lifetime of 7 hours. Since the ssh key is also stored locally this makes logging in a breeze.

Leave a Reply

Your email address will not be published. Required fields are marked *