Nginx: Redirecting server names in one paragraph - nginx

I using the Nginx configuration below and it works fine.
However, I'm using three paragraphs {...} for redirections, can this be optimized to a single paragraph or set directly in the main paragraph ?
upstream mywebsite_upstream {
server 127.0.0.1:3003;
keepalive 64;
}
server {
server_name www.mywebsite.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://mywebsite_upstream;
proxy_redirect off;
proxy_read_timeout 240s;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.mywebsite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.mywebsite.com/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.mywebsite.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.mywebsite.com;
return 404; # managed by Certbot
}
server {
listen 80;
server_name mywebsite.com;
return 301 https://www.mywebsite.com;
}
server {
listen 443;
server_name mywebsite.com;
return 301 https://www.mywebsite.com;
}

Yes, sure you can:
server {
listen 80;
server_name mywebsite.com www.mywebsite.com;
return 301 https://www.mywebsite.com$request_uri;
}
server {
listen 443;
server_name mywebsite.com;
# SSL config here
return 301 https://www.mywebsite.com$request_uri;
}
I think you'll need to copy all SSL-related configuration from your main server block to the second one.
I think (and I'm not alone, check an answer under the link) that nginx config produced by certbot is a crap and it is better to do nginx config changes manually a leave for certbot only a certificate receiving/renewing:
certbot certonly --webroot -w /var/www -d hostname -d hostname ...
Update
When your server hosts other domains (and even if ins't) it is a good practice to have an additional server block serving requests than does not contain a valid domain name (or does not have Host HTTP header at all - those are typically port scanners, vulnerability searchers etc.) To close suspicious connections on port 443 you'll need minimal SSL config within that block. It's best to use a self-signed key and certificate for that purpose. For generating a pair of self-signed key/cart in one line you can use the following command:
openssl req -nodes -new -x509 -subj "/CN=localhost" -keyout /etc/nginx/server.key -out /etc/nginx/server.crt
You can use special nginx 444 code (close connection without any response) for the suspicious connections:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
return 444;
}
To simplify certbot key renewing process with the command like given above, you can add an additional section to all your server blocks for hosted domains (including that ones used for redirection too):
location /.well-known/acme-challenge/ {
root /var/www;
}

Related

NGINX reverse proxy relative links, issue with routed location

So I have 2 docker containers running different Flask apps, port forwarded to the host. The host has a NGINX server redirecting requests to the server to the respective containers. The "sites available" file for the NGINX server is as shown:
server {
root /var/www/myserver/html;
index index.html index.htm index.nginx-debian.html;
# Don't forget to include .com below!
server_name myserver.com www.myserver.com;
location / {
proxy_pass http://127.0.0.1:6789/;
} # Here, we reverse proxy the port 80 to port 6789, where the website is served by Docker
location /smallblog/ {
rewrite ^/smallblog/(.*) /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://127.0.0.1:8000/;
proxy_pass_request_headers on;
} # Here, we reverse proxy the port 80 with /smallblog route to port 8000, where the smallblog is also served by another Docker container
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/myserver.com/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.myserver.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = myserver.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name myserver.com www.myserver.com;
return 404; # managed by Certbot
}
With this configuration, accessing www.myserver.com/smallblog indeed gives the right page. But, all links inside that page point to the myserver.com, for example a link to login page is www.myserver.com/login instead of www.myserver.com/smallblog/login. And all internal relative links (e.g. javascript links) don't work. Is there a way to solve this?
Buit if I use the / location in the script above to serve smallblog instead, this issue doesn't exist. So I figure there must be a way I don't see.

404 Error only on when requesting WWW domain?

I have a nodejs server running with nginx as a reverse proxy. https://example.com and http://example.com run correctly with http://example.com redirecting to https, but http://www.example.com gives an nginx error 404 Not Found. https://www.example.com does work, though.
This is my server block configuration:
server {
root /var/www/partyshare.shop/html;
index index.html index.htm index.nginx-debian.html;
server_name partyshare.shop www.partyshare.shop;
location / {
proxy_pass http://localhost:3000;
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/partyshare.shop/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/partyshare.shop/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 = partyshare.shop) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name partyshare.shop www.partyshare.shop;
return 404; # managed by Certbot
I believe the error is on the second server block, where $host = www.partyshare.shop when requesting the http version, so it skips past the redirect and returns a 404 error. I tried adding an if statement for the www version, but it errored out, and wouldn't recognize my SSL certificate as the http was crossed out in red, so if anybody could help that would be great.
You should update the 2nd server block to do the same for both partyshare.shop and www.partyshare.shop, and not just partyshare.shop.
server {
listen 80;
listen [::]:80;
server_name partyshare.shop www.partyshare.shop;
return 301 https://$host$request_uri;
}

404 error on http - let's encrypt certbot , everything fine with https

I'm using certbot to generate a let's encrypt certificate, everything work fine except the http version is not redirected to the https.
Here is my .conf in sites-available :
# the IP(s) on which your node server is running. I chose port 3000.
upstream app_yourdomain {
server 127.0.0.1:3000;
keepalive 8;
}
# the nginx server instance
server {
server_name deussearch.fr www.deussearch.fr;
access_log /var/log/nginx/deussearch.fr.log;
# pass the request to the node.js server with the correct headers
# and much more can be added, see nginx config options
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_Host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://app_yourdomain/;
proxy_redirect off;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.deussearch.fr/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.deussearch.fr/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.deussearch.fr) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name deussearch.fr www.deussearch.fr;
return 404; # managed by Certbot
}
I really can't find what's wrong here, like I followed tutorial and everything worked fine , anyone know ? I'm using Nginx on ubuntu if it can help !
I have check your website it's OK. Every I try access http://deussearch.fr/ always redirect to https://www.deussearch.fr/
https://i.imgur.com/H7c9dXY.png
You can also check in https://www.sslshopper.com/ssl-checker.html#hostname=deussearch.fr

How to fix nginx default configuration after installing an let's encrypt SSL on digital ocean with Ubuntu 18.04?

I had my website running but SSL was only working on non-www. After I reinstalled the let's encrypt SSL certificate the site crashed. I was able to make the front run but not the api.
I moved the site to a new droplet and installed Nginx, Pm2, and certbot with python on Ubuntu 18.04 with Nodejs.
The site is not loading and it is a bit frustrating. I think the issue was that certbot rewrited the ngix default file and I am not sure how to fix it.
This is the configuration I have on /etc/nginx/sites-available/default
upstream my_app {
server 127.0.0.1:3000;
}
server {
#listen 80;
listen [::]:80;
#listen 443 ssl;
#listen [::]:443 ssl;
if ($host = www.mysite.com) {
return 301 https://mysitehere$request_uri;
}
server_name roomies.es;
listen 443 ssl;
ssl on;
ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem;
if ($ssl_protocol = "") {
rewrite ^ https://$server_name$request_uri? permanent;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://mysite_app;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ~ /.well-known {
allow all;
}
}
```
I need the front to run on port 3000 and my api on port 4000.
Thanks in advance!
This is how I had to set up my NGINX configs after installing Let's Encrypt:
/etc/nginx/sites-enabled/default (which should be the same file as /etc/nginx/sites-available/default):
# Default server configuration
server {
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name example.com;
return 301 https://www.example.com$request_uri;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/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
}
To be clear, the return 301 is to ensure all non-www traffic is moved to the www version of the URL.
Remember to save your config on a notepad or something so you can quickly revert back to the original if this doesn't work.

Nginx, Https, reverse proxy, handshake error. Need review of 'nginx/sites-enabled/default' file.

I am hoping for a review of some code below -- it is the 'nginx/sites-enabled/default' file. I believe it may have some obvious gotchas which are preventing my site from redirecting under https. I have spent a few days reviewing the Nginx documentation but have not been able to get a handle on my problem. Thanks for your help!
Context:
I am trying to set up a reverse proxy that points my domain url to localhost:3000 on my Digital Ocean server. Everything seems to be working well except for the fact my https is not resolving. I have generally followed these two tutorials: https://code.lengstorf.com/deploy-nodejs-ssl-digitalocean/ and https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04 .
When I go to my url I get: "ERR_CONNECTION_RESET". When I run curl on my server for http://localhost:3000, my html is returned as expected. When I run curl on my server for https://mysite.io I receive the error: "curl (35) gnutls_handshake() failed: Error in the pull function". All my http curl requests are redirecting properly to https, dig +short mysite.io is pointing to my server, nginx -t is coming back with no errors.
My hunch is the problem is with my 'nginx/sites-enabled/default' file, more specifically the server blocks that are handling https. The first two server blocks are from the first tutorial, the second two were automatically generated by Certbot in the second tutorial mentioned above. Thanks again for your help!
# HTTP — redirect all traffic to HTTPS
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
# HTTPS — proxy all requests to the Node app
server {
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mysite.io;
# Use the Let’s Encrypt certificates
ssl_certificate /etc/letsencrypt/live/mysite.io/fullchain.pem; # managed $
ssl_certificate_key /etc/letsencrypt/live/mysite.io/privkey.pem; # manage$
# Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
server {
return 301 https://$host$request_uri;
server_name www.mysite.io; # managed by Certbot
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mysite.io/fullchain.pem; # managed $
ssl_certificate_key /etc/letsencrypt/live/mysite.io/privkey.pem; # manage$
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.mysite.io) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80 ;
server_name www.mysite.io;
return 404; # managed by Certbot
}
The first two blocks are unnecessary and can be removed. Then, we can take the location block from the second server block and add it to the third server block. And then, finally we can remove the 301 from the third block, ending up with this:
server {
server_name www.mysite.io; # managed by Certbot
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
# change the above line to "listen 443 ssl http2" if you want http2
ssl_certificate /etc/letsencrypt/live/mysite.io/fullchain.pem; # managed $
ssl_certificate_key /etc/letsencrypt/live/mysite.io/privkey.pem; # manage$
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.mysite.io) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80 ;
server_name www.mysite.io;
return 404; # managed by Certbot
}

Resources