I've been using certbot without issue for a while & I normally prefer to do DNS-01 authentication but for one of my websites I only own a subdomain so I have to use HTTP-01 authentication using the Apache plugin
It works great but I'd like to get a better understanding of how it works
Checking the logs after doing a --dry-run renewal simulation, I see that it restarts my Apache subprocesses twice, usually about ~15 seconds apart. So I assume the first reload is to apply a temporary configuration change and the second reload is to revert the change. But what exactly is the temporary change?
The way I have Apache setup on this server, I have many Vhosts for port 443 for different sites, but for port 80, I just have a single catch-all Vhost with no DocumentRoot and a bunch of mod_rewrite rules to perform various redirects. Some hostnames get redirected specific places, but most traffic hits a generic "strip WWW and redirect to HTTPS" rule at the end:
Based on experimentation, I think this is what certbot does:
It modifies my existing port 80 Vhost instead of creating a new Vhost. This is based on the verification traffic appearing in my 80-access.log file and not elsewhere
The Vhost seems to continue to function normally during the verification, all my forwardings continue to work, but I think it's putting something in place to prevent requests from being forwarded specifically if they contain /.well-known/acme-challenge/; under my normal config, these would get forwarded too, but in the log when the connections from LetsEncrypt hit, the end up as 200's instead of 308's. Also, if I test rapidly with curl from another machine while doing the simulated renewal, trying to hit /.well-known/acme-challenge/xxxxxx (I can't test with the actual filename since it's different every time), I see it go from 308 to 404 and then back to 308.
So I think it's probably inserting a rule before all my other rules, something like RewriteRule ^/.well-known/acme-challenge/(.*)$ - [END]
Am I on the right track?
but given that my port 80 Vhost has no DocumentRoot I'm not sure how it actually serves the verification file
Does it write the file to disk or serve it from RAM somehow?
And one final semi-related question, is there anything on the roadmap for Certbot to allow DNS-01 and HTTP-01 to be combined for a single certificate (i.e. use DNS-01 for some domains and HTTP-01 for others)? I think I asked a year or two ago and was told that some other ACME clients support this but for certbot it's a "maybe someday" thing.
After doing some further testing, I managed to catch it writing files named le_http_01_challenge_pre.conf and le_http_01_challenge_post.conf into /etc/apache2
so I think I was on the right track with my guesses
I suppose doing an internal/hidden redirect to an explicit file path works even if you don't have a DocumentRoot for the vhost (was not aware of that until today)
Other people here are much more familiar with certbot than I am, but I think you've got it exactly right. Is it causing any problems, or are you just being curious? (Nothing wrong with being curious, especially as it comes to how software is reconfiguring your server!)
If you want a less intrusive method that you have more control over, you could configure a path for your server to serve the .well-known/acme-challenge files from and then have certbot use the webroot authentication method. That way it would just be writing and deleting a file and not needing to edit your apache config. But I'd be hesitant to muck too much with a production system which is already working.
Just curiosity, although I did have a question at the end of the first post (not sure if anybody made it that far) about if certbot might someday add the ability to combine HTTP-01 and DNS-01 challenges in a single certificate like some other ACME clients can apparently do.
A trick to combine two domains with different challenges on one cert would be to get a cert for each one then immediately request the combined cert. The cached validation from the previous certs would still apply. It's definitely a trick though and you couldn't really rely on that.
As far as I know, Apache can only be configured using its configuration files on disk, not using some remote procedure call or something like that, that would result in a change in RAM.
You change a configuration file and you reload (or restart) Apache to load those changes. That's just about it.
Some applications have methods to change configurations for running daemons which can also save those changes to disk, e.g. postconf -e. But Apache is not one of them.