Home How to fix 'urn:acme:error:unauthorized' certbot error
Post
Cancel

How to fix 'urn:acme:error:unauthorized' certbot error

Today we will talk about auto-updating Let’s Encrypt certificates by certbot. By default, Nginx restricts any request to .well-known folder which is needed to validate a certificate.

Your error message could look like “urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://costs.reheda.pro/.well-known/acme-challenge/0bjc2vZWyBuBfFg1XFFuqzctiUfqqfs” while renewing.

If you have quite a lot of subdomains then this approach would be useful.

Create snippet for letsencrypt acme-challenge:

1
nano /etc/nginx/snippets/letsencrypt-acme-challenge.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

#############################################################################
# Configuration file for Let's Encrypt ACME Challenge location
# This file is already included in listen_xxx.conf files.
# Do NOT include it separately!
#############################################################################
#
# This config enables to access /.well-known/acme-challenge/xxxxxxxxxxx
# on all our sites (HTTP), including all subdomains.
# This is required by ACME Challenge (webroot authentication).
# You can check that this location is working by placing ping.txt here:
# /var/www/letsencrypt/.well-known/acme-challenge/ping.txt
# And pointing your browser to:
# http://xxx.domain.tld/.well-known/acme-challenge/ping.txt
#
# Sources:
# https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491
#
#############################################################################

# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel
# other regex checks, because in our other config files have regex rule that denies access to files with dotted names.
location ^~ /.well-known/acme-challenge/ {

# Set correct content type. According to this:
# https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29
# Current specification requires "text/plain" or no content header at all.
# It seems that "text/plain" is a safe option.
default_type "text/plain";

# This directory must be the same as in /etc/letsencrypt/cli.ini
# as "webroot-path" parameter. Also don't forget to set "authenticator" parameter
# there to "webroot".
# Do NOT use alias, use root! Target directory is located here:
# /var/www/common/letsencrypt/.well-known/acme-challenge/
root /var/www/html/letsencrypt;
}

# Hide /acme-challenge subdirectory and return 404 on all requests.
# It is somewhat more secure than letting Nginx return 403.
# Ending slash is important!
location = /.well-known/acme-challenge/ {
return 404;
}


Then create specified root folder:

1
mkdir -p /var/www/html/letsencrypt

And include created snippet to all your custom domains (/etc/nginx/sites-available) in server block:

1
include snippets/letsencrypt-acme-challenge.conf;

Check configs and restart nginx:

1
2
sudo nginx -t
sudo systemctl restart nginx

Also we need to modify webroot-path of our renewal configuration:

1
nano /etc/letsencrypt/renewal/reheda.pro.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# renew_before_expiry = 30 days
version = 0.23.0
archive_dir = /etc/letsencrypt/archive/reheda.pro
cert = /etc/letsencrypt/live/reheda.pro/cert.pem
privkey = /etc/letsencrypt/live/reheda.pro/privkey.pem
chain = /etc/letsencrypt/live/reheda.pro/chain.pem
fullchain = /etc/letsencrypt/live/reheda.pro/fullchain.pem

# Options used in the renewal process
[renewalparams]
installer = None
account = 9f2268d5959e34d196f6b676cd366464
authenticator = webroot
webroot_path = /var/www/html/letsencrypt,
[[webroot_map]]
jenkins.reheda.pro = /var/www/html/letsencrypt
www.reheda.pro = /var/www/html/letsencrypt
api.costs.reheda.pro = /var/www/html/letsencrypt
reheda.pro = /var/www/html/letsencrypt
costs.reheda.pro = /var/www/html/letsencrypt
blog.reheda.pro = /var/www/html/letsencrypt
vpn.reheda.pro = /var/www/html/letsencrypt