Finally Killing SSLv3 On This Server

Finally Killing SSLv3 On This Server

Tutorials nginx poodle security ssl sysadmin

So it's been about ten days since Google's security team dropped the POODLE bug on everybody (that's Padding Oracle On Downgraded Legacy Encryption, which has to be one of the more tortured acronyms Ive seen this year, and Ive seen a lot of them), and Im only just now getting around to actually patching this server. I run this blog on a single little DigitalOcean droplet, nginx 1.6.2, Ubuntu 12.04 that I really should upgrade one of these years, and it took me until this Friday afternoon to sit down and fix it.

For anyone who somehow hasnt run into this yet: the short version is that SSL 3.0, the old encryption protocol from the mid 90s that browsers still fall back to sometimes, has a flaw that lets an attacker on your network potentially decrypt little pieces of encrypted traffic, like session cookies, by forcing a downgrade and abusing how CBC padding works. Its not a "the internet is on fire" bug like Heartbleed was back in April. Its more of a "well this really shouldnt still be enabled in 2014" bug. Which, honestly, describes a lot of what's running on the internet.

The fix is stupidly simple once you actually do it. You just tell your server to stop offering SSLv3 as an option at all. Here's what I changed in my nginx config, in the server block:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

That's it. That one line, dropping SSLv3 out of the list. Before, mine read SSLv3 TLSv1 TLSv1.1 TLSv1.2 because at some point years ago I must have copy-pasted a config from a tutorial and never touched it again. Reload nginx (sudo service nginx reload, not restart, no need to drop connections) and you're basically done. If you're on Apache it's the equivalent SSLProtocol All -SSLv2 -SSLv3 in your vhost or ssl.conf.

I also went and tightened up the cipher list while I was in there, because if Im already poking around I might as well not have to do this again in six months:

ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;

Copied most of that from Mozilla's SSL config generator page, which is a genuinely useful thing that exists now and I wish had existed three years ago when I first set this box up. Would've saved me a lot of guessing.

One thing worth actually checking after you do this: test it. I used Qualys SSL Labs (ssllabs.com/ssltest), which grades your config and tells you exactly what's still weak. My grade went from a B up to an A after the change, which felt disproportionately satisfying for something that took maybe four minutes of actual editing and about ninety minutes of me getting distracted reading about which browsers were dropping SSLv3 fallback support entirely (Chrome and Firefox are both planning to yank it in upcoming releases, so this stuff is going away whether you patch it yourself or not).

The annoying part, if there is one, is that this breaks connections from genuinely ancient clients, stuff like Internet Explorer 6 on Windows XP, which cant do TLS at all and only ever spoke SSLv3. If you've got a userbase running that combo you've got bigger problems than this blog post is going to solve for you. For a personal site with maybe forty regular readers, I was not losing sleep over IE6 users. I don't think Ive gotten a hit from IE6 since 2012.

If you run any kind of server with a cert on it, even a dinky little VPS running a WordPress install or, like me, a hand-rolled static site generator nobody asked for, go check your SSL Labs grade right now. It takes thirty seconds to run the test and probably another five minutes to fix whatever it flags. I kept meaning to do mine "this weekend" for going on two weekends now, which is a pretty normal way for these things to go if Im honest about it. The bug doesn't care that you were busy.