Search code examples
node.jsssllets-encrypt

Let's encrypt SSL couldn't start by "Error: EACCES: permission denied, open '/etc/letsencrypt/live/domain.net/privkey.pem'"


I tried to use SSL by Node.js but it doesn't work because permission denied.

try {
var TLSoptions = {
    key: fs.readFileSync("/etc/letsencrypt/live/domain.work/privkey.pem"),
    cert: fs.readFileSync("/etc/letsencrypt/live/domain.work/cert.pem")
};

https.createServer(TLSoptions, app).listen(port, host, function() {
   console.log("TLS Website started.")
}); catch(e) {
    console.log(e)
}

=>

{ Error: EACCES: permission denied, open '/etc/letsencrypt/live/domain.work/privkey.pem'
at Object.fs.openSync (fs.js:663:18)
... (Librarys dump)
errno: -13,
code: 'EACCES',
syscall: 'open',
path: '/etc/letsencrypt/live/domain.work/privkey.pem' }

So I tried re-make files of *.pem.

rm -f /etc/letsencrypt/live
rm -f /etc/letsencrypt/archive    
rm -f /etc/letsencrypt/renewal
sudo ./letsencrypt-auto certonly -a standalone -d domain.work

and check file authority.

/etc/letsencrypt/live/domain.work$ ls -lsa
total 12
4 drwxr-xr-x 2 root root 4096 Jan  3 21:56 .
4 drwx------ 3 root root 4096 Jan  3 21:56 ..
0 lrwxrwxrwx 1 root root   37 Jan  3 21:56 cert.pem -> 
../../archive/domain.work/cert1.pem
0 lrwxrwxrwx 1 root root   38 Jan  3 21:56 chain.pem -> 
../../archive/domain.work/chain1.pem
0 lrwxrwxrwx 1 root root   42 Jan  3 21:56 fullchain.pem -> 
../../archive/domain.work/fullchain1.pem
0 lrwxrwxrwx 1 root root   40 Jan  3 21:56 privkey.pem -> 
../../archive/domain.work/privkey1.pem

/etc/letsencrypt/archive/domain.work$ ls -lsa
total 24
4 drwxr-xr-x 2 root root 4096 Jan  3 21:56 .
4 drwx------ 3 root root 4096 Jan  3 21:56 ..
4 -rw-r--r-- 1 root root 1789 Jan  3 21:56 cert1.pem
4 -rw-r--r-- 1 root root 1647 Jan  3 21:56 chain1.pem
4 -rw-r--r-- 1 root root 3436 Jan  3 21:56 fullchain1.pem
4 -rw-r--r-- 1 root root 1708 Jan  3 21:56 privkey1.pem

but It is not resolved and I cannot find any mistakes and problems.
How to resolve this problem?


Solution

  • When you use sudo to issue the certificates, they will be owned by root. Since node is not run as root, and the permissions on the certificate folder do not allow them to be opened by anyone except the owner, your node app cannot see them.

    To understand the solution, let us assume node is running as the user nodeuser

    You can get your user on ubuntu by using : whoami or ps aux | grep node

    Solution #1 (temporary):
    You could switch the owner of the certificates to your node user.
    $ sudo chown nodeuser -R /etc/letsencrypt
    However, this may break any other items that look at the cert, such as Nginx or Apache.
    It will also only last till your next update, which is no more than 90 days. On the other hand, whatever script you have that renews the cert can also set the owner.

    Solution #2 (do not do this):
    Run node as root.
    sudo node index.js
    This will run node as a root user, which means that the terribly insecure surface of node can access everything on your system. Please don't do this.

    Solution #3 (do not do this either):
    Open the certificates to everyone.
    The certificates are stored in /etc/letsencrypt/archive/${domain}/cert1.pem, and are linked to from /etc/letsencrypt/live/${domain}/cert1.pem.

    All folders in both of these paths are +x, meaning that all users on the system can open the folders, with the exception of the "live" and "archive" folders themselves.
    You can make those open as well by changing their permissions.

    $ sudo chmod +x /etc/letsencrypt/live
    $ sudo chmod +x /etc/letsencrypt/archive
    

    This is bad as it allows access from other unexpected sources. Generally opening folders to everyone is a bad idea.

    Solution #4 (do this):
    On the other hand, you can create a limited group, and allow the permissions to only be opened for them.

    # Create group with root and nodeuser as members
    $ sudo addgroup nodecert
    $ sudo adduser nodeuser nodecert
    $ sudo adduser root nodecert
    
    # Make the relevant letsencrypt folders owned by said group.
    $ sudo chgrp -R nodecert /etc/letsencrypt/live
    $ sudo chgrp -R nodecert /etc/letsencrypt/archive
    
    # Allow group to open relevant folders
    $ sudo chmod -R 750 /etc/letsencrypt/live
    $ sudo chmod -R 750 /etc/letsencrypt/archive
    

    That should allow node to access the folders with the certs, while not opening it to anyone else.

    You should then reboot or at least logout and in after these changes.
    (Many changes to permission and groups require a new session, and we had issues with PM2 until reboot.)

    On ec2 instance you can do sudo reboot.

    Should something go wrong and you want to revert to original settings follow this

    # Delete Group
    $ sudo groupdel nodecert
        
    # Reset Permission
    $ sudo chown -R :root /etc/letsencrypt/live
    $ sudo chown -R :root /etc/letsencrypt/archive
        
    # Check Permissions
    $ sudo ll /etc/letsencrypt/