Simple Local Boulder/Certbot HTTP-01 Challenge

I am new. I want to get certbot and boulder working in a simple environment. They both run on the VM where I run the below command (http-01 challenge). I can’t tell if the challenge is getting routed by Boulder’s fake DNS server correctly. I have an endpoint at 127.0.0.1/.well-known/acme-challenge/{whatever} listening for calls, but nothing has come in. I have done no editing to boulder or certbot files (maybe this is the problem).

My domain is: localhost

I ran this command: certbot certonly --server http://localhost:4001/directory --manual --preferred-challenges=http -d mydomain.com

It produced this output:
IMPORTANT NOTES:

  • The following errors were reported by the server:

    Domain: mydomain.com
    Type: unauthorized
    Detail: The key authorization file from the server did not match
    this challenge
    “z2WA2LyKkf_HVWtdNXp4BPVkWJsD4am5iE145mqEm-8.94bvla0zv_zrfHrERr00iaF6ahwEJ0Zv0g-OBUJcsqE”
    != “”

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A/AAAA record(s) for that domain
    contain(s) the right IP address.

The operating system my web server runs on is (include version): Ubuntu 16.04.6

I can login to a root shell on my machine (yes or no, or I don’t know): yes

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot): certbot 0.31.0

Here is the response in the log:
{
“identifier”: {
“type”: “dns”,
“value”: “mydomain.com
},
“status”: “invalid”,
“expires”: “2020-02-07T20:40:05Z”,
“challenges”: [
{
“type”: “http-01”,
“status”: “invalid”,
“error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “The key authorization file from the server did not match this challenge “z2WA2LyKkf_HVWtdNXp4BPVkWJsD4am5iE145mqEm-8.94bvla0zv_zrfHrERr00iaF6ahwEJ0Zv0g-OBUJcsqE” != “””,
“status”: 403
},
“url”: “http://localhost:4001/acme/chall-v3/18/PlC-6A”,
“token”: “z2WA2LyKkf_HVWtdNXp4BPVkWJsD4am5iE145mqEm-8”,
“validationRecord”: [
{
“url”: “http://mydomain.com/.well-known/acme-challenge/z2WA2LyKkf_HVWtdNXp4BPVkWJsD4am5iE145mqEm-8”,
“hostname”: “mydomain.com”,
“port”: “5002”,
“addressesResolved”: [
“123.123.123.123”
],
“addressUsed”: “123.123.123.123”
}
]
}
]
}

Maybe someone can explain the addressResolved and addressUsed attributes? It doesn’t seem to resolve to mydomain.com IP (which is what I would expect with no fake DNS), but it also isn’t 127.0.0.1.

1 Like

These are the only changes I make to a clean copy of Boulder if I want to validate against a real domain:

diff --git a/test/config/va.json b/test/config/va.json
index ece66add..841b3a1e 100644
--- a/test/config/va.json
+++ b/test/config/va.json
@@ -3,15 +3,15 @@
     "userAgent": "boulder",
     "debugAddr": ":8004",
     "portConfig": {
-      "httpPort": 5002,
-      "httpsPort": 5001,
-      "tlsPort": 5001
+      "httpPort": 80,
+      "httpsPort": 443,
+      "tlsPort": 443
     },
     "maxConcurrentRPCServerRequests": 100000,
     "dnsTries": 3,
     "dnsResolvers": [
-      "127.0.0.1:8053",
-      "127.0.0.1:8054"
+      "1.1.1.1:53",
+      "1.0.0.1:53"
     ],
     "issuerDomain": "happy-hacker-ca.invalid",
     "tls": {
@@ -38,7 +38,7 @@
   },

   "common": {
-    "dnsTimeout": "1s",
+    "dnsTimeout": "10s",
     "dnsAllowLoopbackAddresses": true
   }
 }

Have you done something similar already?

3 Likes

No, I’m not trying to validate a real domain. Everything is on localhost. I want to see a successful HTTP-01 challenge. I expect the domain I put in to be ignored and for Boulder to redirect to 127.0.0.1 for the challenge. So I have a server listening at 127.0.0.1/.well-known/acme-challenge. I expect this to be called when certbot gives this message:

Create a file containing just this data:

tFHr3_Y3kBmJad2i256m4VKiFyNBSSo4hKCeLei1lyE.94bvla0zv_zrfHrERr00iaF6ahwEJ0Zv0g-OBUJcsqE

And make it available on your web server at this URL:

http://mydomain.com/.well-known/acme-challenge/tFHr3_Y3kBmJad2i256m4VKiFyNBSSo4hKCeLei1lyE

1 Like

Well, 127.0.0.1 refers to loopback inside the Docker container, not on the Docker host.

So from Boulder’s perspective, nobody is listening on 127.0.0.1:80.

I think you will want to get the IP address of docker0 on your host, and replace the FAKE_DNS environment variable in docker-compose.json with that IPv4 address.

You might still also need to update the HTTP port to 80 in va.json.

3 Likes

:wave: Hi @ryanesch

Are you running Boulder in Docker per the dev setup instructions? If so then the FAKE_DNS value shouldn’t be 127.0.0.1, it should be the IP of your host machine’s docker interface.

This would be the error I would expect to see if the FAKE_DNS was 127.0.0.1 and your ACME client was on the Docker host. The empty key auth response would be from the pebble-challtestsrv running on 127.0.0.1 in the Boulder docker container and not the webserver your ACME client provisioned the HTTP-01 response with.

P.s. Have you considered using Pebble instead of Boulder? It’s generally much easier to work with.

3 Likes

Thank you for the reply! You and _az were spot on. The problem was my FAKE_DNS pointing inside my docker container instead of the bridge to my host machine. After I changed FAKE_DNS and httpport in va.json, I got this working.
Thanks again.

2 Likes

Glad to hear it! Thanks for reporting back with the fix that worked.

1 Like