Most of the time running a dev server on HTTP port 3000 (or whatever) is sufficient, but there are times when you sometimes need HTTPS:
- To authenticate against third party access keys (like google authentication)
- To communicate with a remote API (CORS protection)
There are several reverse proxy services to choose from them, and most of them (like NGROK) have a free tier, but there's one huge reason that I no longer utilize those services for development: it's sloooooooooooow!
When you establish a point-to-point tunnel between your local workstation, your packets have to make a complete round trip from your machine, to the exit node, and then back to your local machine. And if you have a complex app your full-page reloads can be dog slow. So what's the alternative when you need HTTPS?
Stunnel is a versatile proxy server tool that provides secure data communication by encrypting traffic between the client and the server. Primarily, it is used to add SSL (Secure Sockets Layer) and TLS (Transport Layer Security) encryption capabilities to existing clients and servers without any changes to the programs' code. This makes it an invaluable tool for enhancing security in network communications. Stunnel works by creating an SSL/TLS tunnel through which data can be transmitted securely, thus protecting the data from eavesdropping or tampering. It's commonly used to secure non-SSL aware daemons and protocols like POP3, SMTP, and IMAP, and for providing secure encryption to services that may not inherently support it, making it a popular choice for improving security in a variety of networked applications.
The great thing is you can use it locally one your dev machine, so your packets never leave your NIC! Are you ready to take the Stunnel plunge and greatly improve your DX?! Then let's go!
#1 Download and Install Stunnel
Stunnel is available for Windows, Max and Linux. You can follow this link to the downloads page for Windows, but for Mac you can install it via Homebrew:
brew install stunnel. If you don't have Homebrew installed, you're missing out. It's basically like
npm but for MacOS. Here's a script you can use to download and install Homebrew:
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"bash -c
#2 Download and Install Certbot
You're going to need an SSL certificate for Stunnel. Now you can certainly use the snakeoil cert that comes with Stunnel, but you'll get the warning when you try to connect and some things will not work with an invalid certificate. Luckily, setting up Certbot is free and easy! Follow this link to download Certbot for Windows. For Linux, you can install via snap:
snap install certbot. And for Mac, it's:
brew install certbot.
#3 Edit Your Hosts File
Next, you're going to need a domain name that points to localhost. If you have a local DNS server, then you should create a new hostname that points to 127.0.0.1. Otherwise you can simply add an entry to your local
hosts file. For Mac, it's at
/private/etc/hosts, for Linux:
/etc/hosts and for Windows it's at
C:\Windows\System32\drivers\etc\hosts. You'll need elevated permissions to edit the file. Also, please bear in mind that some virus or malware apps will remove your entry from the hosts file, so be sure to add an exception if necessary.
Add the following line to your hosts file and save it:
On Windows, you can not directly save the hosts file in place, you'll have to save it as a copy
host.txt and then change the name back to
hosts and then copy it with elevated permissions back into the directory. It's a huge pain, but protecting your hosts file is actually very important to prevent man-in-the-middle attacks.
#4 Request your SSL Certificate
Now it's time to pull a certificate from Certbot. Run the following command:
certbot certonly -d some.host.com
Make sure you have port 80 and 443 on your router NAT'ed to your local machine. You only need to keep these ports open when requesting the certificate, and then you can close them.
You should get a readout that your certificate has been installed successfully. On Windows, your certificate will be at
C:\Certbot\live and in Linux/Mac, it should be at
/etc/letsencrypt/live. You can just leave those files there. We're going to need to reference these files in our Stunnel conf.
#5 Setup and Run Stunnel
On Windows you can start by opening the start menu and typing "edit stunnel" and you should get an autocomplete suggestion for "Edit stunnel.conf". It will prompt you for elevated permissions, accept. On Mac, the file is at
/usr/local/etc/stunnel. On Linux, it's usually at:
/etc/stunnel/stunnel.conf. Delete all the contents of the file (or peruse the sample configs to see what can be done with Stunnel). Then add the following config block:
[contextname] accept = 443 connect = 3000 cert = /etc/letsencrypt/live/some.host.com/fullchain.pem key = /etc/letsencrypt/live/some.host.com/privkey.pem
Ok, let's take this line-by-line. The context name in the square brackets is just an identifier, you can call this what ever you like, but it must be unique from other confs. The accept directive is the port Stunnel will listen on for SSL connections, we want 443 standard SSL port. The connect parameter is the tunnel port that Stunnel will forward the packets to. I have port 3000 in this example. Next are the absolute paths to your FULL CHAIN cert and key files that you got from Certbot.
That's it! Now you can simply start Stunnel on Mac and Linux by typing
stunnel from the terminal, or on Windows you can search the start menu for "Stunnel GUI start." Then you can open up
https://some.host.com in your favorite web browser and you should be good to go!
Thank you for taking the time to read my article and I hope you found it useful (or at the very least, mildly entertaining). For more great information about web dev, systems administration and cloud computing, please read the Designly Blog. Also, please leave your comments! I love to hear thoughts from my readers.
If you want to support me, please follow me on Spotify!
Looking for a web developer? I'm available for hire! To inquire, please fill out a contact form.