简体   繁体   中英

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?

Use setgid .

Set the group ownership of the directory to the group you're using to run nodejs. If your user and group are itay:staff for example, say this

chgrp -R staff /etc/letsencrypt/live/domain.name.example

Then set the setgid bit of the directory's permissions like so.

chmod 02755 staff /etc/letsencrypt/live/domain.name.example

Thereafter, any files written to that directory will be owned by that group, staff in this example. So, your nodejs program will be able to read them without any further ado.

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.

The problem was solved by following the second recommendation here by letsencrypt documentation (Quote B) that doesn't require me to create any script to move or copy the files whenever the certificate auto renews (I installed mine with the --apache plug-in, as a side note, it you have your redirect from http to https inside your virtual host, when you first run certbot use --no-redirect to avoid an error being reported during the installation of the certificates).

Despite that I found unnecessary to move or copy the pem files. In the certbot documentation here , I don't find that letsencrypt doesn't recommend to move the certificates, in their documentation as of now they even tell you how to do it right:

Quote A:

If you would like the live certificate files whose symlink location Certbot updates on each run to reside in a different location, first move them to that location, then specify the full path of each of the four files in the renewal configuration file. Since the symlinks are relative links, you must follow this with an invocation of certbot update_symlinks.

For example, say that a certificate's renewal configuration file previously contained the following directives:

archive_dir = /etc/letsencrypt/archive/example.com
cert = /etc/letsencrypt/live/example.com/cert.pem
privkey = /etc/letsencrypt/live/example.com/privkey.pem
chain = /etc/letsencrypt/live/example.com/chain.pem
fullchain = /etc/letsencrypt/live/example.com/fullchain.pem

The following commands could be used to specify where these files are located:

mv /etc/letsencrypt/archive/example.com /home/user/me/certbot/example_archive
sed -i 's,/etc/letsencrypt/archive/example.com,/home/user/me/certbot/example_archive,' /etc/letsencrypt/renewal/example.com.conf
mv /etc/letsencrypt/live/example.com/*.pem /home/user/me/certbot/
sed -i 's,/etc/letsencrypt/live/example.com,/home/user/me/certbot,g' /etc/letsencrypt/renewal/example.com.conf
certbot update_symlinks

Quote B (my solution, just because it is the simples -KISS principle)

Regarding permissions and group ownerships they say the following:

For historical reasons, the containing directories are created with permissions of 0700 meaning that certificates are accessible only to servers that run as the root user. If you will never downgrade to an older version of Certbot, then you can safely fix this using chmod 0755 /etc/letsencrypt/{live,archive}.

For servers that drop root privileges before attempting to read the private key file, you will also need to use chgrp and chmod 0640 to allow the server to read /etc/letsencrypt/live/$domain/privkey.pem.

Which is VERY interesting, they are 700 only for historical reasons. What they don't clarify is that the /etc/letsencrypt/live and keys folders are 700, and in 20.04 Ubuntu you can't even see that the folder exists unless you become root, yes sudo doesn't work, folder not found error. the -d or domain folders are 755 (/etc/letsencrypt/live.domain.com) and the symlinks themselves to the .pem files are 777.

Letsencrypt documentation says:

the pem files in the directory mentioned above, are only symlinks: /etc/letsencrypt/archive and /etc/letsencrypt/keys contain all previous keys and certificates, while /etc/letsencrypt/live symlinks to the latest version

The keys themselves have permissions: 600 In my Ubuntu 20.04 system with cerbot --apache certificate and installation I find that the keys folder has 000x_key-certbot.pem files with permissions 600, and the the archive directory has the actual cert1.pem, chain1.pem, fullchain1.pem and privkey1.pem files with permissions: 644, 644, 644 and 600 respectively.

The /etc/letsencrypt/archive/domain.com# folder has permissions 755 and /etc/letsencrypt/archive folder has permissions 700. So access is blocked by hiding the directory and and blocking the keys themselves.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM