03 Apr 2017, 23:31

Additional layers of https and ssh security

After moving to the new blog host and scoring only a B on the SSL report, I wanted to make sure I was doing everything I could do secure the server from exploits. Part of the reason for moving was exactly that - increased security! On my journey to improve the score, I learned a fair bit about SSL, server and browser based attacks, and how to mitigate them.

I also did a bit of digging into how to secure my personal connection to the VPS over ssh. I’ll cover some information on that at the end of this post.

Weakness is unacceptable

Turns out that by default, nginx allows weaker versions of cryptographic technology that can be more easily penetrated by nefarious users. Specifically, an attacker can eventually intercept traffic between a browser and server. More reading, including a technical paper and mitigation, can be found here.

For now, we’ll focus on mitigation. Luckily enough, the same site has some information for sysadmins. Let’s get started.

Generating a better DH group

The above group is convinced that state-level actors are capable of penetrating 1024-bit groups. It wasn’t clear whether that is by sheer computing power or exploits. Nevertheless, the group recommends using at least a 2048-bit length group.

I figured that doubling wouldn’t hurt anything, so chose 4096 bits as the length. Running this command generates the .pem file we need to give to nginx.

openssl dhparam -out dhparams.pem 4096
sudo mv dhparams.pem /path/inside/your/jail

While we’re editing nginx configuration, I’ll also suggest that you enable Strict Transport Security (HSTS). It is helpful in preventing the same encryption downgrade attacks.

I added both HSTS and dhparams info to the nginx configuration file in the jail I created before. Mostly taken straight from their sysadmin suggestion page:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
add_header Strict-Transport-Security "max-age=31536000";


ssl_prefer_server_ciphers on;
ssl_dhparam /path/inside/your/jail/dhparams.pem;

Afterwards, restart nginx:

sudo service nginx reload

This was enough to get me to an A+ on the SSL test. Skeptical readers can run it themselves. Again, I’m not entirely sure how well qualified they are to give that grade - but as long as the grade is improving, things can’t be getting worse… right?

Hardening ssh

Now that the https part of the server was mitigated against most attacks, I wanted to see if there was anything I was missing on the ssh side of things. Knowing that OpenSSL is basically full of vulnerabilities and odd nuggets (here’s one of the latest ones I’ve seen), I figured the defaults weren’t good enough. And, according to at least one guy on the ‘net, I was right!

The information there is great. There’s also a very brief justification for most of the changes, enough to satisfy a sysadmin without needing a ton of security background. Those paying attention will notice the same information about weaknesses in DH that was covered earlier, in the https part of the post.

A small note: in the section about enabling Protocol 2, you’ll be asked to accept the new fingerprint (as the blog says). Even if you skip this step, however, you’ll likely be asked to accept the new fingerprint. The scary warning that pops up might make you think your server has been compromised, but it’s just using the ED25519 keys instead of the old, normally RSA keys.

That’s not to guaranteed your server wasn’t compromised, of course, but you’re probably fine if it happened in between updating your configuration.

Other avenues

Right now I can’t add too much to the linked resources, due to time constraints. I think a few things left unsaid, such as port knocking, are also worth considering. I’m considering adding that to my setup - expect a future blog post on its pros and cons to come.