TL:DR, this was a caching problem - Apache's internal data cache was jamming up the ephemeral test file creation/removal process that dehydrated/Lets encrypt use to validate the domain, serving a null file which was cached before the the validation text was inserted. Blocking caching in the permissions stanza for the .well-known
directory in httpd.conf
solved this issue. The successful incantation is in the responses below. It could be inserted in httpd.conf
, httpd-vhosts.conf
, or a .htaccess
file, depending on how one's servers are configured.
I migrated my server from one box to another, updating some of the config files, so there's definitely a risk of misconfiguration, [spoiler: it was] but I've checked against other servers already migrated and collecting certs correctly. This one seems to be having a problem validating despite carefully "melding" the .conf
files as best I can. It does not seem to be a problem with :80 access from outside (that works) nor with dehydrated having write permissions as the authorization files are being created and deleted with the correct ownership, group, and permissions. I'm stumped...
My domain is: cube.blackrosetech.com
I ran this command: # su -m _letsencrypt -c 'dehydrated -c''
It produced this output:
# INFO: Using main config file /usr/local/etc/dehydrated/config
Processing cube.blackrosetech.com with alternative names: webmail.blackrosetech.com red.blackrosetech.com git.blackrosetech.com cameras.blackrosetech.com
+ Checking domain name(s) of existing cert... unchanged.
+ Checking expire date of existing cert...
+ Valid till Jul 5 10:16:25 2024 GMT (Less than 30 days). Renewing!
+ Signing domains...
+ Generating private key...
+ Generating signing request...
+ Requesting new certificate order from CA...
+ Received 5 authorizations URLs from the CA
+ Handling authorization for cube.blackrosetech.com
+ Handling authorization for git.blackrosetech.com
+ Handling authorization for red.blackrosetech.com
+ Handling authorization for webmail.blackrosetech.com
+ Handling authorization for cameras.blackrosetech.com
+ 5 pending challenge(s)
+ Deploying challenge tokens...
+ Responding to challenge for cube.blackrosetech.com authorization...
+ Cleaning challenge tokens...
+ Challenge validation has failed :(
ERROR: Challenge is invalid! (returned: invalid) (result: ["type"] "http-01"
["url"] "https://acme-v02.api.letsencrypt.org/acme/chall-v3/404149904996/uC9XdA"
["status"] "invalid"
["validated"] "2024-09-16T00:07:30Z"
["error","type"] "urn:ietf:params:acme:error:unauthorized"
["error","detail"] "During secondary validation: The key authorization file from the server did not match this challenge. Expected \"--30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts.soCaRvo-o7b26zonEQR2-fzRoG0fVrYbUoYpR1P6abQ\" (got \"\")"
["error","status"] 403
["error"] {"type":"urn:ietf:params:acme:error:unauthorized","detail":"During secondary validation: The key authorization file from the server did not match this challenge. Expected \"--30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts.soCaRvo-o7b26zonEQR2-fzRoG0fVrYbUoYpR1P6abQ\" (got \"\")","status":403}
["token"] "--30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts"
["validationRecord",0,"url"] "http://cube.blackrosetech.com/.well-known/acme-challenge/--30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts"
["validationRecord",0,"hostname"] "cube.blackrosetech.com"
["validationRecord",0,"port"] "80"
["validationRecord",0,"addressesResolved",0] "23.114.97.246"
["validationRecord",0,"addressesResolved"] ["23.114.97.246"]
["validationRecord",0,"addressUsed"] "23.114.97.246"
["validationRecord",0] {"url":"http://cube.blackrosetech.com/.well-known/acme-challenge/--30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts","hostname":"cube.blackrosetech.com","port":"80","addressesResolved":["23.114.97.246"],"addressUsed":"23.114.97.246"}
["validationRecord"] [{"url":"http://cube.blackrosetech.com/.well-known/acme-challenge/--30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts","hostname":"cube.blackrosetech.com","port":"80","addressesResolved":["23.114.97.246"],"addressUsed":"23.114.97.246"}])
My web server is (include version): apache24-2.4.62
The operating system my web server runs on is (include version): FreeBSD 14.1-RELEASE-p3
My hosting provider, if applicable, is: self
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):
# INFO: Using main config file /usr/local/etc/dehydrated/config
# INFO: Running /usr/local/bin/dehydrated as _letsencrypt/_letsencrypt
# INFO: Using main config file /usr/local/etc/dehydrated/config
Dehydrated by Lukas Schauer
https://dehydrated.io
Dehydrated version: 0.7.2
GIT-Revision: unknown
OS: FreeBSD 14.1-RELEASE-p3
Used software:
bash: 5.2.32(0)-release
curl: 8.9.1
awk, sed, mktemp, grep, diff: BSD base system versions
openssl: OpenSSL 3.2.3 3 Sep 2024 (Library: OpenSSL 3.2.3 3 Sep 2024)
if I create an index.php file in /usr/local/www/.well-known/acme-challenge/index.htm
, with the text "test" I can curl it from outside the LAN (e.g. from a machine not VPN'd in) with the same permissions/ownership as the challenge files.
# ls -lah
-rw-r--r-- 1 _letsencrypt www 5B Sep 15 17:27 index.htm
$ curl http://cube.blackrosetech.com/.well-known/acme-challenge/
test
This made me suspiecious that the challenge files weren't being created, and as they're ephemeral, curling them as they appear from a remote host isn't trivial, but I did run the following which shows the files were created successfully.
# /usr/local/www/.well-known/acme-challenge # fswatch -m kqueue_monitor . | xargs -n 1 -I {} ls -lah {}
total 38
drwxrwxr-x 2 _letsencrypt www 2B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
total 39
-rw------- 1 _letsencrypt www 87B Sep 15 17:07 --30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts
drwxrwxr-x 2 _letsencrypt www 3B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
total 39
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 --30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts
drwxrwxr-x 2 _letsencrypt www 4B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw------- 1 _letsencrypt www 87B Sep 15 17:07 TMDgK--NQ5Aa3oMXuNo4Rp8cZtxtCgp1XwQ66vcLKh4
total 40
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 --30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts
drwxrwxr-x 2 _letsencrypt www 5B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw------- 1 _letsencrypt www 87B Sep 15 17:07 hUIN_2LqifS2sKBhAFYk0ixotx-RxFTtGovU8bBOJQg
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 TMDgK--NQ5Aa3oMXuNo4Rp8cZtxtCgp1XwQ66vcLKh4
total 40
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 --30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts
drwxrwxr-x 2 _letsencrypt www 6B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 hUIN_2LqifS2sKBhAFYk0ixotx-RxFTtGovU8bBOJQg
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 jguvPlz9gBkIwRCwOfucjw4oqweglL-B4m5q6VO7OA4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 TMDgK--NQ5Aa3oMXuNo4Rp8cZtxtCgp1XwQ66vcLKh4
total 41
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 --30dcmwgxO0LTDtwMV96Oe5DcrlC-laI1A2q8l8Tts
drwxrwxr-x 2 _letsencrypt www 7B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 hUIN_2LqifS2sKBhAFYk0ixotx-RxFTtGovU8bBOJQg
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 jguvPlz9gBkIwRCwOfucjw4oqweglL-B4m5q6VO7OA4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 TMDgK--NQ5Aa3oMXuNo4Rp8cZtxtCgp1XwQ66vcLKh4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 vD4aQ9F61bMTTJSYWf9IpecOj3UAbq-q29n8dt4WsD0
total 76
drwxrwxr-x 2 _letsencrypt www 6B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 hUIN_2LqifS2sKBhAFYk0ixotx-RxFTtGovU8bBOJQg
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 jguvPlz9gBkIwRCwOfucjw4oqweglL-B4m5q6VO7OA4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 TMDgK--NQ5Aa3oMXuNo4Rp8cZtxtCgp1XwQ66vcLKh4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 vD4aQ9F61bMTTJSYWf9IpecOj3UAbq-q29n8dt4WsD0
total 67
drwxrwxr-x 2 _letsencrypt www 5B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 hUIN_2LqifS2sKBhAFYk0ixotx-RxFTtGovU8bBOJQg
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 jguvPlz9gBkIwRCwOfucjw4oqweglL-B4m5q6VO7OA4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 vD4aQ9F61bMTTJSYWf9IpecOj3UAbq-q29n8dt4WsD0
total 57
drwxrwxr-x 2 _letsencrypt www 4B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 jguvPlz9gBkIwRCwOfucjw4oqweglL-B4m5q6VO7OA4
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 vD4aQ9F61bMTTJSYWf9IpecOj3UAbq-q29n8dt4WsD0
total 48
drwxrwxr-x 2 _letsencrypt www 3B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..
-rw-r--r-- 1 _letsencrypt www 87B Sep 15 17:07 vD4aQ9F61bMTTJSYWf9IpecOj3UAbq-q29n8dt4WsD0
total 38
drwxrwxr-x 2 _letsencrypt www 2B Sep 15 17:07 .
drwxrwxr-x 3 _letsencrypt www 3B Dec 7 2017 ..