I have a simple webserver using nginx as a reverse proxy, with config file as follows:
server {
server_name outsidetheasylum.blog www.outsidetheasylum.blog;
location / {
proxy_pass http://localhost:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/outsidetheasylum.blog/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/outsidetheasylum.blog/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.outsidetheasylum.blog) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = outsidetheasylum.blog) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name outsidetheasylum.blog www.outsidetheasylum.blog;
return 404; # managed by Certbot
}
I want all traffic to the www subdomain to be 301 redirected to the main domain. e.g. www.outsidetheasylum.blog/foo should go to outsidetheasylum.blog/foo. I tried modifying the nginx config file in a few different ways to do this, but they all seemed to break the SSL certification, making the site show "not secure" in the browser. I attempted to reinstall the certificate, but got various errors from certbot not recognizing the new file layout. For example:
Problem in /etc/nginx/sites-enabled/outsidetheasylum.blog: tried to insert directive "[['if', '($host', '=', 'www.outsidetheasylum.blog)'], [['return', '301', 'https://$host$request_uri']]]" but found conflicting "[['if', '($host', '=', 'www.outsidetheasylum.blog)'], [['return', '301', 'https://outsidetheasylum.blog$request_uri']]]".
What's the correct way to set up this redirect that won't interfere with certbot's functioning?
IMHO the best way to handle nginx is the following:
run Certbot in standalone mode, configured with --http-01-port=8080 or something similar.
create a proxypass directive in nginx to route all traffic to /.well-known/acme-challenge/ to the port Certbot runs on. If you do this in as a macro file, you can just include it on every server block.
The result of this type of integration is the following:
Certbot doesn't touch or care about nginx
LetsEncrypt will contact your site on port 80, your site handles the proxypass to 8080, which is an ephemeral server that is part of the Certbot process
@jvanasco I think the webroot plugin is more lean than using Certbot in standalone and a proxy pass. IMO it complicates things unnecessarily. Using a location directive for /.well-known/acme-challenge/ in the HTTP block as suggested by Rudy and a specific root directive and point Certbots webroot path to that same destination should work flawlessly and wouldn't make Certbot mess with the nginx configuration.
Just do what @9peppe said and add below in your server block for port 443.
if ($host = www.outsidetheasylum.blog) {
return 301 https://outsidetheasylum.blog$request_uri;
}
You can continue to use the Certbot --nginx plugin as you have been. It will create a temp response in your port 80 server block for the challenge and the above "if" statement in your port 443 server block is not involved in the cert challenge.
I think we can agree that both options work well and are much better than letting Certbot manage the server block by the nginx or apache plugin.
Also, both options can be used server-wide with a single macro file that is included into each configuration block (or file).
In terms of webroot vs proxypass, it comes down to preference and experience. With nginx, I personally think proxypass is better for a few reasons:
It can be easier to initially setup and debug, as it does not require coordinating permissions for read/write of the Certbot and Apache/Nginx processes. All you need to do is ensure the proxypass works correctly once (which is similar to webroot, but the nature of the proxypass means different locations must all use the same configuration, while webroots can be varied on a single install).
There are no files written to the server to cleanup or confuse on a debugging/inspection, and you eliminate an issue where different block define different locations (happens often!) so troubleshooting is overly complicated. The Certbot process that runs the ACME protocol handles everything. Because this is handled by the server process, and cerbot binds to the higher port, you're also effectively blocked from accidentally running two processes at once. It's just harder to mess up in many ways.
There are a few other reasons why I think standalone is superior to webroot on Nginx, but those are the top ones.
MikeMcQ's solution worked perfectly for me, thank you.
I dislike copy-pasting code that I don't understand, so by any chance does anyone have a link to a good technical introduction to this sort of thing? All the existing resources I could find either assume a lot of prior knowledge that I don't have or are insufficiently technical to allow me to actually implement what I'm trying to do.