简体   繁体   English

Nginx将http:// www和裸http / https重定向到https:// www

[英]Nginx redirect http://www and naked http/https to https://www

I would like to redirect all traffic from the following domains: 我想重定向以下域中的所有流量:

  • http://domain.com
  • http://www.domain.com
  • https://domain.com

to

  • https://www.domain.com

I have a SSL certificate for the above domain. 我有上述域名的SSL证书。 It hosts a Rails app, served by Passenger. 它托管了一个由Passenger提供服务的Rails应用程序。

To accomplish the naked domain redirect, I've set up an URL redirect in my DNSimple account: 要完成裸域重定向,我在DNSimple帐户中设置了URL重定向:

URL domain.com  3600  https://www.domain.com

My server blocks are as follows (Inspired by Nginx no-www to www and www to no-www amongst others): 我的服务器块如下(灵感来自Nginx no-www to www和www to no-www等):

server {
    listen          80;
    listen          443;
    server_name     domain.com;

    ssl                             on;
    ssl_certificate                 /etc/ssl/domain-ssl.crt;
    ssl_certificate_key             /etc/ssl/domain.key;
    ssl_session_timeout             5m;
    ssl_protocols                   SSLv2 SSLv3 TLSv1;
    ssl_ciphers                     HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers       on;

    server_tokens   off;
    access_log      /dev/null;
    error_log       /dev/null;

    return 301 https://www.domain.com$request_uri;
}

server {
    listen          443 ssl;
    server_name     www.domain.com;

    root                            /home/deploy/app/current/public;
    passenger_enabled               on;
    passenger_app_env               production;
    passenger_set_cgi_param         HTTP_X_FORWARDED_PROTO https;

    ssl                             on;
    ssl_certificate                 /etc/ssl/domain-ssl.crt;
    ssl_certificate_key             /etc/ssl/domain.key;
    ssl_session_timeout             5m;
    ssl_protocols                   SSLv2 SSLv3 TLSv1;
    ssl_ciphers                     HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers       on;
}

passenger_pre_start https://www.domain.com;

What works: 什么有效:

  • naked domain gets redirected to secure https://www 裸域被重定向到安全https://www
  • http://www domain gets redirected to secure https://www http://www域被重定向到安全https://www
  • https:// www works https:// www有效

What does't: 什么不:

  • Naked https:// doesn't work, browsers throws a server not found Naked https://不起作用,浏览器抛出未找到的服务器

Basically I want to redirect all traffic to the secure https://www.domain.com . 基本上我想将所有流量重定向到安全的https://www.domain.com What am I missing here? 我在这里错过了什么?

I had similar kind of scenario and this is how I solved the redirection from 我有类似的场景,这就是我解决重定向问题的方法

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

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

Hope this helps! 希望这可以帮助!

Using if condition in nginx 在nginx中使用if条件

Directive if has problems when used in location context, in some cases it doesn't do what you expect but something completely different instead. 指令如果在位置上下文中使用时有问题,在某些情况下它不会按预期执行,而是完全不同。 In some cases it even segfaults. 在某些情况下,甚至是段错误。 It's generally a good idea to avoid it if possible. 如果可能的话,尽量避免使用它通常是个好主意。 The only 100% safe things which may be done inside if in location context are: return ...; 如果在位置上下文中,可以在内部完成的唯一100%安全的事情是:return ...; rewrite ... last; 重写...最后;

如果您没有domain.com的证书,从https://domain.com重定向到https://www.domain.com将无法正常工作,因为在浏览器获得重定向之前,它必须成功建立SSL连接(https是SSL中的http)并且由于证书不匹配而失败。

Provide a specific server block for the naked domain along with a general default. 为裸域提供特定的服务器块以及一般默认值。 The more-specific ones will be used first. 将首先使用更具体的。

    server {
            listen 80;
            listen [::]:80;
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name example.com;

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

            return 301 https://$host$request_uri;
    }
    server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name www.example.com;
            # omitting the rest for https://www.example.com
    }

I use Let's Encrypt for my certificates so something like the following for default_server prevents redirecting the ACME challenges (note the second wildcard server_name for handling all https://*.example.com which don't have their own server block). 我使用Let's Encrypt作为我的证书,因此类似于default_server的以下内容可防止重定向ACME挑战(请注意第二个通配符server_name用于处理所有没有自己的服务器块的https://*.example.com )。

    # omit server_name example.com block, same as above
    server {
            listen 80 default_server;
            listen [::]:80 default_server;

            location ~ ^/\.well-known/acme-challenge {
                # LetsEncrypt
                add_header Content-Type text/plain;
                expires 0;
                alias /var/www/html/acme/$host;
                break;
            }
            location ~ ^/(?!\.well-known/acme-challenge) {
                return 301 https://$host$request_uri;
            }
    }
    server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name *.example.com;
            # omitting the rest for https://*.example.com
    }

Setup certificates for the naked example.com, www.example.com and any others: 为example.com,www.example.com和其他任何人设置证书:

sudo certbot certonly --manual -d example.com -d www.example.com -d abc.example.com

Following will help. 以下将有所帮助。

server {
            listen 80;
            listen [::]:80;
            server_name example.com www.example.com;


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

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

server {
            listen 443 ssl http2;
            listen [::]:443 ssl http2;
            server_name www.example.com;

   ====>>> Your site configuratioin Goes here <<======
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM