ngnix www to no-www on config file generated by certbot - nginx

I am trying to get requests to example.com as well as www.example.com to go to https://example.com in the configuration file shown below. The file is exactly as generated by certbot.
Changing the two return 301 statements to
return 301 https://example.com$request_uri;
did not work as https://www.example.com still goes to https://www.example.com and not the desired https://example.com
Would appreciate if someone could point out the exact changes needed to get the desired result. Simplified instructions would be a bonus as I am quite new to both nginx and certbot. Thanks.
server {
root /var/www/html/drupal;
index index.php index.html index.htm;
server_name example.com www.example.com;
location / {
try_files $uri /index.php?$query_string;
}
location #rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
location ~ [^/]\.php(/|$) {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ ^/sites/.*/files/styles/ {
try_files $uri #rewrite;
}
location ~ ^(/[a-z\-]+)?/system/files/ {
try_files $uri /index.php?$query_string;
}
listen [::]:443 ssl; # 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://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}

Open the brackets for a clearer way.
Instead of one 443 listener, create 2. Same with the 80 ones.
Like that it's much easier for you to know what is doing what, one configuration for each pair of host and schema.
server {
listen 80;
listen [::]:80;
server_name www.example.com; #this will only listen to http://www.example.com
location / {
return 301 https://example.com$request_uri; #and will upgrade to https
}
#we don't want that many redirects, so this will go directly to example.com
}
server {
listen 80;
listen [::]:80;
server_name example.com; #this will only listen to http://example.com
location / {
return 301 https://$host$request_uri; #and will upgrade to https
}
}
server {
server_name www.example.com;
location / {
return 301 https://example.com$request_uri #this redirects to non-www
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server{
#same server configuration as your first server bracket, only accepting https://example.com and not www.
}
I see that you are sending the arriving connection to a Drupal so think that the Drupal has a variable $base_url that any redirect that it makes it's made to that host, so if it's set to www.example.com, it won't matter you nginx conf, as Drupal itself can also make redirects.
Hope it helped, comment for any question.

Its working now, #flaixman. I made one change from your suggestion - which was to make just one block for 80, since they both did exactly the same thing. So, here's the final version : (I have hopefully not messed up something which might cause a problem later.)
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location / {
return 301 https://example.com$request_uri;
}
}
server {
server_name www.example.com;
location / {
return 301 https://example.com$request_uri;
}
listen [::]:443 ssl; # 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{
root /var/www/html/d8;
index index.php index.html index.htm;
server_name example.com;
location / {
try_files $uri /index.php?$query_string;
}
location #rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
location ~ [^/]\.php(/|$) {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ ^/sites/.*/files/styles/ {
try_files $uri #rewrite;
}
location ~ ^(/[a-z\-]+)?/system/files/ {
try_files $uri /index.php?$query_string;
}
listen [::]:443 ssl; # 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
}

Related

How to accept request with port after domain in nginx

I have a subdomain https://test.shop.com, I'm running a Nginx server and it's working fine. But I have to accept the request with https://test.shop.com:8080/graphql/ and redirect to http://127.0.0.1:8000 to the same machine. I've added this block
location /graphql/ {
proxy_pass http://127.0.0.1:8000;
}
But when I try to access https://test.shop.com:8080/graphql/ from the browser it shows me This site can’t be reached seems something to do with dns. Although I can access https://test.shop.com/graphql/ and it works fine.
My whole config file is
server {
server_name test.shop.com;
root /var/www/html/test;
index index.html;
location / {
try_files $uri $uri/ /index.html?$args;
}
# dashboard app
location /dashboard/ {
try_files $uri $uri/ /dashboard/index.html?$args;
}
location /graphql/ {
proxy_pass http://127.0.0.1:8000;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/test.shop.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/test.shop.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 = test.shop.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name test.shop.com;
return 404; # managed by Certbot
}
You must create new virtualhost and listen that virtualhost to port 8080.
server {
listen 8080 ssl;
server_name test.shop.com;
root /var/www/html/test;
index index.html;
location /graphql/ {
proxy_pass http://127.0.0.1:8000;
}
ssl_certificate /etc/letsencrypt/live/test.shop.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/test.shop.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
}

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)

Nginx redirect to non-www not working for laravel application

I have my Laravel app configured on Ubuntu 16.04.6 x64 with nginx and I keep getting a 404 page when I try to load the site with the “www” prefix
It all works perfect at https://example.com, but https://www.example.com will cause a 404 error
I have A records setup for both the www.example.com and example.com pointing to the same IP address
Ideally I would like to redirect all https://www.example.com traffic to https://example.com
The nginx conf file is below, would appreciate some help debugging
I’ve tried adding a 301 redirect at the start and end of the file but it doesn’t seem to work
Interestingly I can access static files fine at www, it’s any of the laravel paths that seem to trigger a 404
server {
root /var/www/example.com/web/public;
error_log /var/www/example.com/errors.log;
access_log /var/log/nginx/example.comaccess_log.log;
index index.php index.html;
server_name example.com www.example.com;
client_max_body_size 80m;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
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.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name example.com www.example.com;
listen 80;
return 404; # managed by Certbot
}
server {
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
Something to this effect should do it. If you go to http://www.example.com, you should be redirected to https://www.example.com, which intern redirects to https://example.com.
server {
root /var/www/example.com/web/public;
error_log /var/www/example.com/errors.log;
access_log /var/log/nginx/example.comaccess_log.log;
index index.php index.html;
server_name example.com;
client_max_body_size 80m;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
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 {
# Force all HTTP traffic to SSL
listen 80;
return 301 https://$host$request_uri;
}
server {
# Redirect www.example.com to example.com
listen 443 ssl;
# This needs to be the cert for www.example.com or *.example.com
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Remember, if nginx doesnt find the server_name, it uses the first vhost.
server_name www.example.com;
return 301 https://example.com$request_uri;
}

NGINX redirecting non secure subdomain to main domain

I have 2 domain hosted on the same server let's say testwebsite.com and staging.testwebsite.com. I have added the nginx configuration in which there is one problem subdomain is getting redirected to main domain only on non secure protocol.
http://testwebsite.com -> https://testwebsite.com = OK
https://testwebsite.com -> https://testwebsite.com = OK
http://staging.testwebsite.com -> https://testwebsite.com = NOT OK
https://staging.testwebsite.com -> https://staging.testwebsite.com = OK
testwebsite.com
server {
root /var/www/testwebsite.com/live;
index index.html index.php index.htm index.nginx-debian.html;
server_name testwebsite.com www.testwebsite.com;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/testwebsite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/testwebsite.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 {
listen 80;
listen [::]:80;
server_name testwebsite.com www.testwebsite.com;
return 301 https://testwebsite.com$request_uri;
}
staging.testwebiste.com
server {
root /var/www/testwebsite.com/staging;
index index.html index.php index.htm index.nginx-debian.html;
server_name staging.testwebsite.com www.staging.testwebsite.com;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/staging.testwebsite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/staging.testwebsite.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 {
listen 80;
listen [::]:80;
server_name staging.testwebsite.com www.staging.testwebsite.com;
return 301 https://staging.testwebsite.com$request_uri;
}
Can anyone please help what went wrong with the config?
The config looks OK to me.
Are you sure that it is not your browser caching the redirect? Browsers tend to cache 301 redirects very aggressively.

Resources