Certbot, force IPv4?

Hello,
Is there a way to force certbot to use only IPv4 for renewals?
I have a home setup in which the domain2 is hosted on dual-stack server2 (apache) behind a home router. The problem is that i only have 1 IPv4 address. And this IPv4 address is used by a more important web server1 (apache ports 80 and 443).
I must have this new domain2 on a separate server2. This server is dual-stack, but because of the NAT on IPv4, it is only directly reachable by its IPv6 address.
I want to set up a reverse proxy on main web server1 (NATted) to pass the IPv4 requests to server2. At the same time, i want to let server2 continue serving IPv6 requests directly.
I have set up certbot on server2 and enabled the https successfully over IPv6.
The problem is when i run certbot from reverse proxy, it fails because it switches to IPv6. The verification goes asymmetric to server2 which replies 404.
This config is very often used in IPv4-deficient environments.

Previously proposed workarounds do not satisfy because:
IPv6 is the way to go, it is secure. Direct connection is the most reliable one, it works even if reverse proxy or NAT is down.
At home i don't have a pool of expensive redundant load-balancers to centralize and route all the traffic through.
Removing IPv6 DNS entry disables direct reliable connection, which is future-proof.
Removing IPv4 DNS entry blocks my site from most of today's internet.
Adding redirects to IPv4 effectively disables IPv6 connectivity.
Manual copy the certificate and key files effectively kills certbot's renewal automation on reverse proxy.

Please, add the -4 and -6 parameters to ensure symmetric validation. Like in ping command.
Or maybe you know about a reliable and secure solution with automated renewals?
Thank you,

It produced this output:
Performing the following challenges:
http-01 challenge for [domain]
Waiting for verification...
Challenge failed for domain [domain]

My web server is (include version): apache
The operating system my web server runs on is: Ubuntu 20.04
My hosting provider, if applicable, is: free.fr
I can login to a root shell on my machine: yes
I'm using a control panel to manage my site: no
The version of my client is : certbot 0.40.0

1 Like

Using IPv6 or IPv4 is not something certbot can regulate: it's determined at the Let's Encrypt validation servers and the ACME client (such as certbot) doesn't have influence over that.

I'd like to propose another workaround:

  1. set up a distinct hostname for your IPv4 reverse proxy server;
  2. on your second, IPv6 server, redirect all requests for /.well-known/acme-challenge/ to the specific hostname mentioned in step 1;
  3. set up your IPv4 reverse proxy server to accept requests for the distinct hostname set up in step 1;
  4. run certbot on your IPv4 reverse proxy server.

Using the above system, it doesn't matter at which server the request comes first: if it ends up at the IPv4 server somehow, that's fine, as you're running certbot on that one. If it ends up on the IPv6 server somehow, it'll get redirected to the IPv4 server, where you'd run certbot.

3 Likes

Hello,
Do i have to set up another virtual server in apache for that distinct domain name? Should it be third domain apart from domain1 and domain2?
The server1 already has its own short hostname which is different from server2 short hostname.
Should i configure reverse proxy on server2 in order to redirect requests for /.well-known/acme-challenge/ ?
I have certbot already running on both servers for their respective domains. Should i uninstall/disable certbot on server2?
Sorry, I don't have enough knowledge to understand your idea.

That's probably the most easy method, yes. If you set up the DocumentRoot for that virtualhost to be /var/lib/letsencrypt/http_challenges/ (which is used internally by the apache plugin), you could use that directory as the webroot-path for certbot too. But if you want a different DocumentRoot, that's fine too.

It doesn't have to be a separate domain, it can also be a subdomain from either domain1 or domain2, as long as it points to the correct server.

What do you mean with "short hostname"? Is that a publically accessible hostname?

Server2 is the server with IPv4, right? So that would be the server answering to /.well-known/acme-challenges/ not redirecting them.

You could stop using certbot on the server redirecting the request for the challenge file to the other server.

I forgot to mention this in my previous post, but in this scenario you would need to securely transfer the certificate and private key from the server with certbot to the server without certbot.

2 Likes

I don't know if I'm quite following everything, but it sounds to me like this is all overcomplicating things. If everything has IPv6 connectivity, then just ensure each server has an AAAA record for its name and use IPv6 for everything. Why do you need to try to get validation happening over IPv4 at all?

1 Like

I thought some DNS based round robin might be at play here, but come to think of it: two separate domains with two separate servers: not really an issue indeed? Let's Encrypt should prefer IPv6 above IPv4...

Only thing is: when suddenly Let's Encrypts validation server tries over IPv4 for some reason, things get messy.

1 Like

OK, server1 is the main server with both external adresses: IPv4 (via NAT) and IPv6. Server2 is new server without NAT, so no inbound IPv4 connectivity because ports 80 and 443 are already forwarded to server1.
So, if i understand right, you propose me to redirect (proxy) requests from server2:/.well-known/acme-challenges/ to server1:/var/lib/letsencrypt/http_challenges/
Short hostname is like server1, long hostname is like server1.domain.tld

Did i understand correctly that you propose to run certbot only on main server1 and copy certificate/key to the server2?
Now both servers obtain their respective certificates independently by certbot on each server via IPv6.
So, if i have to copy files, i dont need to forward anything, i just need to copy certificate/key from server2 to server1. The problem is that what happens when copy expires? Would i need to automate that copy, and how when the permissions are restricted on these files?
Yes, each server has its own AAAA record, that is how they run certbot and obtain certificates.
Validation over IPv4 is needed because i have only ONE IPv4 address and i have to reverse proxy IPv4 (ports 80 and 443) traffic via server1 to server2, so that server2 becomes available over IPv4. That is why i want to run certbot on both servers for the same domain name server2.domain.tld. I need to run certbot on reverse proxy because it terminates IPv4 https traffic and passes it further to server2.

Do you know, is it possible NOT to terminate https traffic on Apache reverse proxy, but forward it transparently to server2? Will it work with symmetric responses?
Thanks

This may overlap with suggestions people already made, but:

  • You could configure a different DNS name for the other server that only works over IPv6, and forward challenge requests that fail from the original name to the new DNS name. Then Let's Encrypt will follow the forward and make the challenge request over IPv6 to the other server.

  • You could proxy requests at the application layer from one server to the other, so a failed request could be re-attempted on the other server.

  • You could do some kind of union filesystem mount, or mount both directories from the same remote filesystem, so that both /.well-known/acme-challenge directories are always synchronized with regard to their contents (only with --webroot, not with --apache, because --apache uses an ephemeral temporary directory to serve the challenge, while --webroot uses a predictable existing path on disk).

1 Like

Http validation has various limitations depending on your configuration and your scenario is one of them.

While there will definitely be a clever way to get http validation working, the easiest solution is to use DNS validation instead of http validation.

Either use a plugin to script updates to your DNS, your own script, or use an acme-dns service.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.