Nginx + certbot - redirect https www to https

Hello. I'm having a problem with the redirection of my domain.

I've sucessfully redirected http-www and http to https but nothing seems to work in case of https-www to https redirection. Below is my nginx config.

server {
        server_name domain.com www.domain.com;   

	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; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain.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.domain.com) {
        return 301 https://domain.com$request_uri;
    } # managed by Certbot

    if ($host = domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name domain.com www.domain.com;
    listen 80;
    return 404; # managed by Certbot
}

I've tried creating additional server blocks etc. but i can't make it working.

Thank you in advance!

Hello @xBaSic,

Just remove www.domain.com from the server block and create a new one and then redirect to https://domain.com from that server block.

Like this:

server {
    server_name www.domain.com;   
    return 301 https://domain.com$request_uri;
    listen 443 ssl; 
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
        server_name domain.com;   

	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; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain.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.domain.com) {
        return 301 https://domain.com$request_uri;
    } # managed by Certbot

    if ($host = domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name domain.com www.domain.com;
    listen 80;
    return 404; # managed by Certbot
} 

Cheers,
sahsanu

Hey I implemented the changes and now addres http://www.example.com/ is not working.

What means "is not working"?

Could you please share your real domain so we can test it?

Cheers,
sahsanu

Sure it's prawnyregulamin.pl

I've tested exactly the same conf I pasted above in my server and it is working fine so seems there is another conf file in your nginx serving your domain.

Please, show the output of this command:

grep -ri prawnyregulamin.pl /etc/nginx/*

Looks great from here!

I’ve got a 404 unless I access it via https - but I can access it fine. Is there a load balancer in place here?

curl -Iki prawnyregulamin.pl

HTTP/1.1 404 Not Found
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 15 Jan 2021 02:56:37 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Vary: Accept-Encoding

So I am getting a 404 with curl without a protocol declaration....

rip:T430 ~ >> curl -Iki https://prawnyregulamin.pl
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 15 Jan 2021 02:57:15 GMT
Content-Type: text/html
Connection: keep-alive
Vary: Accept-Encoding

But the https is returning the correct response.
Hope this helps
Works ok in firefox from my location though.
@sahsanu... does this help?

@Rip, yes, the http part is the problematic one, https is working fine. It is like nginx is ignoring the ifs in this server block:

server {
    if ($host = www.domain.com) {
        return 301 https://domain.com$request_uri;
    } # managed by Certbot

    if ($host = domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name domain.com www.domain.com;
    listen 80;
    return 404; # managed by Certbot
} 

but I tested this conf in my server and all is working fine, redirections are being done, so or there is a typo in the server block or there is another server block taking precedence.

@xBaSic, to know whether nginx is using that server block you can replace:

return 404; # managed by Certbot

by

return 405; # managed by Certbot

and reload nginx systemctl reload nginx so if we get a 405 error instead of 404 we will know that nginx is using the server block and ifs are not working.

Cheers,
sahsanu

Ok, i've changed from 404 to 405.

@xBaSic, ok, I get the 405 code so for whatever reason I don't know nginx is ignoring the if part, so to do it easy just change this:

server {
    if ($host = www.domain.com) {
        return 301 https://domain.com$request_uri;
    } # managed by Certbot

    if ($host = domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name domain.com www.domain.com;
    listen 80;
    return 405; # managed by Certbot
}

to this

server {
    server_name domain.com www.domain.com;
    listen 80;
    return 301 https://domain.com$request_uri;
}

Restart or reload nginx and we will try again.

Cheers,
sahsanu

Ok, i've done the changes.

Perfect, from my side all is working fine now.

Yup. It looks like it's working fine now... Thank you very much... i've been trying to fix this for ages before i created this thread. I was trying all kind of redirections with no succeess.