Over the past decade, there has been a concerted push towards HTTPS across the internet. On many platforms, setting up HTTPS is usually a single click away or even automatic, in no small part thanks to the rise of Let's Encrypt making certificates much more accessible. However, in non-managed environments or in the absence of application support, it usually entails setting up a reverse proxy such as Apache or NGINX to handle HTTPS connections.
Recently I had an application which didn't support HTTPS and a valid certificate and private key, and wanted to find the most direct path to serving the application over HTTPS. This probably called for some sort of reverse proxy, but while Apache, NGINX and other solutions such as OpenBSD relayd are powerful and widely-used, configuring them is often similarly involved. Was there an easier way?
I ended up writing a single-minded CLI tool which takes a certificate and private key, then accepts HTTPS connections and proxies them to a upstream URL:
In fact, the application I was referring to earlier was godoc,
Go's documentation tool. I wanted to share the HTML documentation created by godoc for some code I wrote at work, but
while godoc is able to run as a HTTP server for serving documentation, it does not support HTTPS on its own. Instead,
secure can run as a reverse proxy in front of the godoc http server and terminate TLS connections for it.
Run a godoc web server on port 6060 in the background:
$ godoc -http :6060 &
secure binary permission to bind to port 443 so that we don't have to run it as root:
$ sudo setcap CAP_NET_BIND_SERVICE=+ep $(which secure)
secure with your cert file, key file and the URL of the godoc server (by default,
secure listens for
incoming HTTPS connections on all interfaces and port 443):
$ secure -cert cert.pem -key key.pem http://localhost:6060 2018/08/19 16:28:18 cert-file=cert.pem key-file=key.pem listen-addr=:443 upstream-url=http://localhost:6060
Now visit https://localhost (or your machine's address on the network) to view godoc over HTTPS!
Of course, it's not always a good idea to reinvent the wheel, especially when there are more established and
battle-tested alternatives in the field.
secure is only meant to be an easily-deployed, temporary stand-in for
a more robust reverse proxy setup (for something more ambitious, take a look at Caddy,
which is also built on Go).
At the same time, it may be reassuring to know that Go's network stack is quite capable on its own:
http.ListenAndServeTLS gets an A rating from SSL Labs out of the box,
and with a bit of additional configuration it's possible to get a perfect score.
Go's default TLS settings resemble the Intermediate recommended configuration of the Mozilla guidelines, and can be further configured for greater security. However, a lack of timeouts makes the default configuration vulnerable to certain types of denial of service attacks .
secure is currently using a mostly default configuration. Setting some reasonable defaults soon
should be a priority.)
Nevertheless, these articles were written back in 2016, almost 2 years ago! Surely the story has only gotten better in the meantime 🙂 (although there is still an open issue on GitHub about improving the default HTTP timeouts).
ngrok itself is a useful tool that can open HTTPS tunnels to your local machine over the internet,
which is often what you actually want to do when securing local services with HTTPS and a use case that
only addresses a part of. I use
ngrok myself for things like sharing a work-in-progress version of my blog.