Yubikey
People that know me think I’m “too paranoid”. Personally, I think they’re all in on it together. ;) But I do like to make things as secure as possible. This is why I own my own domains, why I surf via SSL as much as possible, and why I run my own servers.
I have my own mail servers running. I even forward my Yahoo mail to this server so I don’t have to trust Yahoo with my email. I have used the most secure software I could find (Postfix and Dovecot), put a firewall in front of them, and host my webmail over SSL only. It was a bit scary to realize that running my own mailer meant I had to allow anyone in the world to connect. After watching my logfiles for a month or so, I was sorely tempted to just block Taiwan completely, but I refrained. They were not getting through Postfix anyway, and I wasn’t seeing any spam, so why bother?
The webmail was a different story. Only I need access to it. So I used the firewall to reject any connections not coming from me. How did I know which machines were “me”? Well, I figured I’d be checking in from work, so I allowed any IPs from my employer to pass through. I’m traveling a lot these days, so when I first get into a hotel I capture the IP block in use and (via SSH) add an exception to the firewall.
This is a bit of a pain, but I figured it was good enough for now. And the logs don’t show anyone getting in, so it’s probably good enough forever. But I’m a bit paranoid (I’ve been told). Enter Yubikey.
For work, I have remote access to the company network via a secure VPN. And the company uses two-factor authentication, providing an RSA SecurID token for the purpose. I liked this idea a lot, but every vendor of such tokens wanted me to buy hundreds of tokens, use proprietary software or hardware, and cost big bucks per token.
There are certainly non-token options: I could generate some one-time passwords and print them out, I could install an Android app on my phone to give me one at the press of a button. (I do not currently consider my phone to be anything close to secure, so that last option is out.) And I liked the idea of a single-purpose token.
Two-factor authentication is nice, but it doesn’t really solve all your problems. For example, it is completely vulnerable to a Man-in-the-Middle attack. The Yubikey folks state that a replay attack (capturing and reusing the OTP in a later session) will not work. For now, I believe them. And, ultimately, this is just another speedbump into my system.
First you have to find me (a standard scan won’t find my machine), then you have to get through the firewall(s). Next you have to know the username (not my name or anything you’d guess), and find my password (three failures and you’re history). With Yubikey, you now also need to have the correct OTP. A future project will force Apache to only talk to people with proper client SSL certificates, which allows my server to authenticate the incoming connection as being me.
I somehow stubled on the Yubikey. This is a small, thin OTP generator that costs $25. It’s a clever idea: to the computer it appears to be a USB keyboard. When I log in to my web mail, there’s a text field for “Yubikey OTP”; I just put the mouse in that field and press the button on the device. It “types” my OTP into the box for me and (annoyingly) presses return for me.
I bought one, and tonight installed it for my webmail. I use Squirrelmail, and they have a standard plugin for this device. I followed the standard plugin installation routine, then had some fun trying to figure out how to configure it. The docs for the plugin are missing a large chunk of information. So here’s what I had to do.
I had to go to https://upgrade.yubico.com/getapikey/ to generate an “API ID”. This permits the plugin to query the Yubico server to check my OTP is valid. I don’t really trust the Yubico authentication server, so I will eventually run my own. But for now it’s good enough.
I now change the config_yubikey.php file to include my API ID. The last step in the INSTALL file says to use the Squirrelmail configuration tool to activate the plugin. So I do that, then test the login page. It appears to work, but it rapidly became clear that it was not using my OTP. It simply accepted username/password as usual.
I started looking for logs; Squirrelmail doesn’t seem to have any. Instead, they seem to want to print errors to the page (how will I know if someone is accessing my login page? or if they succeed?) So I do a bit of hackery by going to the init function and forcing it to fail no matter what the config file says. That does trigger the error message, so I know init is being called. I do something similar with the code that sets up the “personal options”, and sure enough I get an error saying that code failed.
Now that I’m wondering what these “personal options” are, I log in to the webmail and look at the “Options” page. No “Yubikey” section is found. Hmmm. But there is a “Personal Information” section. I try that, and way down at the bottom is a “Yubikey Options” section. (Why this is “Personal Information” and not its own section is a mystery.)
So I check the box that requires Yubikey for access, and wonder what the “Primary Yubikey ID” means. This has been a problem throughout my journey into the plugin source: I’m sure the developer knew what he meant by his variable names, but I certainly didn’t. He either didn’t bother to use the Yubico terminology, or Yubico has changed what it calls things and he hasn’t updated the plugin to match. In this case, I was guessing that it was the “API ID” I generated from the Yubico page. I try that and no joy. So I check the code again, and see that a function later in the code has a comment to see if the user entered a full Yubikey OTP string, and seems to fiddle with it a bit. So I try that, and it seems to be happy. (It turns out that the first 12 characters of the OTP are the token ID. So what he wanted here was that ID for my token. And he allowed me to specify a second token if I had one. And that is what he meant by “primary” and “backup”.)
Now, I try it again. This time I get an error for a function “curl_init” not found. A bit of checking shows that a php curl wrapper is a prerequisite for this plugin. (“Helpfully” documented in the README instead of the INSTALL doc.) So, this being Debian, I install it easily. Still doesn’t work, same error. So I ask Dr. Google and he tells me I have to restart Apache to get this new PHP module recognized. I do it, and now things work.
So this was a bit more of a hassle than I expected, but I think it’s worth the effort. I will also install the PAM module for yubikey, and can then control my SSH sessions via the yubikey as well.
With this in place, I can remove the IP restrictions from the firewall, and allow connections in from whatever hotel or coffee shop I’m at. But not right away. I want to watch the logs for a bit to be sure things are working properly.
It’s probably overkill, but I’ve been told I’m paranoid.