I use certbot v2.9.0 with Apache (httpd) on Rocky Linux 9.
I was getting the dreaded error "renewal config file {} is missing a required file reference", which was totally my fault as I migrated an existing website and config (including LetsEncrypt config) into a new server, and messed up a bit in the process.
I solved the error by noticing that all certificate names referred to dr0.ch-0001, while the renewal process was looking for /etc/letsencrypt/renewal/dr0.ch.conf, so I added a symlink from renewal/dr0.ch-0001.conf to renewal/dr0.ch.conf and now everything works fine.
If I wanted to change all references from dr0.ch-0001 to dr0.ch, where should I look, apart from the /etc/letsencrypt/ and /etc/httpd/conf.d/ directories?
So it appears that certbot considers twice the same SSL cert.
VirtualHost configuration:
*:80 is a NameVirtualHost
default server dr0.ch (/etc/httpd/conf.d/dr0.conf:1)
port 80 namevhost dr0.ch (/etc/httpd/conf.d/dr0.conf:1)
port 80 namevhost jargon.dr0.ch (/etc/httpd/conf.d/jargon.conf:1)
port 80 namevhost photos.dr0.ch (/etc/httpd/conf.d/photos.conf:1)
*:443 is a NameVirtualHost
default server dr0.ch (/etc/httpd/conf.d/dr0-le-ssl.conf:2)
port 443 namevhost dr0.ch (/etc/httpd/conf.d/dr0-le-ssl.conf:2)
port 443 namevhost jargon.dr0.ch (/etc/httpd/conf.d/jargon-le-ssl.conf:2)
port 443 namevhost photos.dr0.ch (/etc/httpd/conf.d/photos-le-ssl.conf:2)
port 443 namevhost dr0.ch (/etc/httpd/conf.d/ssl.conf:40)
I should ditch the last HTTPS vhost which is a duplicate, and move the SSL configuration from ssl.conf to dr0-le-ssl.conf.
# renew_before_expiry = 30 days
version = 2.9.0
archive_dir = /etc/letsencrypt/archive/dr0.ch-0001
cert = /etc/letsencrypt/live/dr0.ch-0001/cert.pem
privkey = /etc/letsencrypt/live/dr0.ch-0001/privkey.pem
chain = /etc/letsencrypt/live/dr0.ch-0001/chain.pem
fullchain = /etc/letsencrypt/live/dr0.ch-0001/fullchain.pem
# Options used in the renewal process
[renewalparams]
account = 848f0d3def0c400d8185a4dd3d8ba99a
authenticator = apache
installer = apache
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsa
I cleaned up the SSL vhost config:
VirtualHost configuration:
*:443 is a NameVirtualHost
default server dr0.ch (/etc/httpd/conf.d/dr0-le-ssl.conf:2)
port 443 namevhost dr0.ch (/etc/httpd/conf.d/dr0-le-ssl.conf:2)
port 443 namevhost jargon.dr0.ch (/etc/httpd/conf.d/jargon-le-ssl.conf:2)
port 443 namevhost photos.dr0.ch (/etc/httpd/conf.d/photos-le-ssl.conf:2)
*:80 is a NameVirtualHost
default server dr0.ch (/etc/httpd/conf.d/dr0.conf:1)
port 80 namevhost dr0.ch (/etc/httpd/conf.d/dr0.conf:1)
port 80 namevhost jargon.dr0.ch (/etc/httpd/conf.d/jargon.conf:1)
port 80 namevhost photos.dr0.ch (/etc/httpd/conf.d/photos.conf:1)
I thought you said that was a symlink to the dr0.ch.conf file.
No, it's the other way around. dr0.ch.conf is a symlink to dr0.ch-0001.conf, because the renewal process looks for the former conf file.
Here's the file /etc/httpd/conf.d/dr0-le-ssl.conf:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName dr0.ch
DocumentRoot "/var/www/html/main"
Include /etc/letsencrypt/options-ssl-apache.conf
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
TraceEnable off
SSLCertificateFile /etc/letsencrypt/live/dr0.ch-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/dr0.ch-0001/privkey.pem
</VirtualHost>
</IfModule>
Note that the command certbot --apache works fine, and I can even renew my SSL cert by hand via that command. It's certbot renew that returns an error "renewal config file {} is missing a required file reference" about which I wrote in my first post.
total 4
drwxr-xr-x. 2 root root 49 Jun 18 12:38 ./
drwxr-xr-x. 7 root root 182 Jun 18 16:27 ../
-rw-r--r--. 1 root root 530 Jun 18 12:17 dr0.ch-0001.conf
lrwxrwxrwx. 1 root root 16 Jun 18 12:38 dr0.ch.conf -> dr0.ch-0001.conf
The best would be to wipe out the whole LetsEncrypt configuration and start over again. I even uninstalled the package before posting here and moved /etc/letsencrypt to another place, then reinstalled the package, but it did not properly recreate the subdirs in /etc/letsencrypt and the certbot client did not work. So I had to restore the directory.
Your renewal is failing because of the HTTP error 400 "Bad Request"
A request to your "home" page gets the same "400" error and shows below. Do you maybe have port 80 forwarded to port 443 in your Apache server?
curl -i http://dr0.ch
HTTP/1.1 400 Bad Request
Server: Apache
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
(...)
<title>400 Bad Request</title>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</p>
Similarly, this should not work. HTTPS should not work on port 80
However, I had that exact same configuration on my previous CentOS Stream 8 server and the renewal worked flawlessly for years. Also, certbot --apache works on this server, so I might theoretically run it every three months to renew the certificate by hand.
No, that is different. That is just your HTTP VirtualHost redirecting to HTTPS. Very normal.
But, HTTP requests to your dr0 domain are not reaching that VirtualHost. Instead, they reach something that requires a cert (HTTPS) and is using the below cert. Do you recognize that?
Do you have a router or some other port forwarding (NAT) happening?
openssl s_client -connect dr0.ch:80 | head
depth=1 C = US, O = Unspecified, OU = ca-5795508124087980945, CN = vps-65ee61ee.vps.ovh.net, emailAddress = root@vps-65ee61ee.vps.ovh.net
verify error:num=19:self-signed certificate in certificate chain
verify return:1
depth=1 C = US, O = Unspecified, OU = ca-5795508124087980945, CN = vps-65ee61ee.vps.ovh.net, emailAddress = root@vps-65ee61ee.vps.ovh.net
verify return:1
depth=0 C = US, O = Unspecified, CN = vps-65ee61ee.vps.ovh.net, emailAddress = root@vps-65ee61ee.vps.ovh.net
verify return:1
My previous post is the main one. I just wanted to add that I don't think that is working like you think it is. It might appear to work but I think it is just relying on the cached authorization. When that Let's Encrypt auth cache expires the certbot --apache will need to get a new auth and it will fail with the same "400" error we see above.
No, I never set up that. I've asked my VPS provider and awaiting for their answer.
Also, there is no NATting, masquerading, or port forwarding set up.
In the meanwhile, thank you very much for your help. I'll post an update as soon as I hear something from my provider. If you have other ideas please don't hesitate to post them.
Found it. The SSL cert that it is served on port 80 is the self-signed cert generated and installed automatically by the httpd package on the machine, and referenced in ssl.conf, as SSLCertificateFile and SSLCertificateKeyFile.
I've tried to remove the HTTP->HTTPS redirection (done via RewriteEngine on the vhost conf file, see my previous post) for one of my subdomains http://jargon.dr0.ch, but it results in an error when accessing the site on HTTP:
Bad Request
Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.
which is consistent with the LetsEncrypt renewal behavior you wrote about.
Therefore there's still something that redirects traffic from port 80 to 443, and I'm trying to understand what it is. There are no other Rewrite statements on jargon.conf, and I haven't set up anything firewall-wise. I have also tried commenting out Strict-Transport-Security "max-age=63072000; includeSubDomains" or changing it to Strict-Transport-Security "max-age=0; includeSubDomains", with no avail. However, it is worth pointing out that LetsEncrypt renewal worked fine with this same exact configuration on my previous VPS (a CentOS Stream 8).
Hmm. Why did that not show up in the DUMP_VHOSTS output shown earlier in post #5? There was no ssl.conf file in that display. You had removed a duplicate that was in ssl.conf and moved its general settings to a different ssl config file.
Can you show a current
I still think it is more likely there is software or a device that is routing incoming port 80 requests to your Apache on port 443.
This isn't unique to Let's Encrypt. Anyone trying to reach you with HTTP will fail. Even your "home" page. They won't reach your Apache to be told to redirect to HTTPS.
You should look at all the things that are different between them. Whatever components and settings "before" Apache is the place to focus on.