Failed to renew Let's Encrypt Certificate

Hello together,

to the setup:

  • public domain with DynDNS to my network
  • Port forwarding from my Router to my Pi (80, 443)
  • Pi with nginx proxy to redirect the traffic
    - 80 → get blocked (301 Moved Permanently)
    - 443 → get tunneled and spited up to the docker container with Vaultwarden (8080:80, 3012:3012)
  • created HTTPS-Connection with Let’s Encrypt signed certificates

worked for 2 months without problems

Problem:
If I try to renew the certificate after 90 days (certbot renew), I get an error that the http-connection isn’t possible, but necessary to renew the certificate. What I have to change and thanks for helping?

logs:

sudo certbot renew

Challenge failed for domain xxxx.selfhost.eu
http-01 challenge for xxxx.selfhost.eu
Cleaning up challenges
Failed to renew certificate xxxx.selfhost.eu with error: Some challenges have failed.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
All renewals failed. The following certificates could not be renewed:
  /etc/letsencrypt/live/xxxx.selfhost.eu/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: xxxx.selfhost.eu
   Type:   unauthorized
   Detail: 91.15.90.xxxx: Invalid response from
   https://xxxx.selfhost.eu/.well-known/acme-challenge/VVz5QBXzzRHP97QJydGRs0SCDh2JXTxwSx55H35PykM:
   404

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.

and /etc/nginx/sites-enabled/bitwarden.conf

server {
    listen 80;
    listen [::]:80;
    server_name xxxx.selfhost.eu;
    return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name xxxx.selfhost.eu;
  
  ssl_certificate /etc/letsencrypt/live/xxxx.selfhost.eu/fullchain.pem;	#/etc/ssl/certs/nginx-bitwarden.crt;
  ssl_certificate_key /etc/letsencrypt/live/xxxx.selfhost.eu/privkey.pem;	#/etc/ssl/private/nginx-bitwarden.key;

  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  # Allow large attachments
  client_max_body_size 128M;

  location / {
    proxy_pass http://0.0.0.0:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
  
  location /notifications/hub {
    proxy_pass http://0.0.0.0:3012;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
  
  location /notifications/hub/negotiate {
    proxy_pass http://0.0.0.0:8080;
  }
}

Your server is redirecting everything to https instead of returning the requested resource.

Not sure what command you used to initially get the certificate but I would recommend using the webroot authenticator (certbot certonly --webroot -w /var/www/letsencrypt/ -d vault.domain.tld), which lets you update the certificates without certbot taking control of the web server or running it standalone on port 80.

For nginx to serve the webroot, I’m using this snippet

# /etc/nginx/snippets/certbot.conf
location /.well-known/acme-challenge {
	root /var/www/letsencrypt;
	try_files $uri =404;
}

that I include in each site like this:

# /etc/nginx/sites-enabled/vaultwarden.conf
server {
	listen 80;
	listen [::]:80;
	server_name vault.domain.tld;
	location / {
		return 301 https://$host$request_uri;
	}
	include snippets/certbot.conf;
}

(You can check what parameters certbot is using for renewal by viewing the /etc/letsencrypt/renewal/vault.domain.tld.conf file.)

1 Like

Thank you for your response :slight_smile:
I changed the directory of the challenge in the /etc/nginx/snippets/certbot.conf to /etc/letsencrypt and was able to renew my certificate, because this directories is shown in the /etc/letsencrypt/renewal/vault.domain.tld.conf file. After a server restart (sudo systemctl nginx.service) I was able to renew the certificate with this command sudo certbot certonly --webroot -w /etc/letsencrypt/ -d xxxx.selfhost.eu .
Thanks a lot for your help :slight_smile:

# /etc/nginx/snippets/certbot.conf
location /.well-known/acme-challenge {
	root /etc/letsencrypt/;
	try_files $uri =404;
}

I’d recommend changing the directory since there might be sensitive data in this directory which could be served by nginx.

okay moved letsencrypt folder to /var/www and changed dependencies in /etc/nginx/snippets/certbot.conf and /etc/nginx/sites-enabled/vaultwarden.conf. Is that anything I have to do?

Did you really move the folder? Because I’m not sure if certbot would know about the move and it would also not resolve the issue I raised if you have moved the sensitive content inside the folder as well.

Just to be clear, you don’t need to move the folder, only change the location of the webroot (e.g. in the renewal configuration file) and the path inside the certbot.conf snippet . Besides maybe making sure that the webroot path (e.g. /var/www/letsencrypt) exists, there is nothing else you’d have to do as certbot will create the .well-known/acme-challenge/ folder automatically when creating the challenge).

Thanks for the tip, I have undone my changes but I am a bit confused what to do with the sensitive content and where to save it properly. Could you please explain this to me in more detail.
Thanks :slight_smile:

You don’t have to do anything. You just don’t want everything in the /etc/letsencrypt directory to be potentially served by nginx.

Not sure if nginx actually will serve anything from the directory (I might have confused the behavior of the root directive with alias) but I think it’s better to be safe than sorry.