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>
ServerName subdomain.foo.com
Redirect permanent / https://subdomain.foo.com/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@foo.com
ServerName subdomain.foo.com
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
</Directory>
ErrorLog "/logs/subdomain.foo.com-error_log"
CustomLog "/logs/subdomain.foo.com-access_log" combined
SSLEngine on
SSLProtocol TLSv1.2
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile "/keys/rootCA.pem"
SSLCARevocationFile "/keys/rootCA.crl"
SSLCARevocationCheck chain
SSLCertificateFile "/etc/letsencrypt/live/subdomain.foo.com/fullchain.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/subdomain.foo.com/privkey.pem"
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"
</VirtualHost>
Here's my renewal script for Let's Encrypt:
# renew_before_expiry = 30 days
version = 2.1.0
archive_dir = /etc/letsencrypt/web/archive/subdomain.foo.com
cert = /etc/letsencrypt/web/live/subdomain.foo.com/cert.pem
privkey = /etc/letsencrypt/web/live/subdomain.foo.com/privkey.pem
chain = /etc/letsencrypt/web/live/subdomain.foo.com/chain.pem
fullchain = /etc/letsencrypt/web/live/subdomain.foo.com/fullchain.pem
# Options used in the renewal process
[renewalparams]
account = MYACCOUNTNUMBER
rsa_key_size = 4096
config_dir = /etc/letsencrypt/web
authenticator = webroot
webroot_path = /web/letsencrypt,
server = https://acme-v02.api.letsencrypt.org/directory
post_hook = /certbot-web-hook
key_type = rsa
[[webroot_map]]
subdomain.foo.com = /web/letsencrypt