Cannot get HTTP-01 validation working in my env (acme.sh, Pebble, Apache2)

Hello once again! I'm attempting to make Pebble (v1.0.2-0.20211028190950-4cce110cac5a) issue a certificate for a locally resolvable domain - bullseye.com (this is done via a record in /etc/hosts).

I'm using acme.sh for this purpose - v.3.1.0 and i'm running the following commands to trigger the issuing process:

acme.sh --register-account --server $PEBBLE_URL --accountemail "my_email_address@domain.com"

sudo -E acme.sh --issue --server $PEBBLE_URL -d bullseye.com --webroot /var/www/html --force --debug

and I'm getting this response:

[Mon Jan  6 20:51:19 CET 2025] original='{
   "status": "invalid",
   "identifier": {
      "type": "dns",
      "value": "bullseye.com"
   },
   "challenges": [
      {
         "type": "http-01",
         "url": "https://localhost:14000/chalZ/uXkXsbSltX4ySiB4TDOUvA6J1rqpueb77mBGJYReIC4",
         "token": "hH5GCUj2Eqe4IPEfE9w20GuitTo_M_0DAtDuPbHfC28",
         "status": "invalid",
         "validated": "2025-01-06T19:51:13Z",
         "error": {
            "type": "urn:ietf:params:acme:error:connection",
            "detail": "Get \"http://bullseye.com:0/.well-known/acme-challenge/hH5GCUj2Eqe4IPEfE9w20GuitTo_M_0DAtDuPbHfC28\": dial tcp 127.0.0.1:0: connect: connection refused",
            "status": 400
         }
      }
   ],
   "expires": "2025-01-06T20:51:12Z"
}'

From it, it seems that the validation is being attempted against "http://bullseye.com:0" and is being rejected as there is nothing listening on port "0" obviously.

Formerly the validation has been attempted on port 5002, but has been failing for the same reason. This is why I have modified the pebble-config.json like this:

{
  "pebble": {
    "listenAddress": "0.0.0.0:14000",
    "managementListenAddress": "0.0.0.0:15000",
    "certificate": "test/certs/localhost/cert.pem",
    "privateKey": "test/certs/localhost/key.pem",
    "httpPort": 0,
    "tlsPort": 5001,
    "ocspResponderURL": "",
    "externalAccountBindingRequired": false,
    "externalHttpPort": 80
  }
}

It seems it does not matter if the "httpPort" is being set to "0" or ommited completely, the behaviour is same. According to available resources I have the "externalHttpPort" should play a key role here. However, I must be missing something.

Follows the part that should make sure that the requests against my Apache2 server get served by Pebble (as long as I understand the topic properly, please feel free to sched some light into this as I'm new in this area completely):

 ProxyPass /.well_known/acme-challenge/ https://localhost:14000/.well_known/acme-challenge/
 ProxyPassReverse /.well_known/acme-challenge/ https://localhost:14000/.well_known/acme-challenge/

this has been an excerpt from /etc/apache2/sites-available/acme-proxy.conf that has been added to the config via "a2ensite" and apache reloaded.

So to sum up my question: I would need to know how to get rid of the "0" port in the requests and make acme.sh query apache on port 80 instead and then get served by Pebble.

Best regards,
Michal

There is no externalHttpPort configuration parameter. Where did you see that?

I think you need to set httpPort to the HTTP port you'd like to reach, typically 80. Not 0, or 5002, or whatever.

3 Likes

Also, if you're using pebble you can tell it to skip validation altogether, unless you're trying to emulate real certificate renewal against a real CA.

If your objective is to run a local ACME CA for local certs, consider something like Smallstep Step CA or Hashicorp Vault, both of which are designed to be more persistent than pebble.

2 Likes