SSL Autorenew failure - NET::ERR_CERT_DATE_INVALID

Setup

DigitalOcean 1-Click Droplet
Node Version: v10.17.0
Ghost-CLI version: 1.12.0
Ghost version: 2.10.1 (at /var/www/ghost)

sudo crontab -l
23 0 * * * "/etc/letsencrypt"/acme.sh --cron --home "/etc/letsencrypt" > /dev/null

ghost setup ssl
SSL has already been set up, skipping
ℹ Setting up SSL [skipped]

Here is the SSL Error when I access my domain:

NET::ERR_CERT_DATE_INVALID

Subject: www.my-domain.com

Issuer: Let's Encrypt Authority X3

Expires on: Oct 27, 2019

Current date: Oct 29, 2019

I recently noticed that my SSL failed for my domain and it appears to be related to an expired domain. Where should I look to determine the root cause of this issue? I’m unfamiliar with SSL generation process

Are you using nginx? If so, try running sudo nginx -s reload. It might be that your certificate updated but nginx wasn’t reloaded

Thanks for the suggestion. I ran that command and received this error:

nginx: [warn] conflicting server name "www.my-domain.com" on 0.0.0.0:443, ignored
nginx: [warn] conflicting server name "www.my-domain.com" on [::]:443, ignored

What file should I search for to correct this issue? Could this stem from generating a lets encrypt certificate independent from the one Ghost creates?

It’s going to be in /etc/nginx/sites-enabled Did you create any custom nginx configurations?

I do not believe I have. I think I left it based on the ghost-cli setup. In that directory I have the following files

xx.xxx.xx.xx.conf  www.my-domain.com-ssl.conf
default            www.my-domain.com.conf

Can you check that the {ip}.conf does not contain your domain name?

server {
    listen 80;
    listen [::]:80;

    server_name xx.xxx.xx.xx;
    root /var/www/ghost/system/nginx-root;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;

    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

It looks like my www.my-domain.com.conf is where the error lies. Here is my conf below. Is it possible to determine which SSL block of code was generated by the Ghost CLI and what might have been generated from the manual run of certbot?

www.my-domain.com.conf

server {

    server_name www.my-domain.com my-domain.com;
    root /var/www/ghost/system/nginx-root;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2369;

        return 301 https://www.my-domain.com$request_uri;

    }

    location ~ /.well-known {
        allow all;
    }
    client_max_body_size 50m;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/my-domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/my-domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = www.my-domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = my-domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;

    server_name www.my-domain.com my-domain.com;
    return 404; # managed by Certbot
}

www.my-domain.com-ssl.conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name www.my-domain.com;
    root /var/www/ghost/system/nginx-root;

    ssl_certificate /etc/letsencrypt/www.my-domain.com/fullchain.cer;
    ssl_certificate_key /etc/letsencrypt/www.my-domain.com/www.my-domain.com.key;
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2369;

    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}
server {
    if ($host = www.my-domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = my-domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;

    server_name www.my-domain.com my-domain.com;
    return 404; # managed by Certbot
}

That block is from certbot and shouldn’t be there. Just FYI, Ghost doesn’t use certbot, it uses acme.sh

Got it so I should remove this code block and also remove the cerbot SSL certificates. Do you know what my acme.sh setup should look like? I don’t see a reference in my conf files

I checked the config again and it looks like you’re going to need to make more changes. I can’t tell you exactly what right now, but the non -ssl file should not have any references to port 443 or ssl.

The /etc/letsencrypt folder is where the acme.sh related stuff goes

Got it. Thank you for your help so far. I removed the certificate generated by certbot and also removed the following code section that looks to be the last of the removal from this conf

listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/my-domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/my-domain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

When I run sudo nginx -s reload again no error messages, which shows progress, but I still received the invalid date certificate error. I checked out the Ghost documentation on running acme.sh commands and ran --list while a ghost-mgr user, not the root which returns:

/etc/letsencrypt/acme.sh: line 1931: /etc/letsencrypt/account.conf: Permission denied
Main_Domain             KeyLength  SAN_Domains  Created                       Renew
www.my-domain.com       ""         no           Tue Jul 30 00:23:07 UTC 2019  Sat Sep 28 00:23:07 UTC 2019

which despite the access error shows that the renew date has long past and the automation didn’t work. Running /etc/letsencrypt/acme.sh --renew-all renders a permission error since I’m not the root. I then try sudo /etc/letsencrypt/acme.sh --renew-all and the command runs, but running --list again shows that nothing has changed with the certificate. Any ideas of what I should try next? Should I have configured this as root instead of the manager user? It looks like there is a difference when running --list between the two users

Yes, since that’s how Ghost runs it ;) I unfortunately can’t help you too much with acme.sh, since I don’t have a ton of experience with it. Your crontab (sudo crontab -l iirc) should show the acme.sh renewal command.

I don’t know if this will help you, but I had problems renewing my certificate as well and thought that I’d include this in case it helps others.

What I found was that I had a very old version of acme.sh installed. You can check the version by doing:

/etc/letsencrypt/acme.sh --version

As of the date of this posting the version is 2.8.4.

Upgrade as follows:

sudo /etc/letsencrypt/acme.sh --home /etc/letsencrypt --upgrade

(if you miss the --home then looks like the upgrade fails.)

And then you can rerun the cron job but add --force as in the latest version of acme.sh it’s unhappy about being run with sudo permissions.

sudo /etc/letsencrypt/acme.sh --cron --home /etc/letsencrypt --force