Certbot renew on Apache through nginx proxy

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is: blesk.ca

I ran this command: python -c ‘import random; import time; time.sleep(random.random() * 3600)’ && certbot renew

It produced this output: nothing!

My web server is (include version): Apache 2.4.6

The operating system my web server runs on is (include version): CentOS Linux release 7.6.1810

My hosting provider, if applicable, is: none

I can login to a root shell on my machine (yes or no, or I don’t know): yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot): certbot 0.31.0

We have a certificat to renew now that is running on Apache for 3 month now. Executing the following command does nothing : python -c ‘import random; import time; time.sleep(random.random() * 3600)’ && certbot renew

I suspect our nginx server which is in front of our Apache server to be in cause here. This is the configuration of our nginx server for the proxy :

server{
listen 80;
server_name blesk.ca www.blesk.ca;
return 301 https://$host$request_uri;
}

For SSL stuff

server {
ssl on;
ssl_certificate /certs/blesk.ca.pem;
ssl_certificate_key /certs/private-blesk.ca.pem;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA’;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;

    default_type  application/octet-stream;

    listen 443;
    server_name blesk.ca www.blesk.ca;

    root /var/www/blesk.ca;

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

    location / {
            proxy_pass https://10.0.0.19;
            proxy_buffering off;
            proxy_buffers 12 12k;
            proxy_redirect off;

            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;

            client_max_body_size 20m;
    }

}

I’m pretty sure something is missing in the nginx configuration to make the cert renewal to pass.

Regards,

Hi @gmourani

what's the content of the configuration file?

Check

/etc/letsencrypt/renewal

to find your config file. Perhaps you use the wrong command.

Hi @JuergenAuer,

renew_before_expiry = 30 days

version = 0.31.0
archive_dir = /etc/letsencrypt/archive/blesk.ca
cert = /etc/letsencrypt/live/blesk.ca/cert.pem
privkey = /etc/letsencrypt/live/blesk.ca/privkey.pem
chain = /etc/letsencrypt/live/blesk.ca/chain.pem
fullchain = /etc/letsencrypt/live/blesk.ca/fullchain.pem

Options used in the renewal process

[renewalparams]
authenticator = apache
installer = apache
account = 5f708b64e159b9fa55d20f56bd872a8c
server = https://acme-v02.api.letsencrypt.org/directory

If you use apache and if you have a nginx, that redirects http -> https, that can't work.

The apache authenticator creates a http location, but the redirect http -> https - the http location is invisible.

So use the webroot of the Apache https version.

certbot run -a webroot -i apache -w DocumentRootApachePort443 -d blesk.ca -d www.blesk.ca

Then you don't need to change your nginx.

Thanks for the reply, but don’t seem to work, here the output.

[root@cms renewal]# certbot run -a webroot -i apache -w /var/www/blesk -d blesk.ca -d www.blesk.ca
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer apache
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Cert is due for renewal, auto-renewing…
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for blesk.ca
http-01 challenge for www.blesk.ca
Using the webroot path /var/www/blesk for all unmatched domains.
Waiting for verification…
Cleaning up challenges
Failed authorization procedure. blesk.ca (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://blesk.ca/.well-known/acme-challenge/yqWjmmF4naZRi-3vV2fSUPc0sPGspemZGoRHokZttEw [69.70.31.194]: “\r\n404 Not Found\r\n<body bgcolor=“white”>\r\n

404 Not Found

\r\n
”, www.blesk.ca (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://www.blesk.ca/.well-known/acme-challenge/kYe9VdRs-ER-UNOS6MbRACd3ZXbX5Nh4LS47o2J19nY [69.70.31.194]: “\r\n404 Not Found\r\n<body bgcolor=“white”>\r\n

404 Not Found

\r\n

IMPORTANT NOTES:

Then your webroot is wrong.

Create the two subdirectories

yourWebroot/.well-known/acme-challenge

there a file (file name 1234), then try to load that file via

http://blesk.ca/.well-known/acme-challenge/1234

Or you have additional definitions in your nginx.

Oh, what's that?

Checking your domain ( https://check-your-website.server-daten.de/?q=blesk.ca )

Domainname Http-Status redirect Sec. G
http://blesk.ca/
69.70.31.194 301 https://blesk.ca/ 0.264 A
http://www.blesk.ca/
69.70.31.194 301 https://www.blesk.ca/ 0.267 A
https://blesk.ca/
69.70.31.194 301 https://www.blesk.ca/ 1.820 B
https://www.blesk.ca/
69.70.31.194 200 2.513 B
http://blesk.ca/.well-known/acme-challenge/check-your-website-dot-server-daten-dot-de
69.70.31.194 301 https://blesk.ca/.well-known/acme-challenge/check-your-website-dot-server-daten-dot-de 0.270 A
Visible Content: 301 Moved Permanently nginx/1.14.0 (Ubuntu)
http://www.blesk.ca/.well-known/acme-challenge/check-your-website-dot-server-daten-dot-de
69.70.31.194 301 https://www.blesk.ca/.well-known/acme-challenge/check-your-website-dot-server-daten-dot-de 0.260 A
Visible Content: 301 Moved Permanently nginx/1.14.0 (Ubuntu)
https://blesk.ca/.well-known/acme-challenge/check-your-website-dot-server-daten-dot-de 404 1.117 A
Not Found
Visible Content: 404 Not Found nginx/1.14.0 (Ubuntu)
https://www.blesk.ca/.well-known/acme-challenge/check-your-website-dot-server-daten-dot-de 404 1.116 A
Not Found
Visible Content: 404 Not Found nginx/1.14.0 (Ubuntu)

there is no Apache.

nginx answers. Is Certbot able to use the nginx https root? If yes, use that. And where is your certificate installed? Use the correct installer.

It’s nginx which try to respond to the request for -> https://blesk.ca/.well-known/acme-challenge/1234.html

I’ve no certbot defined on nginx, we use it as a proxy server for different servers inside our private domain like Apache, IIS, etc…

Certificate is installed on the Apache server from where I execute the certbot renew command.

Then you must change your nginx configuration, so

https://blesk.ca/.well-known/acme-challenge/1234.html

sends an Apache answer. So Certbot can create a file in the correct subdirectory.

I knew that’s is coming from nginx but i’ve no idea about how to fix it :frowning:

Since your primary hit from Internet is nginx, it would make more sense to run certbot on nginx server IMO. You could even run http only on Apache server and setup the certificate on the Nginx server entry doing the proxying to Apache server. This would avoid you the hassle of moving the generated certificate on the Apache server.

server {
listen *:443 ssl http2;
ssl_certificate /etc/nginx/apache/fullchain.pem;
ssl_certificate_key /etc/nginx/apache/privkey.pem;
(…)
location / {
(…)
proxy_pass http://my_internal_apache_server;
}

This kind of setup is used for web servers that don’t support https, it works.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.