Documentation/Examples in Configuring nginx for automated certificate renewal


#1

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:

not necessary

I ran this command:

sudo /etc/certbot-auto/certbot-auto certonly --authenticator webroot --installer nginx --must-staple --staple-ocsp -d …

server {
autoindex on;
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www;
server_name example.com;
location ~ /.well-known {
add_header Content-Type text/plain;
allow all;
}}

It produced this output:

Congratulations! Your certificate and chain have been saved at: …

My web server is (include version):

nginx

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

ubuntu 16.04

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

As you can see I succeeded in issuing the certificate.
I set up a dedicated nginx configuration (shown above) just for this purpose.
As I understand, since Jan 2018, the challenge has to be in http, not in https, due to a technical problem.
(Is that correct?)

Note: I don’t rely SNI - I only have only one certificate with multiple domains (SAN).

In normal usage, I return the nginx configuration to always forward port 80 (http) to port 443 (https).
But in that state I don’t believe it can perform the automatic certificate renewal. (Is that correct?)

I am looking for documentation (or examples) about how to set up the nginx configuration so that it will always forward to 443 (https) except for access to /.well_known , so that auto renewal could be performed.

Also it would be a plus if there were a way to limit access to /.well_known only to letsencrypt.org only at time of auto renewal.


#2

This issue is a little bit subtle. :slight_smile:

The challenge validator will follow redirects, so there’s nothing inherently preventing automated renewal.

It appears that your configuration may prevent your HTTP→HTTPS redirect from applying to /.well-known URLs at all (though I’m not certain that it has that effect). This isn’t strictly necessary, since the validator follows redirects, but it could make the validation process more straightforward in some configurations if it does have the effect that I’ve speculated.

Using --authenticator webroot (instead of --nginx or --authenticator nginx) may also be compatible with a slightly wider range of nginx configurations, although there are probably also causes in which it reduces compatibility instead. The idea of --authenticator nginx is that Certbot would create a temporary server block somewhat akin to the one that you’ve created above, and then automatically remove it for you after the certificate is issued. (This process would be repeated at every renewal.) By contrast, --authenticator webroot just creates the one single challenge file per domain in the indicated webroot directory, and then deletes that file afterward, without creating or removing any server blocks.

I don’t currently know of any reason why automated renewal wouldn’t work. You can test it with certbot renew --force-renewal. (If you have more than one certificate or have reissued your certificate more than once already this week, this might run up against issuance rate limits and may be better with --dry-run, which uses a test CA instead of the real CA to avoid rate limit problems. The version without --dry-run is a more realistic test but does count against your weekly rate limit, which is probably only an issue if you have or intend to have more than one certificate from Let’s Encrypt at a time.)

Without --force-renewal, certbot renew will say that it’s not yet necessary to renew your certificate (because it’s not near expiry), and won’t attempt to renew it until such a command is run 60 days from the original issuance time.

By the way, I think certonly causes --installer to be ignored. (You can tell if this is so if your nginx configuration did not get edited for you to refer to the newly-issued certificate.) This might or might not be want you wanted.


#3

I guess I should say specifically that if you want to put the blanket HTTP→HTTPS redirect in place without any exceptions, you can just set up the /.well-known server block to refer to the HTTPS service instead of the HTTP one—since the validator will follow that redirect. If you’re serving static files out of the filesystem, you may not even need a separate server block for Let’s Encrypt validation (you can just tell Certbot where your document root is). If you’re not simply serving static files out of the filesystem, you’ll probably still need a server block like the one that you’ve added, but it’s fine for it to be in HTTPS rather than HTTP!


#4

Hi Schoen

Thanks very much for your help.

(1)

I should have included the letsencrypt reference:

in my original post.

In particular this part:

If you use Certbot in its automatic Nginx or Apache modes, you need to upgrade to version 0.21 in order to issue certificates for new domain names. If you use the certbot or letsencrypt command, you are using packages provided by your operating system vendor, which are often slow to update. If this is the case, you should probably switch to certbot-auto626, which provides the latest version of Certbot on a variety of operating systems. Also note: If you block port 80 on your web server, upgrading to the latest Certbot will not fix your problem, because it switches to the HTTP-01 validation method, which uses port 80. I recommend opening port 80 and redirecting HTTP traffic to HTTPS.

(2)

I tried and failed to install certbot - probably because the packages were in flux. So I followed the recommendation and installed certbot-auto instead. Following the guidelines for certbot-auto did not include the --nginx flags.

However, thanks to your explanation I now understand that with regular certbot I will be able to specify
–authenticator nginx and it will modify my nginx configuration only temporarily for the challenge timespan only.
I guess I will wait until the ubuntu packages are ready - I’m not in a rush right now.

(3)

I did set up the nginx

location ^~ .well_known { … }

block inside the https server block, to see if the challenge would work in https.
However it returned an error as follows:

The following errors were reported by the server:

Domain: www.go-oio.com
Type: connection
Detail: Fetching
http://www.go-oio.com/.well-known/acme-challenge/7Oe4qP4r1R5J22VX3l7zGXAVgHHaouZiN9myQF4Jpdw:
Timeout

Although it could be something I did wrong, I’m inclined to think
it was a requirement to use HTTP for the challenge, as the letsencrypt reference seems to say.

(4)

As you say, trying to handle the authentication in HTTP with a “localtion /.well-known {…}” clause
which if that clause fails skips out with a redirect to the HTTPS block is also an option.
I find nginx syntax and semantics somewhat problematic in that it is not always intuitive,
the documentation is not always straightforward, and it is difficult/awkward to debug and test.
I will consider that option if by the end of April, when the current cert expires, the new certbot module is still not stable.

With your helpful dialog I think I now have a good enough grasp to move forward.

Thanks again!