Search code examples
node.jslinuxsslrootlets-encrypt

What is the most secure way to use Let's Encrypt certificates with Node.js?


I am developing a secure web server on node.js and I am using Let's Encrypt certificates with the https module. I want it to run on Ubuntu/Debian machines. By default, the certificate and private key are stored in:

/etc/letsencrypt/live/domain.name.example/fullchain.pem
/etc/letsencrypt/live/domain.name.example/privkey.pem

These files permissions only allow the root user to read them, so the problem is that the node.js server can't load them normally using:

const cert = fs.readFileSync("/etc/letsencrypt/live/domain.name.example/fullchain.pem");
const privKey = fs.readFileSync("/etc/letsencrypt/live/domain.name.example/privkey.pem");

(Which will throw a permission error)

The only solutions to this I know are:

  1. running the node server as root so it has the permission to the files (not recommended for node).
  2. Copy the files with sudo cp to a local directory and apply permissions with sudo chmod +r so they can be accessed by the server after every certificate renewal (let's encrypt does not recommend to copy these files, this is my current solution though).
  3. running node as root, load the certificate and private key, and then change the uid to a non-root user with process.setgid() and process.setuid(), which will drop root privileges.

My question is if there is a better solution to achieve this, or maybe one of these methods are just fine?


Solution

  • As per O. Jones comment, I solved this problem by using nginx as a reverse-proxy for my nodejs server. This way nginx handles the SSL without permission issues, and nodejs only needs to run an http server.