Securing intranet applications with SSL
Getting rid of browser warnings on private network HTTPS connections
We all know how important is HTTPS for securing data flowing between users’ web browsers and the webserver.
With the release of Chrome 56, Google decided to start marking websites not served using the HTTPS protocol as Insecure (source), so it is becoming even more important, if not critical, to use HTTPS for all web applications.
This is obviously relevant for web applications and websites in general, which are available to the public. In such situations, the typical solution is to purchase an SSL certificate from a certification authority (such as RapidSSL or GoDaddy) and enable it within the webserver. This article is not about this.
What we’re going to talk about today is the security of Intranet web applications, such as a websites which are not publicly available, but somehow available to specific people having access to private networks.
Why is it important to secure intranet applications too?
Somebody might think that, since an application is not publicly available, it is not important to secure it with SSL. This is not true, and here’s why.
Think about a document storage web application that is running in the local area network (LAN) of your company. That application of course may contain many documents of different nature, such as customers’ and suppliers’ invoices and employees contracts and payment receipts.
While some of this documents might be visible to all the users of such web application, many others have to be visible to specific users only.
Let’s say that you implement a very secure ACL to ensure this security layer on your application and avoid unauthorized access to your sensitive data.
If you don’t serve your project using the HTTPS protocol, than all your documents are traveling in the cables of your LAN unencrypted, and anybody connected to the same network can easily scan your network and read those documents. Plus, a malicious user could use the same technique to sniff user passwords and easily access your secure web app with other peoples’ credentials (don’t you believe that? Check this tutorial).
That said, I hope you are all convinced now that SSL is important for every web application, even if it’s not public.
How to secure an intranet application
There are a few options to secure private web applications.
- The dumbest option is to generate a self signed certificate. That does not solve the security problem though (read this to understand why).
- Buy a standard certificate. This is perfectly acceptable but requires spending some amount of money every year.
- Generate a certificate using Letsencrypt
If you haven’t heard about Letsencrypt before, go have a look at their website to learn more. In one sentence, it is an organization that aims at making the web more secure and gives you free SSL certificates for personal or professional use.
This is in my opinion the perfect solution for intranet applications (which tipically have budget constraints).
Generating SSL certificates with letsencrypt
Letsencrypt uses the ACME protocol to release SSL certificates in an automated manner.
That means you need an ACME client to get an SSL certificate. The official client is called certbot, it’s free and open source and it is easily installable in many UNIX-based operating systems. We’re not going to cover the installation of certbot, though, because it is out of scope. You can find easy tutorials for your operating system on the officiale page.
There are a few different ways to get a new certificate using certbot (such as apache, nginx, webroot, and so on. Read them here) but all of them have a very important common step to be performed which is domain ownership verification. This step is required by the certification authority to ensure that you are the owner, or at least you are allowed to manage, the DNS records for the internet domain you are requiring the certificate for. Skipping this step would mean that anybody could request a certificate for google.com or paypal.com and that of course would be a giant security problem.
How does Letsencrypt check domain ownership?
There are basically 2 ways:
- HTTP challenge: an HTTP request is sent to the domain name you requested the domain for. The server must respond to a specific endpoint with a specific content in order for the domain ownership to be verified.
- DNS challenge: letsencrypt servers will search on the DNS records of the requested domain for a specific TXT record, with a specific value.
HTTP challenge is the most common and the easiest, because certbot (and other ACME clients) can do that for you automatically. Unluckily, it requires that the domain name resolves to a public IP address which is freely reachable on the internet. But, remember, our domain is in the intranet and so this approach simply would not work in our scenario. That means we need to choose the DNS challenge option.
Generate a certificate using the DNS challenge
To do that, we need to use the manual strategy of certbot, by running a command similar to the following:
1 |
certbot -d private.mydomain.com --manual --preferred-challenges dns certonly |
Of course adjust private.mydomain.com with your domain.
This command starts an interactive wizard:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Saving debug log to /var/log/letsencrypt/letsencrypt.log Obtaining a new certificate Performing the following challenges: dns-01 challenge for private.mydomain.com ------------------------------------------------------------------ NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged? ------------------------------------------------------------------ (Y)es/(N)o: Y ------------------------------------------------------------------ Please deploy a DNS TXT record under the name _acme-challenge.private.mydomain.com with the following value: LngHg_3lhXDJ_m3ArGTgtalz50uVCjXW5-zFVCulK8I Once this is deployed, ------------------------------------------------------------------ Press Enter to Continue |
At this point, as clearly requested by the script, you need to create a new TXT record in your DNS administration panel for _acme-challenge.private.mydomain.com with value LngHg_3lhXDJ_m3ArGTgtalz50uVCjXW5-zFVCulK8I
Once done, check that the DNS record propagated successfully (you can use this website to do that) than press enter to continue executing the script.
If all went well, you should see a success message:
1 2 3 4 5 6 7 |
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/private.mydomain.com/fullchain.pem. Your cert will expire on 2017-05-16. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le |
Good, our certificates are ready! You can find everything you need under the folder: /etc/letsencrypt/live/mydomain.com/ (of course adjust the path to meet your domain name). In that folder you’ll find 4 files:
- cert.pem: the actual certificate
- chain.pem: the certificate of the certification authority
- fullchain.pem: basically the merge of the above 2 files
- privkey.pem: your private key (never share this file with anybody)
Now you only have to tell your webserver to use the HTTPS protocol and where to get the certificate files. Check the official documentation for Nginx and apache to get started.
Recap
In this article we discussed about the risks of having a plain HTTP web application hosted inside our company’s private network and the need of an SSL certificate to make traffic flow securely inside our ethernet wires.
We then learned how to generate a free SSL certificate using Letsencrypt even if our webservers are not public.