38

I'm setting up an nginx server with an SSL.

The domain with the ssl is www.mydomain.com

I want to redirect all requests from:

http://mydomain.com, http://www.mydomain.com, & https://mydomain.com to

https://www.mydomain.com

I have the following server blocks setup currently:

server{
  listen 443 ssl;
  root /www/mydomain.com/;

  ssl_certificate /ssl/domain.crt;
  ssl_certificate /ssl/domain.key;
  .
  . 
  .
}

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

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

server{
  listen ssl 443;
  server_name mydomain.com;
  return 301 https://www.mydomain.com$request_uri;
}

This currently does not work, but I don't understand why not. I can get a combination of either http -> https working or no-www to -> www working, but mixing them as above does not work.

on3al
  • 2,030
  • 4
  • 19
  • 19

6 Answers6

18

The ssl redirect won't work if your ssl certificate doesn't support the non-www domain. The config is correct but can be reduced to just 1 redirect server

Also don't forget to reload nginx sudo service nginx reload

server {
  listen 80;
  listen 443 ssl;
  server_name example.com;
  # add ssl settings
  return 301 https://www.example.com$request_uri;
}
Mohammad AbuShady
  • 38,096
  • 10
  • 75
  • 89
  • 1
    This is exactly what I wanted and am using it the other way around. Thank you! – Danijel-James W Jan 30 '14 at 02:31
  • You'll need a separate server with server name `www.domain.com` and liatens to port 80 to do that aditional redirect if you need it. – Mohammad AbuShady Aug 19 '14 at 14:32
  • 3
    This gives me - `nginx: [emerg] invalid parameter "443" in /etc/nginx/nginx.conf:96` – sarat Oct 18 '14 at 11:27
  • could u paste that line '96', also your nginx version – Mohammad AbuShady Oct 18 '14 at 11:44
  • This is also giving me `nginx: [emerg] invalid parameter "443"` - Something must have changed. Using nginx 1.6.2 – Berto Oct 21 '14 at 18:27
  • 4
    I just tested it on that version, it gave me the same too, you can split it into two listen lines `listen 80;` and `listen 443;` – Mohammad AbuShady Oct 21 '14 at 21:35
  • could someone explain why you need a working certificate for the none-www domain, since, this is a plaine redirection that leads to a new request with the www.domain ? – haemse Oct 31 '17 at 22:22
  • @haemse because what the browser does ( roughly ) is it creates a connection to the non www domain ( the url you requested ), gets the certificate and validates it, then if things are ok it would ask for the response ( the redirect ), so you get the certificate failure before getting the redirect response. – Mohammad AbuShady Nov 01 '17 at 10:08
  • @MohammadAbuShady: Ok, so in short, without the cert, it does not even build up a connection ... – haemse Nov 01 '17 at 15:44
  • @haemse yea, you'll get the invalid certificate error from the browser – Mohammad AbuShady Nov 01 '17 at 19:38
13

I am late, But you can do like this

server{
  listen 443 ssl;
  server_name www.mydomain.com;
  root /www/mydomain.com/;

  ssl    on;
  ssl_certificate /ssl/domain.crt;
  ssl_certificate /ssl/domain.key;
  .
  . 
  .
}

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

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

Or you can replace return 301 https://www.$server_name$request_uri; with rewrite ^ http://www.$server_name$request_uri? permanent;, both will work.

You also need to set this in google webmaster for better SEO.

Suneel Kumar
  • 5,213
  • 3
  • 30
  • 41
1

this works for me for http to https redirection,

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name example.com;

    #For HTTP to HTTPS:

    proxy_set_header X-Forwarded-Proto $scheme;
    if ( $http_x_forwarded_proto != 'https' ) 
    {
        return 301 https://$host$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php;
        add_header 'Access-Control-Allow-Origin' '*';
    }
    
    location ~ \.php$ {
        include fastcgi.conf;   
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
    }

    
    location ~ /\.ht {
        deny all;
    }
}

thanks.

Sushil
  • 1,968
  • 21
  • 24
0
#If you like to redirect all "http" to "https" then add the following:
server {
        listen 80;

        server_name yourdomain.com;
        server_name www.yourdomain.com;

 if ($scheme = "http")
        {
                rewrite ^(.*)$ https://yourdomain.com$1 permanent;
        }
}
Ranch Camal
  • 445
  • 1
  • 4
  • 10
0

Use a rewrite to send all HTTP traffic to HTTPS:

server {
 listen 80 default_server;
 listen [::]:80 default_server;
 server_name _;
 return 301 https://$host$request_uri;
}

This configuration listens on port 80 as the default server for both IPv4 and IPv6 and for any hostname. The return statement returns a 301 permanent redirect to the HTTPS server at the same host and request URI.

rjhcnf
  • 341
  • 2
  • 7
0
Please add two given things on your file.

Given code paste on top side 
server {
    listen 80;
    server_name linuxize.com www.linuxize.com;
    return 301 https://linuxize.com$request_uri;
}

Given code paste on bottom side.
server {
    listen 443 ssl http2;
    server_name www.linuxize.com;

    # . . . other code

    return 301 https://linuxize.com$request_uri;
}

For more click here!

Yagnesh bhalala
  • 967
  • 1
  • 14
  • 16