Ayesh Karunaratne: Full-time traveler, freelance software architect and security researcher
Tue, 2016-06-28 02:55
Serving your web site via HTTPS is paramount nowadays, with the coffee shop owners to governments sniffing your data, crooks tampering them, and popularity of web services use in mobile apps, desktop apps, and bots, HTTPS has become one of the first things you need to take care of. Fortunately, with significant effort from many parties, it is now quite easy to almost-instantly make your web site work over HTTPS, and that is without costing a dime!
Refresher: How your browser connected to an HTTPS web page
- Browser makes a DNS lookup to get the IP address of the domain name.
- Browser sends a request to the server that it needs to connect to the given domain name. This does not send any actual data of the request; just that it needs to connect to the domain name. Read more about Server Name Indication.
- Server sends an SSL certificate.
- Browser verifies the authenticity of the certificate.
- Browser creates an encryption key, and signs it with the public key the server just sent. This new key is symmetric, meaning the same key is used to encrypt and decrypt.
- Server has the private key, and it can decrypt the encryption key the browser sent encrypted.
- Server and Browser both now use the negotiated symmetric key to communicate.
Note that when I say "SSL", it is just to refer to the name of this mechanism. What we are talking about is TLS version 1.2.
The certificate the web server sends is called an x.509 certificate, and anyone can create one. That means you can ensure nobody else can decrypt your data in the wild, but the server can pretend to be some other server. With decent enough effort, someone can trick your browser to connect to an IP address, and the server on this IP address can pretend be some web site that it really isn't. It is not a problem in x.509 certificates because it does what it's supposed to do: provide a secure channel between two endpoints making nobody else can snoop or tamper your data.
How does the browser verify the certificate authenticity
This is where the step 4 above plays its role. If we have a trusted third party to certify that the SSL certificate the server just sent us, that will solve the problem of making sure that the server we intend to connect actually has the accompanying private key. There is a third party, and they are called Certificate Authorities or CAs. Your web browser or the operating system trusts a bunch a certificates, and if the server sends a valid certificate signed by one of the trusted CAs, the browser will happily continue the connection.
Running a Certificate Authority is a risky business. CA first need to generate a private key, and another set of keys that you sign the customers certificates with. If the CA leaks the main private key, or gets any bad reputation issuing certificates that it should not, the browser vendors and operating system vendors are hardly tolerant towards that. DigiNotar and some others learned the lesson hard way. Obtaining a certificate for a domain used to be rigorous process because proving ownership of a domain name used to hard, and with no easy to automate that. Until only a few months back, web site owners had to pay an annual fee to get a certificate signed by one of those CAs.
Encryption is a necessity nowadays with almost everyone using WiFi networks that they can't trust, the ISPs and governments sniffing and even tampering your data. Then there came a new organization, Let's Encrypt, founded by many companies who we already love, offering FREE SSL Certificates. Let's Encrypt is not the first CA to offer free SSL certificates to the masses, but they did a great job making it easier and automatic to get a Domain Validation certificate for free of charge (can contain up to 100 domains, no wildcard domain support). This is a very important achievement for the Internet in many ways.
- You can get a certificate for free.
- The whole process can be automated.
Let's Encrypt CA was not trusted by many browsers at first, and IdenTrust (a trusted CA) cross-signed Let's Encrypt's certificate, and with a chain of signings, all certificates Let's Encrypt issues became widely trusted browsers. The whole process is automatic, but it does not compromise the very thing CAs are supposed to do. In order to get a certificate from Let's Encrypt, you still have to provide that you own the domain name. The most important thing is that Let's Encrypt made it really easy with its Automatic Certificate Management Environment (ACME). There are several implementations in many languages, and an official client that can even modify your web server software. With a few lines and no money spent, you can now instantly make your web site work with HTTPS!
I personally do not use their Python client, but a PHP implementation because I like to the configuration myself. Every 3 months, I have to manually renew the certificates. There are several ACME clients that work perfectly well and you can automate the renewal if you wish.
If you don't already have made your web site work in HTTPS, I strongly recommend you spent a few minutes doing so. There are no more excuses to not have an HTTPS web site anymore.
Let's Encrypt is a collaborative project, but there are emerging competitors to them.
StartSSL: StartSSL is arguably the best competitor in this market. They do offer paid plans, and has a premium model. On the plus side, there appears to be an automatic solution from them as well.
WoSign: This Chinese CA also has a premium model, and there is no automatic tool.
Dedicated IP addresses?
About a few years back, the only information available to the web server was the IP address of the client making the request. The new TLS extension, Server Name Indication fixes the problem by sending the "Host" header before the initial SSL handshake. Almost every browser and HTTP client nowadays support SNI, and web server can figure out the correct certificate to send to the client. If you want to host multiple web sites under the same IP address (most VPSs nowadays come with only one IP address), you have to drop support for browsers that do not support SNI. Most importantly, none of the Internet Explorer versions running on Windows XP supports it, so they are probably your most concern. In my opinion, you have to select a group of users whom you want to server the best, and implicitly force the rest to upgrade their damn browser. Other than that, Android 2 stock browser does not support SNI.
Third party content
In order for an HTTPS web page to work, all assets served in that page must be served via HTTPS. Some of us use CDNs, third party video hosts, traffic analytical software and such services. Google Analytics, Google Adsense, Amazon Cloud Front, KeyCDN, YouTube, and almost every such provider I can think of already come with HTTPS, so they won't be a problem. If you have custom domain names assigned to your CDNs, Amazon CloudFront and KeyCDN users (I hope the others too) are in luck. Amazon itself is now a trusted CA, so you can easily generate a certificate that the same browsers will trust. KeyCDN integrates well with Let's Encrypt.
Shared hosts, at least the cPanel hosts do not support Let's Encrypt yet, and they host multiple domains under the same IP (unless you pay them to get a dedicate IP), and SNI-assisted SSL certificate support is questionable. Their justifications can include the additional CPU usage, and several more. It's 2016 now, with cheaper hardware and automation tools, there are VPS providers that provide a decent box for only $5 a month. This gives you a great control over the software you want to install, and the exact configuration you want. Managing a VPS yourself can be problematic, but a cPanel license costs only $10 a month, so you can actually get the exact same thing with no adverse effect in your budget.
Additional server load
It is true that running HTTPS on the server will require slightly more CPU usage.
On our production frontend machines, SSL/TLS accounts for less than 1% of the CPU load, less than 10 KB of memory per connection and less than 2% of network overhead. Many people believe that SSL/TLS takes a lot of CPU time and we hope the preceding numbers will help to dispel that.
- Adam Langley, Google H/T IsTLSFastYet.com/
Chances are, your web site/application has more things to fix that account for more than 1%, so go fix them. Use HTTPS.
Other than that, you can use Keep-Alive, and many other improvements to overcome the HTTPS handshake overhead.
Edit 1: Thanks to /u/disclosure5 for pointing out that cPanel servers do indeed support HTTPS. I previously had it written as they don't, but I was trying to say it with the Let's Encrypt context.