I set that up originally for a wildcard, as http validation is not supported for them and I didn't fancy mucking about automating updating the main bind instances, but it is convenient for the others too and will be unaffected by these changes.
Not a perfect solution for everyone of course, copies of all the keys are in one place for one thing, and it all in one place could be bad or good for maintenance (single point of failure, but single service to monitor & maintain), but worth considering if you expect problems with http validation.
> some countries and their IP ranges just need not access my server
I'm guessing that they won't be using locations that are commonly blocked in this way anyway. And if they do happen to use one, you may be fine as only two of the three external checks need to be responded to.
Still unexperienced with letsencrypt, but I know enough that I cannot use the standard way.
Therefore ACME's DNS request for checking via DNS validation is validated directly by the tiny DNS server due to the CNAME record directing traffic to it.
I've never done this my self neither, but I think it would be along those lines.
You first set up a VM and set up your favourite authoritative DNS software on it: popular choices are ISC's BIND and NLnet's NSD. Either will do. Call it (e.g.) ns-dnsauth.mydomain.com, which is Internet accessible only on udp/53 and tcp/53.
You have to then configure that DNS server to serve the domain (e.g.) dnsauth.mydomain.com.
Next you configure the DNS server software to allow dynamic updates. For ISC BIND, you can set up (crypto) keys and use the nsupdate(1) utility:
* https://www.zytrax.com/books/dns/ch7/xfer.html#allow-update
* https://dan.langille.org/2017/05/31/creating-a-txt-only-nsup...
Point your public/external DNS records to your delegated-auth server by having (say) _acme-challenge.www.mydomain.com be a CNAME to (say) _acme-challenge.www.dnsauth.... LE will follow the CNAME and try to do the verification against the record in dnsauth sub-domain that lives on the ns-dnsauth VM.
Then you have your LE/ACME client(s) run a hook script to publish (and cleanup) the dns-01 TXT challenge records:
* https://dan.langille.org/2017/07/04/acme-sh-getting-free-ssl...
* https://github.com/dehydrated-io/dehydrated/wiki/example-dns...
The LE client goes to the LE API, gets a verification token/nonce, executes the the hook script to push the TXT record to ns-dnsauth, the LE folks verify the record, the LE client (ideally) cleans up the TXT record, receives the cert for the LE API, puts it in the correct path and restarts your (web) service(s).
Someone actually wrote a limited-functionality DNS server that allows for pushing of records via a REST API for this purpose:
* https://github.com/joohoi/acme-dns
This way the 'heavier' BIND/NSD software doesn't have to be used, as those have more features than are needed.
4-6 instances of pdns authoritative for a domain, and pdns recursor running locally for each box. And Cloudflare free tier while revenue can't justify rolling-out Varnish and other locally-deployed capacity/DDoS mitigations.
It may also be a better idea to push DNS updates via configuration management or driven from something like Envoy so there's a history and a single-source-of-truth (SSOT) to point-to rather than multiple people doing manual tinkering, which is a labor-intensive, antiquated approach.
* https://doc.powerdns.com/authoritative/dnsupdate.html
If we're just talking about issuing certs, I don't know why one need 4-6 instances for serving the dnsauth sub-domain.
Though that isn't actually how I do it (I'm using dehydrated with my own hook script to update a bind9 instance) but probably would be if I started again from scratch.
Let's encrypt will only check the DNS entry once, if it doesn't find it, it fails the authentication process and doesn't retry (contrary to the specs).
Either way, letsencrypt will probably have a somewhat fixed pool of these challenge validation IP addresses/ranges, so adding those to a white list should probably work with a strict firewall.
But that's a wrong metric to optimize for. Cutting down the number of "attacks" by 90% doesn't improve your security. If your server has a vulnerability that can be picked up by script kiddie scanners, changing the default port only delays the inevitable.
For example, if you don't have WordPress, then all the attempts to access /wp-admin will never work, but will fill your logs with 404 errors.
You scan for and patch known vulnerabilities, and assume that some unknown ones still remain. You deploy WAF to block some of the unknowns or at least make them harder to exploit. You harden the host and segregate the network to make it harder for the attacker to move laterally when they manage to exploit something anyway. You use SIEM or just regular log review to hopefully catch attackers that have been delayed by your defensive measures.
Putting your service on a non-default port is a perfectly valid measure as part of a larger defensive strategy. It has its pros and cons, you've got to be aware of what threats it mitigates and what it doesn't, but it can be useful.
It’s about as useful as wearing a condom 50% of the time.
Only you can talk to sensitive ports. And the server is available to the rest of the world for non sensitive things. And if you connect from a new IP, within 5 min you have access to the server (I have a scheduled task that updates the IP list with my current IP so I usually don’t even wait).
If you weren't trying to say that, my mistake.
> Either way, letsencrypt will probably have a somewhat fixed pool of these challenge validation IP addresses/ranges, so adding those to a white list should probably work with a strict firewall.
They won't publish the ranges as far as I've read.
Really, do give it a try.
Your idea of just randomly blocking access from certain IP address ranges doesn’t really provide you with any security at all. If you’re worried about rusaian hackers or whatever, most people exploiting anything have access to botnets with whatever bespoke IP address ranges they need to bypass those sort of rules.
In anti fraud we see this commonly, people using stolen details will happily get better matches with GEOIP than the legitimate users of the credentials. Blocking specific countries IP allocations is just providing a false sense security on your part.
Like? For what price?
> Blocking specific countries IP allocations is just providing a false sense security on your part.
No, it's a preventative measure. Just like changing SSH to a non-standard port reduces pointless attempts.
If you own example.com, you can delegate to dnsauth.example.com for $0 (or simply the price of a Internet-facing machine that has DNS open).
Say you want a cert for www.example.com. LE will check for ownership by looking up _acme-challenge.www.example.com. Instead of having a TXT record with the nonce, _acme-challenge.www is actually a CNAME pointing to _acme-challenge.www.dnsauth--where the TXT nonce lives.
The DNS daemon that is authoritative for dnsauth can be the traditional BIND, or other software:
* https://github.com/joohoi/acme-dns
This is often called 'DNS alias' mode:
* https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mo...
* https://www.eff.org/deeplinks/2018/02/technical-deep-dive-se...
This isn't some special "Let's Encrypt DNS forwarding mode" that DNS providers have to explicitly support. It's simply part of "how DNS works".
And which of those also have an API that is supported by Certbot?
I would really like names where a setup like this has been tested and works.
Certbot allows for hook scripts, and you can use a utility that can talk multiple APIs:
* https://github.com/AnalogJ/lexicon
> I would really like names where a setup like this has been tested and works.
The guy who runs BSDCan and PgCon uses it for his personal stuff as well as FreshPorts.org, etc:
* https://dan.langille.org/2017/05/31/creating-a-txt-only-nsup...
* https://dan.langille.org/2019/02/01/acme-domain-alias-mode/
He used acme.sh, though I'm more partial to dehydrated:
* https://github.com/dehydrated-io/dehydrated/wiki/example-dns...
We use it at work, but I don't want to dox myself. :)
And as I stated in the very first sentence, it is self-serve:
> If you own example.com, you can delegate to dnsauth.example.com for $0 (or simply the price of a Internet-facing machine that has DNS open).
We do this at work: our main registrar does not have a restricted API, so we have a sub-domain that lives on a DNS server in our DMZ. Internal ACME clients update the desired TXT records when asking LE for a cert.
The cost is the price for keeping a VM running and updated, which for us is minimal since it is on our private cloud.
Every layer of security makes attacks that much more costly.
I'm always a little surprised when there are short comings in IAM like that with route53 and records. It seems like a natural thing to be able to control, but for some reason you don't have resource level controls on hosted zones. It's all or nothing.
There is no way to create a token allowing access only to _acme-challenge record.
Let's Encrypt is obeying normal DNS mechanics, so when they ask for a TXT record for _acme-challenge.cat-photos.example.com and get a CNAME as a response, they'll ask for the TXT record for the name in the CNAME answer instead. If that's cat-photos.cert-issuer.example.com then a token valid only for the sub-domain cert-issuer.example.com can write that TXT record.
You sort out the CNAME once, probably when creating cat-photos.example.com or setting it up to get a certificate, and then afterwards the API token is enough for automation.
Run your own DNS server and get a registrar lock. If that is not feasible, and consultants are too expensive, I would look into the more expensive dns providers that provide custom interface that fit the threat model of your system. If that is also too expensive then I would take a second look at the risk analysis and recalculate the cost of each risk.
Do you really think you're stopping anyone in .cn who wants to actually connect to your server from doing so?
Proxies and botnets are a thing.