Monthly Archives: February 2017

https and express: brought to you by the EFF

Thanks to the helpful folks at Lets Encrypt and the EFF, it is possible for a nobody to at least enable https on their site for free! You could use a self-signed certificate but if you want to access, for instance, Slack’s webhooks, you’ll need a recognized CA behind your certs.

As of this writing, you can find the instructions for installing the Lets Encrypt certificate engine at https://certbot.eff.org/#ubuntuother-other for generic installs of Ubuntu, with even easier installers available if you peruse the drop down menu at the top of the page. Following these installation instructions:

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

Downloads the certbot command line utility that will install dependecies and grab certs for you, all in one tool. From there, you can start to follow along at https://lucaschmid.net/anotherblog/letsencrypt-express (replacing letsencrypt-auto with certbot-auto) where the next step is to, for example:

./certbot-auto certonly --standalone --email not_an_email_address@gmail.com -d ryan.fish

which sets up certbot and pulls in cert files for the domain ryan.fish , using the contact email given. It will require interaction unless you add the auto TOS flag to the command.

Note that you will have to have done some prep before this point; you’ll need to have set up your DNS to point at \something/ that will at do something with the connection. Note: a router that doesn’t have port forwarding for port 443 will not reply, causing certbot to error out. It doesn’t have to be a full webpage, but it seems like it at least needs to be a machine that will close the connection.

I found that letsencrypt made uber conservative permissions on the key files, so lets relax that a little:
/etc/letsencrypt/ is the root for the install, I found that archive and live both had restrictive permissions that prevented the user from even reading the contents unless they were root. However, upon relaxing the permissions for the folders, the private key files inside had read permissions for group and world! No Bueno, fix that asap.

apparently ports below 1024 need root access to open, but you can allow node to selectively have access to restricted ports with the setcap command

setcap 'cap_net_bind_service=+ep' /path/to/nodejs

This sets the kernel “capacities” for the node executable, to have permission to bind services to restricted ports, and that it is effective upon running the executable (other options are that it can be inherited if a process with permission launches the executable).

to the base boilerplate generated with express myapp, I added:

var fs = require('fs');
var https = require('https');
var http = require('http');

to the requires section. fs implements filesystem access, https implements TLS, and http will let us redirect unwitting users to https. Adding the following after var app = express();

var http_redirect = express();
http_redirect.use(function(req, res, next) {
var httpsUrl = 'https://' + req.get('host') + req.originalUrl;
res.redirect(301, httpsUrl);
});
http.createServer(http_redirect).listen(80);

var server = https.createServer(
{
key: fs.readFileSync('./tls/privkey.pem'),
cert: fs.readFileSync('./tls/fullchain.pem')
},
app
);
server.listen(443);

finishes setting up the http redirect to https, and the https server for the app.