Nginx wont redirect to www - nginx

Hello I have hard times to configure nginx properly. I would like redirect from https://example.com to https://www.example.com I found a lot of tutorials how to do it but not a single one worked with mine configuration files.
I used letsencrpyt to configure the SSL for me.
Here is the nginx conf file:
server {
server_name IP_ADDRESS example.com www.example.com;
location /static/ {
root /home/user/pyapps/ks_g;
}
location /media/ {
root /home/user/pyapps/ks_g;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.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
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name IP_ADDRESS example.com www.example.com;
return 404; # managed by Certbot
}

Add redirect on condition to the server block with SSL or both:
if ($host != www.example.com) {
return 301 https://www.example.com$request_uri;
} # managed by Stack Overflow (sorry cannot hold myself)
This works as the following: if the Host HTTP header not equals www.example.com make permanent redirect to https://www.example.com$request_uri.

Related

Block request that is not coming through the load balancer (Fixed)

I have a two servers that serve the same static content behind an Nginx load balancer
`
upstream backend {
server xxx.xxx.xxx.xx;
server xxx.xxx.xxx.xx;
}
server {
server_name example.com www.example.com;
location / {
proxy_pass http://backend;
}
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
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host !~* ^(www\.)?example.com$) {
return 444;
}
listen 80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
`
So far I have blocked access to the load balancer from the IP and I want to do the same for the servers I want only the requests that goes through the load balancer to be accpted by both backend servers.
servers have same configuration here is how it looks:
`
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/access.log;
}
`
FIXED:
I created a special header that the load balancer adds to the request and if it is not included the server will close the connection.

Nginx doesn't serve subdomain

I thought this would be simple, but for some reason I can't get my subdomain to serve. I am just trying to get the basic "Welcome to Nginx" page to show at this point.
I have A records in digital ocean:
A api.example.com -> my_ip 3600
A www.api.example.com -> my_ip 3600
A example.com -> my_ip 3600
A www.example.com -> my_ip 3600
This is my config file for api.example.com. It sits in /etc/nginx/sites-available/api.example.com and is linked to /sites-enabled:
server {
root /var/www/api.example.com/html;
index index.html index.htm index.nginx-debian.html;
server_name api.example.com www.api.example.com;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/api.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
}
server {
if ($host = www.api.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = api.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name api.example.com www.api.example.com;
return 404; # managed by Certbot
}
I know the DNS record exists using Dig and because certbot ran successfully, but when I navigate to the page it is unable to resolve. Ping and curl also cannot resolve. This is the exact same configuration I have for the main domain (example.com), which does display the Nginx splash page.
What I have tried: I noticed that default has configs for example.com but not for api.example.com (why is that?), so I tried creating them and restarting nginx, but that didn't change anything. Is it necessary to have the configs in default?

nginx page not found error after certbot installation

I have a http website (with Flask and nginx) which is up and running. I'm trying to install ssl with certbot and following their steps leads to a successful installation message (congratulations...) but refreshing my webpage leads to 404 Not Found nginx/1.18.0 (Ubuntu).
This is the nginx.conf file after sudo certbot --nginx
server {
server_name www.mydomain.com;
location /static {
alias /home/ubuntu/adviser/flaskblog/static;
}
location / {
proxy_pass http://localhost:8000;
include /etc/nginx/proxy_params;
proxy_redirect off;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.mydomain.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.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.mydomain.com;
return 404; # managed by Certbot
}
any help is really appreciated.
First, just remove this line:
return 404; # managed by Certbot
which causes 404 error to be returned.
If it doesn't help, change whole this block:
server {
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.mydomain.com;
return 404; # managed by Certbot
}
to this:
server {
listen 80;
server_name www.mydomain.com;
return 301 https://$host$request_uri;
}
UPDATE
Also, you can try to change
return 301 https://$host$request_uri;
to
return 301 https://www.yourdomain.com$request_uri;
(I had to replace mydomain with yourdomain due to some strange StackOverflow restrictions.)
I finally figured out what is the problem.
I was creating certificate for www.mydomain.com, but in reality I my domain was set to mydomain.com (no www). I was redirecting to www but either I was doing it wrong or certbot does not like redirects of that nature.
Long story short, I (re)issued certificate for mydomain.com and certificate worked like a charm!

Nginx redirect all traffic to HTTPS and non-www

have what I thought was a simple issue but cannot figure it out. My goal is to have HTTPS non-www.
NON-HTTPS traffic is being redirected properly, but the last one I cannot figure out is to redirect HTTPS www traffic to HTTPS non-www.
Working:
http://example.com -> https://example.com
http://www.example.com -> https://example.com
https://example.com (no redirect needed)
Not Working:
https://www.example.com -> https://example.com (not working)
server {
root /var/www/example.com/;
index index.php index.html index.htm;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
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
}
server {
if ($host = www.example.com) {
return 301 https://example.com$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://example.com$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
So I was missing the if statement in the SSL server block
Added:
if ($host = www.example.com) {
return 301 https://example.com$request_uri;
} # managed by Certbot

Is this redirect non-www domain to www domain in nginx actually works?

I have the following nginx server block for my domain name example.com. I want to redirect non www to www for the SEO.
Update
According to this answer I used the following server block. But when I test it, I got the following
nginx: [warn] conflicting server name "www.example.com" on 0.0.0.0:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
So, I have the doubt is it correct or not and Whether it actually redirects the non www to www, please.
/etc/nginx/sites-available/example.com
server {
server_name www.example.com;
rewrite ^(.*) https://www.example.com$1 permanent;
}
server {
root /var/www/abc-company-website/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
#Cache-Control
location ~* \.(?:ico|ttf|png|svg|jpg|jpeg|js)$
{
expires 7d;
add_header Pragma public;
add_header Cache-Control "public";
}
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
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
How can I change the above server block to redirect, please?
It's in the best practices of nginx not to use if (even more of a reason if you are using it for $host), it's better to use server brackets with different server_name.
server {
listen 80;
server_name example.org www.example.org;
return 301 https://www.example.org$request_uri;
}
This will send HTTP www and HTTP non-www to HTTPS www
If you have a cert for non-www set a server bracket and redirect to www:
server{
listen 443 ssl;
server_name example.com;
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
return 301 https://www.example.com$request_uri;
}
And finally you can do whatever you want in the https www.example.com bracket:
server {
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
server_name www.example.com;
# Do whatever you want to do here to get to your application
}
It's better to read the documentation and best practices of nginx, and try to make clean configurations so the next one that comes can understand it on first sight :D
If you've got any question just ask it. (looks like you didn't understand the duplicates given in the comments, so I decided to explain it 1 by 1 for your case)

Resources