Allow Certificate Renewals When Using Client Certificate Authentication

Using Apache virtual hosts, I have client certificate authentication setup for a number of my domains that also use Let's Encrypt certificates. This all works great, but certbot is not able to renew the certificates because there is no client certificate presented.

I have a virtual host on port 80 that permanently redirects all requests to the virtual host on 443, but I'm not sure how to allow certbot to renew/issue certificates.

Here's an example of my apache config:

<VirtualHost *:80>
    Redirect permanent /

<VirtualHost *:443>
        Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
        Header always set X-XSS-Protection "1; mode=block"
        Header always set X-Content-Type-Options "nosniff"
        Header always set X-Frame-Options "SAMEORIGIN"
        Header always set Referrer-Policy "no-referrer-when-downgrade"
        Header always set X-Permitted-Cross-Domain-Policies "none"

        SSLProxyEngine on
        ProxyVia on
        ProxyAddHeaders on
        ProxyPreserveHost on

        SecRuleEngine On

        RewriteEngine On

        RewriteRule /.well-known/acme-challenge/ - [R,L]
        Alias /.well-known/acme-challenge /web/letsencrypt/.well-known/acme-challenge

        <Directory /web/letsencrypt>
               Require all granted

        ErrorLog "/logs/"
        CustomLog "/logs/" combined

        SSLEngine on
        SSLProtocol TLSv1.2
        SSLHonorCipherOrder on

        SSLVerifyClient require
        SSLVerifyDepth 1
        SSLCACertificateFile "/keys/rootCA.pem"
        SSLCARevocationFile "/keys/rootCA.crl"
        SSLCARevocationCheck chain

        SSLCertificateFile "/etc/letsencrypt/live/"
        SSLCertificateKeyFile "/etc/letsencrypt/live/"

        UseCanonicalName on
        ProxyPreserveHost on
        CacheStaleOnError on
        RemoteIPHeader X-Forwarded-For
        ProxyRequests Off

        AllowEncodedSlashes NoDecode
        ProxyPass /.well-known !
        ProxyPass / http://myproxy:18495/ nocanon
        ProxyPassReverse / http://myproxy:18495/

        BrowserMatch ".*MSIE.*" \
        nokeepalive ssl-unclean-shutdown \
        downgrade-1.0 force-response-1.0

        CustomLog "/logs/ssl_request_log" \
        "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

Here's my renewal script for Let's Encrypt:

# renew_before_expiry = 30 days
version = 2.1.0
archive_dir = /etc/letsencrypt/web/archive/
cert = /etc/letsencrypt/web/live/
privkey = /etc/letsencrypt/web/live/
chain = /etc/letsencrypt/web/live/
fullchain = /etc/letsencrypt/web/live/

# Options used in the renewal process
rsa_key_size = 4096
config_dir = /etc/letsencrypt/web
authenticator = webroot
webroot_path = /web/letsencrypt,
server =
post_hook = /certbot-web-hook
key_type = rsa

[[webroot_map]] = /web/letsencrypt

My recommendation: handle all the /.well-known/acme-challeng/ stuff in the HTTP (port 80) virtualhost and never let it redirect to HTTPS to begin with.


I have tried that in a few different way but none seem to work. Here's an example, replacing the

Redirect permanent /


RedirectMatch permanent ^/(?!\.well-known/acme-challenge/.*)(.*)$1

1 Like

If you only exempt the acme-challenge path from the redirect, then you're lacking more directives in your HTTP vhost. E.g., you're using the webroot authenticator, but the HTTP vhost doesn't have any documentroot.


OK, fair enough. Can you please provide the solution so I can try it? Bearing in mind that this all worked prior to setting up client certificate authentication. That's the only thing blocking it.

Also, this is a docker setup for Apache httpd and I am volume mapping for LE via

- /etc/letsencrypt/web:/etc/letsencrypt:ro
- /web/letsencrypt:/web/letsencrypt:rw

Probably just move all the acme-challenge related stuff like that Alias to the HTTP vhost?


Yes! Moving the acme stuff to the port 80 vhost does allow it to work. Thank you.

This is what my vhost on port 80 looks like now:

<VirtualHost *:80>

        Alias /.well-known/acme-challenge /web/letsencrypt/.well-known/acme-challenge

        <Directory /web/letsencrypt>
                Require all granted

        RedirectMatch permanent ^/(?!\.well-known/acme-challenge/.*)(.*)$1

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