Nginx:将非www重定向到https上的www

时间:2014-04-01 17:07:14

标签: .htaccess redirect ssl nginx

如果我在https上,Nginx无法将非www重定向到www:

https://domain.comhttps://www.domain.com

.conf中的设置是:

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

http://domain.comhttps://www.domain.comhttp://www.domainhttps://www.domain.com有效,但https上的非www到www无效。

如果我在第二个server块上添加了IP_ADDRESS,则会在Chrome中出现错误(SSL错误),并且(www和非www)都会停止工作。

更新:

感谢Steffen(以下回答),我将自签名证书更新为*.domain.com而不是domain.com

.conf文件已按以下格式更新:

ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;

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

5 个答案:

答案 0 :(得分:9)

我有类似的场景,这就是我解决重定向问题的方法

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

 server {
      listen        443;
       server_name    example.com;
         if ($host = example.com) {
        rewrite ^(.*) https://www.example.com:443$request_uri? permanent;
      }
 } 

希望这有帮助!

Using if condition in nginx

  

指令如果在位置上下文中使用时会出现问题,在某些情况下它不会达到您的预期,但会完全不同。在某些情况下,甚至是段错误。如果可能的话,避免使用它通常是一个好主意。如果在位置上下文中,可以在内部完成的唯一100%安全的事情是:   回来......;重写...最后;

答案 1 :(得分:5)

在第二个服务器块(一个以“listen 443;”开头)中,您必须添加SSL服务器组(最后一个组)中所有与SSL相关的指令。这是我的example.conf:

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

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

    # SSL
    ssl on;
    ssl_certificate /var/www/example.com/cert/bundle.cer;
    ssl_certificate_key /var/www/example.com/cert/example.com.key;

    # Enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Intermediate cypersuite as recommended by Mozilla
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;
    # Add HSTS (HTTPStrictTransportSecurity)
    add_header Strict-Transport-Security "max-age=31536000";
}


server {
    listen 443 ssl;
    server_name www.example.com;
    root /var/www/example.com/public;
    index index.html index.htm index.php;
    client_max_body_size 32m;

    access_log  /var/www/example.com/access.log;
    error_log  /var/www/example.com/error.log;

    # SSL
    ssl on;
    ssl_certificate /var/www/example.com/cert/bundle.cer;
    ssl_certificate_key /var/www/example.com/cert/example.com.key;

    # Enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Intermediate cypersuite as recommended by Mozilla
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;
    # Add HSTS (HTTPStrictTransportSecurity)
    add_header Strict-Transport-Security "max-age=31536000";

    # Directives to send expires headers and turn off 404 error logging.
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        #expires max;
        log_not_found off;
        access_log off;
    }

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    ## Disable viewing .htaccess & .htpassword
    location ~ /\.ht {
        deny  all;
    }

    location ^~ /admin/ {
                auth_basic "Restricted";
                auth_basic_user_file /var/www/example.com/.htpasswd;
                try_files $uri $uri/ /index.php$is_args$args;
                location ~ \.php$ {
                        include /etc/nginx/php-inside.conf;
                }
        }

    include /etc/nginx/php.conf;
}

答案 2 :(得分:4)

这可能是因为您没有domain.com的证书,但仅限于www.domain.com或* .domain.com。有关详细信息,请参阅Nginx redirect http://www and naked http/https to https://wwwhttps://serverfault.com/questions/579916/nginx-redirect-https-www-to-https-non-www-without-untrusted-connection-warn/579917#579917

答案 3 :(得分:0)

这是我使用的更优雅的解决方案。需要一个服务器块用于实际网站,一个服务器块用于从非www /非https重定向到https://www.*

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

default_server选项很重要,否则第一个定义将成为默认值,可能会影响您重定向www.domain.com以外的所有请求的意图。通过使用default_server,您的重定向服务器块充当了一个全能的。

在我看来,你不应该使用" www"。您应该从www重定向到非www。 www是一个传统的东西,现在并不相关。您可以通过从非www重定向到www.

来延续这种无关的遗产

答案 4 :(得分:0)

我在两个服务器指令上都使用了重写,它对我有用:

  

一般重写指令非www到https wwww

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

非www到https的SSL规则指令wwww

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