Where are all references to my domain name?

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?

That is not a good idea. Manually modifying the Certbot folders can easily lead to all kinds of unpredictable bad results.

The best way forward is to have a working Certbot cert profile and have that used by Apache.

Let's start by you showing us results of these two commands

sudo certbot certificates
sudo httpd -t -D DUMP_VHOSTS
7 Likes

Here they are:

Found the following certs:
  Certificate Name: dr0.ch-0001
    Serial Number: 3d7fa6120889a4396dd63ff814e5986e8a6
    Key Type: ECDSA
    Domains: dr0.ch jargon.dr0.ch photos.dr0.ch
    Expiry Date: 2024-09-16 09:17:52+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/dr0.ch-0001/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/dr0.ch-0001/privkey.pem
  Certificate Name: dr0.ch
    Serial Number: 3d7fa6120889a4396dd63ff814e5986e8a6
    Key Type: ECDSA
    Domains: dr0.ch jargon.dr0.ch photos.dr0.ch
    Expiry Date: 2024-09-16 09:17:52+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/dr0.ch-0001/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/dr0.ch-0001/privkey.pem

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.

That's a good start. Especially the second part :slight_smile:

Then we need to sort out your Certbot cert profiles and folders

Please show the contents of each .conf file in the /etc/letsencrypt/renewal folder

4 Likes

There is only one file, dr0.ch-0001.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. Can you show this:

sudo ls -l /etc/letsencrypt/renewal

Also show contents of this file.

4 Likes

This is weird. Certbot counted the same certificate twice (same serial number, same paths)

4 Likes

Yeah, they symlinked one from the other. Probably because of that

tempted to have them wipe it all and start over. But, possibly a simpler fix is possible.

5 Likes

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.

Yes, I understand. I am trying to sort out how to fix the Certbot renewal profiles while still having your Apache work properly.

3 Likes

Here's the content of /etc/letsencrypt/renewal:

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.

Alright, so what does this do

sudo certbot renew --dry-run --cert-name dr0.ch-0001.conf
3 Likes

Here's the output of certbot renew --dry-run --cert-name dr0.ch-0001 (without the .conf):

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/dr0.ch-0001.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for dr0.ch and 2 more domains

Certbot failed to authenticate some domains (authenticator: apache). The Certificate Authority reported these problems:
  Domain: dr0.ch
  Type:   unauthorized
  Detail: 51.195.91.24: Invalid response from http://dr0.ch/.well-known/acme-challenge/MTNBTQWKkfIX9pyumqU3d9c-e_jv-1wkn5ZFnXOtUvc: 400

  Domain: jargon.dr0.ch
  Type:   unauthorized
  Detail: 51.195.91.24: Invalid response from http://jargon.dr0.ch/.well-known/acme-challenge/52quzHWZR3ldQWbxjwi5RODPVbEY3QmcYr1w38nPDpM: 400

  Domain: photos.dr0.ch
  Type:   unauthorized
  Detail: 51.195.91.24: Invalid response from http://photos.dr0.ch/.well-known/acme-challenge/R4rqEGhvYplC2kybsRilyQ8qsV3Bt0DecsciZTEu3OA: 400

Hint: The Certificate Authority failed to verify the temporary Apache configuration changes made by Certbot. Ensure that the listed domains point to this Apache server and that it is accessible from the internet.

Failed to renew certificate dr0.ch-0001 with error: Some challenges have failed.

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

Similar result for certbot renew --dry-run --cert-name dr0.ch.

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

curl -ik https://dr0.ch:80
HTTP/1.1 301 Moved Permanently
Server: Apache
Location: https://dr0.ch/
3 Likes

Yes, I have set up URL rewriting to redirect all traffic to HTTPS. Here's my /etc/httpd/conf.d/dr0.conf:

<VirtualHost *:80>

    ServerName dr0.ch
    DocumentRoot "/var/www/html/main"

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =dr0.ch
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

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
3 Likes

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.

4 Likes

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.

1 Like

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.

(I've left the config without the Rewrite on http://jargon.dr0.ch, if you would like to try it out.
https://jargon.dr0.ch clearly still works.)

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.

3 Likes