1

I want to 301 redirect all non-https and non-www to https://www.example.com using the following configuration I found in another thread as the accepted answer. But it's not working for me.

What works:

  • https://example.com -> https://www.example.com

  • http://example.com -> https://www.example.com

BUT...

  • http://www.example.com -> TOO MANY REDIRECTS... using curl I can see that this always redirects to itself...

Here is my nginx.conf:

server {

    # ports
    listen 80;
    listen [::]:80;

    # domain name
    server_name example.com www.example.com;

    # Redirect all non-https requests
    rewrite ^ https://www.example.com$request_uri? permanent;
}

server {

    if ($bad_referer) {
        return 444;
    }

    if ($bad_bot) {
        return 444;
    }

    # ports
    listen [::]:443 ssl http2;
    listen 443 ssl http2;

    # domain name
    server_name example.com www.example.com;

    if ($host = 'example.com') {
      return 301 https://www.example.com$request_uri;
    }

    # ssl certificate files
    ssl_certificate /etc/ssl/certs/domain.crt;
    ssl_certificate_key /etc/ssl/private/domain.key;

    include basic.conf;
}

Any ideas?

Update: It's getting even weirder...i've tried to make a general rule to route everything to ssl (as suggested on many blogs)...now www as well as non-www version are redirecting back to itself...

server {

    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    return 301 https://$host$request_uri;
}

I have no idea how to debug this...btw...this is a docker swarm cluster...if this helps...

1

After testing this myself, I had to edit my original answer because it led to a conflicting server name error.

Sadly I cannot tell you why you still get this redirect loop - maybe the error comes from your include. But I can present you with a working (tested) configuration that accomplishes what you were asking for:

Generally: For rather simple redirecting it is recommended to use the return directive instead of redirect (https://www.nginx.com/blog/creating-nginx-rewrite-rules/)

Goal: Whatever combination

  • of scheme (http or https)
  • and domain (example.com or www.example.com)

you type into the browser, you will get redirected to https://www.example.com

Heres the configuration:

server {

listen 80;

server_name www.example.com redirecttest.de;

return 301 https://www.example.com$request_uri;

}

server {

listen 443 ssl http2;

server_name www.example.com;

root /var/www/example.com/http;

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

}
  • Ok, so i took your code and did the same for www.example.com and added if ($scheme = 'http') { return 301 https://www.example.com$request_uri; } but nothing changed...requesting http://www.example.com leads to an redirect-loop to itself... – Lars Dittrich Nov 15 '18 at 15:05
  • @LarsDittrich In my opinion you don't need that "if/else". If you have a look at my serverblock you will notice the following: No matter what 'scheme' (say: https or http) the user enters in it's browser you will be redirected to https anyways: return 301 'example.com$request_uri;' – geets Nov 15 '18 at 15:42
  • I cannot edit my comment anymore: The point is you will get redirected to https anyways, no matter what you initially typed into the browser – geets Nov 15 '18 at 15:50
  • ...but thats not the case...browser says "too many redirects" and curl does that too...but only for the http-www ...any other combination is working... – Lars Dittrich Nov 15 '18 at 15:57
  • I tested what I was proposing first and updated my answer. Please notice, that there is no need for an if-statement to get the redirecting done! – geets Nov 15 '18 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.