Let's Encrypt using webroot on nginx with an SSL redirect
I have a web site being served with nginx
with the following requirements:
- Redirect all http -> https
- Zero-downtime Let's Encrypt certificate renewal
In order to satisfy (1) I have a small http->https redirect in my nginx
config. In order to satisfy (2) I'll need to modify said config so that I can use the webroot Let's Encrypt authentication method.
I'm trying to figure out the optimal solution that will satisfy both requirements. I've come up with the following, which works.
Before:
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
After:
server {
listen 80;
server_name example.com;
location ~ /\.well-known\/acme-challenge {
root /usr/share/nginx/html;
allow all;
}
if ($request_uri !~ /\.well-known) {
return 301 https://example.com$request_uri;
}
}
However, I was hoping to figure out another way of doing it. The reasons for that are:
if is evil. Might not be such a big deal in this case because this is just the http->https redirect, which should be very low-traffic.
More importantly, avoiding the
if
would make it easier to bolt on webroot authentication to all of my sites running behindnginx
since I could just plop thatlocation
directive in a.conf
that I could then include willy-nilly inside all of my little http->https redirect blocks.
In this question, Alex gives an example using a bare return
statement, but that doesn't work for me (nginx -t
complains with nginx: [emerg] invalid number of arguments in "return" directive in /etc/nginx/...
).
Is there a better way of doing this? Or is my solution above as good as it gets?
You can replace the if
with a normal location:
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge {
root /usr/share/nginx/html;
allow all;
}
location / {
return 301 https://example.com$request_uri;
}
}
Reason: the location with the longest matching prefix is selected and remembered.
To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.
Source: Nginx Docs