Score:0

Nginx emergency: cannot load certificate "/etc/letsencrypt/live/mail.example.com/fullchain.pem". How to fix this Nginx error?

mx flag

I am running a LEMP email/web server with Ubuntu 20.04. My Nginx user is www-data. I also have roundcube installed in /var/www/roundcube. In my Nginx logs, I am getting the following error:

2023/07/01 00:00:18 [emerg] 337875#337875: cannot load certificate "/etc/letsencrypt/live/mail.example.com/fullchain.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/mail.example.com/fullchain.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib)

My mail.example.com.conf virtual host file looks like this:

server {
    # Restrict access to LAN / Work / Home IP's
    allow lan.ip.address.0/24; # LAN IP Address
    allow xxx.xx.xxx.xxx/32; # Home IP address
    allow xxx.xxx.xxx.xxx/32; # Work IP Address
    deny all;
    error_page 403 =444;

    # Begin Server Directives
    server_name mail.example.com;
    root /var/www/roundcube/;
    index index.php index.html index.htm;

    # Logs
    error_log /var/log/nginx/mail.example.com.error.log;
    access_log /var/log/nginx/mail.example.com.access.log;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        # Pass FastCGI to PHP7.4 with included settings in the snippet
        include snippets/fastcgi-php.conf;
    }

    location ~ /.well-known/acme-challenge {
        allow all;
    }
    location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
        deny all;
    }
    location ~ ^/(bin|SQL)/ {
        deny all;
    }
    # A long browser cache lifetime can speed up repeat visits to your page
    location ~ \.(jpg|jpeg|gif|png|webp|svg|woff|woff2|ttf|css|js|ico|xml)$ {
        access_log off;
        log_not_found off;
        expires 360d;
    }

    listen *:443 ssl;
    http2 on;
    ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    # Perfect Forward Secrecy Diffie-Hellman 4098 parameters
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    #ssl_dhparam /etc/ssl/private/dhparams4096.pem; # Managed by admin

    add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot

    ssl_trusted_certificate /etc/letsencrypt/live/mail.example.com/chain.pem; # managed by Certbot
    ssl_stapling on; # managed by Certbot
    ssl_stapling_verify on; # managed by Certbot

}
server {
    if ($host = mail.example.com) {
        return 301 https://$host$request_uri;
    }
    # managed by Certbot

    # Restrict access to LAN / Work / Home IP's
    allow lan.ip.address.0/24; # LAN IP Address
    allow xxx.xx.xxx.xxx/32; # Home IP address
    allow xxx.xxx.xxx.xxx/32; # Work IP Address
    deny all;
    error_page 403 =444;

    # Begin Server Directives
    listen *:80;
    server_name mail.example.com;
    root /var/www/roundcube/;
    index index.php index.html index.htm;

    error_log /var/log/nginx/mail.example.com.error.log;
    access_log /var/log/nginx/mail.example.com.error.log;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        #try_files $uri =404;
        # Pass FastCGI to PHP7.4 with included settings in the snippet
        include snippets/fastcgi-php.conf;
    }

    location ~ /.well-known/acme-challenge {
        allow all;
    }
    location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
        deny all;
    }
    location ~ ^/(bin|SQL)/ {
        deny all;
    }
    # LINUXBABE + Extra Extensions
    # A long browser cache lifetime can speed up repeat visits to your page
    location ~ \.(txt|flv|pdf|avi|mov|ppt|wmv|mp3|ogg|webm|aac|jpg|ogg|ogv|svgz|eot|otf|mp4|rss|atom|zip|tgz|gz|rar|bz2|doc|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|jpeg|gif|png|swf|jpeg|webp|svg|woff|woff2|ttf|css|js|ico|xml|otf|woff|woff2)$ {
        access_log off;
        log_not_found off;
        expires 1y;
    }
}

The output of ls -la /etc/letsencrypt/ is:

drwxr-xr-x   9 root root  4096 Jul  1 14:49 .
drwxr-xr-x 156 root root 12288 Jul  1 20:15 ..
drwxr-xr-x   4 root root  4096 Dec 31 23:12 accounts
drwxr-x---  10 root root  4096 Jan 10 22:58 archive
-rw-r--r--   1 root root  1435 Dec  8  2021 cli.ini
-rw-r--r--   1 root root   121 Dec  8  2021 cli.nin.orig
drwxr-xr-x   2 root root 28672 May 29 12:01 csr
drwx------   2 root root 24576 May 29 12:01 keys
drwxr-x---  10 root root  4096 Jan 10 22:58 live
-rw-r--r--   1 root root   741 Jun 22  2021 options-ssl-nginx.conf
drwxr-xr-x   2 root root  4096 May 29 12:01 renewal
drwxr-xr-x   5 root root  4096 Dec 31 23:12 renewal-hooks
-rw-r--r--   1 root root   424 Jun 22  2021 ssl-dhparams.pem
-rw-r--r--   1 root root    64 Jun 22  2021 .updated-options-ssl-nginx-conf-digest.txt
-rw-r--r--   1 root root    64 Jun 22  2021 .updated-ssl-dhparams-pem-digest.txt

The output of ls -la /etc/letsencrypt/live is:

total 44
drwxr-x--- 10 root root 4096 Jan 10 22:58 .
drwxr-xr-x  9 root root 4096 Jul  1 14:49 ..
drwxr-xr-x  2 root root 4096 May 29 12:00 mail.example.com
  1. What exactly is does this error mean?
  2. What is causing this error?
  3. How can I fix this error?
Score:0
br flag

To answer your questions:

  1. The error message is pretty straight forward, look at this snippet inside:

    error:0200100D:system library:fopen:Permission denied:

    So the error message means the sytem cannot open the file that you specified in your configuratoin as your www-user does not have the proper permissions to do so.

  2. With Nginx it is important to note that it always requires read and execute rights on the entire path of of any file it needs to access. As you already provided an output of yome folder permissions, we can see the /etc/letsencrypt/live folder lacks the read and execute permissions for the www-user:

    drwxr-x--- 10 root root 4096 Jan 10 22:58 live

    It's also possible the /etc directory also doesn't carry the proper permissions.

  3. To fix the error you can either assign the proper permissions to the paths, i.e. chmod o+rx /etc/letsencrypt/live or you can move the certificate somewhere the www-user is already allowed to access, like somewhere close (but not inside) your webroot folder. it's also a common practice to assign file ownership (or group ownership) to the paths and files of sensitive that Nginx needs to access, as this keeps tighter permissions on the files and doesn't allow every user on the system to read them.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.