Where is the documentation for acme-challenge?

I don’t see any documentation at certbot or letsencrypt about “acme-challenge”. I’ve tried generating certificates the simple way, even following this tutorial:

Not even the tutorial mentions acme-challenge. But when I run the sudo letsencrypt command, I get:

  • The following errors were reported by the server:

    Domain: xyz.com
    Type: unauthorized
    Detail: The key authorization file from the server did not match
    this challenge

So now I’m in my web server trying to guess how to respond to the challenge, and it looks like I need to echo the big number in the url. Unfortunately though I’ve hit the rate limit, so my experimentation is at an end this week.

Why is it that NONE of the instructions I’ve seen, including online tutorials, ever mention that I have to set up some magic responder to the acme-challenge?

1 Like

Hi @fexl, welcome to the community forum :wave: Sorry to hear about the trouble you're having.

I think the best way for us to help you is if you fill out the new topic help template so we can know more about your hosting provider and what you've tried so far:

My domain is:

I ran this command:

It produced this output:

My web server is (include version):

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

My hosting provider, if applicable, is:

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

I'm using a control panel to manage my site (no, or provide the name and version of the control panel):

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

Unfortunately that's not the correct way to respond to the ACME HTTP-01 challenge and won't work. The key authorization is a combination of the challenge token and your ACME account thumbprint. The ACME RFC has the full details but see my next answer, you shouldn't need to worry about this level of detail.

The reason you haven't found much documentation about the way to do that manually is because ACME is designed to be automated and responding to the challenge with the correct value is the duty of your ACME client (like Certbot). It sounds like that isn't working right in your case so the best way to fix your problem will be figuring out what needs to be changed in your Certbot usage or the configuration.

1 Like

Hi @fexl

start with some basics:

Then check the page about Challenge types:

My domain is:

nficp.com

I ran this command:

sudo letsencrypt certonly -a webroot --webroot-path=/usr/share/nginx/html -d nficp.com -d www.nficp.com

It produced this output:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nficp.com
http-01 challenge for www.nficp.com
Using the webroot path /usr/share/nginx/html for all unmatched domains.
Waiting for verification…
Cleaning up challenges
Failed authorization procedure. nficp.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://nficp.com/.well-known/acme-challenge/iR8KnoGMNCig9YeQlzJKgpZrBaHs4iT5RnDA27xkZz4 [74.207.231.23]: “\n\n404 Not Found\n\n

Not Found

\nTh”, www.nficp.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.nficp.com/.well-known/acme-challenge/p9dT1gwDkDJXxpH4ygsTnYBXDbl11FbvTJIiUxa-0IU [74.207.231.23]: "<!DOCTYPE HTML PUBLI

IMPORTANT NOTES:

My web server is (include version):

nginx version: nginx/1.14.0 (Ubuntu)

(By the way, I do not automatically serve any static files. It’s all served by application code.)

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

Ubuntu 18.04.3 LTS

My hosting provider, if applicable, is:

linode

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

yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel):

no

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

Thanks for the info!

I think this is your problem. When you specify --webroot-path=/usr/share/nginx/html Certbot expects that it can create a file in /usr/share/nginx/html/.well-known/acme-challenge/xxxx that will be served as a response for HTTP requests to www.nficp.com/.well-known/acme-challenge/xxxx where xxxx is the challenge token.

You'll need to adjust your webserver configuration to serve static files for requests to that path in order to use the HTTP-01 challenge like you have.

Another option is to use Certbot's --nginx plugin instead of the certonly method. That's likely a superior experience overall. These docs have more information: https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx

4 Likes

OK I’ll try to figure out how to serve a static file of that form only.

I did try the --nginx method first, thinking it would be simpler, but it just told me it was unable to connect for port 80. I did a “ufw allow 80”, but to no avail.

Great :+1: If you get stuck please share your Nginx config & vhost config and someone will be able to help :slight_smile:

Interesting. I'm not sure what would cause that off-hand since it seems based on the error message you shared that Let's Encrypt was able to connect to your server on port 80 and got back a 404 HTML error page instead of the key authorization. If port 80 weren't accessible the error would have been different.

1 Like

OK, I added this stanza to nginx.conf, and restarted with service nginx restart:

    location /.well-known
        {
        }

(That went under one of my “server” sections.)

Now voila you can see this:

http://nficp.com/.well-known/index.html

Unfortunately I can’t try the certificate again because I am rate-limited due to too many failed experiments, so I’ll have to try again in a week. Thanks for the advice!

1 Like

That's only a one-hour-rate-limit.

1 Like

The other issue with the --nginx method is I had to create a dummy stanza specifically for nficp.com first. You see, I currently only need one stanza to serve many domains:

server
    {
    server_name 74.207.231.23;
    listen 74.207.231.23:80;
    ...
    }

Now I know I have to clone that and modify it with a new domain and port 443 if I’m going to do SSL (e.g. “server_name nficp.com”). I figured if I’m having to manually clone a stanza in the first place just so certbot can find it, I might as well do certificate-only in the first place.

Interesting. I had read this, and took it at face value:

“If you’ve hit a rate limit, we don’t have a way to temporarily reset it. You’ll need to wait until the rate limit expires after a week.”

But perhaps I missed some context somewhere. Thanks for the cheerful news!

Great, don't forget that you'll want to have certbot renew perform that nginx reload itself in the future so that Nginx will always pick up the renewed certificates when they change. Probably configuring a --deploy-hook that runs service nginx reload will do the trick.

Wow, auto-renewal. There’s a whole other kettle of fish. I’ll have to do some serious research into setting up the appropriate cron job, how to use deploy-hook, etc. It’s hard to even imagine all that working properly, but I guess people do it all the time. Thanks for the heads-up!

(EDIT: I do see that /etc/cron.d/certbot is already configured, so it’s just a matter of the hook.)

EDIT:

For the hook that reloads nginx after certs are renewed, I went into /etc/letsencrypt/renewal-hooks/post and created an executable file like this:

root@afs:/etc/letsencrypt/renewal-hooks/post# ll
total 4
-rwx------ 1 root root 21 Oct 10 12:27 reload

(I did a chmod 700 on it just to be as strict as possible.) The script just says:

root@afs:/etc/letsencrypt/renewal-hooks/post# cat reload
service nginx reload

Since the certs expire every 90 days, I should see plenty of opportunities for this hook to work.

1 Like

Everything is working well. TOO WELL. By that I mean, much to my surprise, I am able to serve two different domains, with two different certificates, on the same IP address:

https://absolutefundservices.com/login/

https://nficp.com/

The relevant snippets from nginx.conf are:

    server_name absolutefundservices.com;
    listen 74.207.231.23:443 ssl;

    server_name nficp.com;
    listen 74.207.231.23:443 ssl;

I’m frightened. How can that possibly work? I thought you could only have ONE domain/certificate per IP address.

Not if your server supports SNI:

2 Likes

As I live and breathe -- now I've seen it all. That's pretty convenient. Now I don't have to dink around with getting a dozen or so new IP addresses.

I had already gotten a new IP for nficp.com, but I hadn't ported the A record over yet. I decided to try the certificate on the existing IP. Much to my surprise, the one for absolutefundservices.com still worked.

3 Likes

Now I'm on a roll, deploying https for many sites. I'll definitely donate to Lets Encrypt. Thanks so much for the help.

1 Like

Yep, that's possible.

Earlier (without SNI, sample Windows 2008): Only one certificate -> a lot of ip addresses or one certificate with a lot of domain names.

Now (all modern browsers support SNI): One ip address, a lot of different certificates with different domain names -> the server uses SNI to select the correct certificate.

1 Like

Happy to hear it! Congratulations on getting everything working :tada:

Also, a donation has been sent.

1 Like