【问题标题】:Nginx redirect http://www and naked http/https to https://wwwNginx 将 http://www 和裸 http/https 重定向到 https://www
【发布时间】:2014-05-08 22:10:41
【问题描述】:

我想重定向来自以下域的所有流量:

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

  • https://www.domain.com

我有上述域的 SSL 证书。它托管一个 Rails 应用程序,由 Passenger 提供服务。

为了完成裸域重定向,我在我的 DNSimple 帐户中设置了 URL 重定向:

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

我的服务器块如下(受Nginx no-www to www and 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;

什么有效:

  • 裸域被重定向到安全https://www
  • http://www 域被重定向到安全 https://www
  • https://www 作品

什么不能:

  • https:// 不起作用,浏览器抛出未找到服务器

基本上我想将所有流量重定向到安全的https://www.domain.com。我在这里错过了什么?

【问题讨论】:

标签: ssl nginx https dns dnsimple


【解决方案1】:

我有类似的情况,这就是我解决来自

的重定向的方法

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;
    }

希望这会有所帮助!

Using if condition in nginx

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

【讨论】:

  • 酷!但是检查每个请求不是很昂贵吗?
  • 指令如果在位置上下文中使用时出现问题,在某些情况下,它并没有达到您的预期,而是完全不同。在某些情况下,它甚至会出现段错误。如果可能的话,通常最好避免它。如果在位置上下文中,唯一可以在内部完成的 100% 安全的事情是:return ...;重写...最后;
【解决方案2】:

如果您没有 domain.com 的证书,从 https://domain.com 重定向到 https://www.domain.com 将不起作用,因为在浏览器获得重定向之前,它必须成功建立 SSL 连接(https 是 SSL 内的 http)这失败了,因为证书不匹配。

【讨论】:

  • 以为是这样的。下次应该得到通配符证书。谢谢!
  • 通配符是不够的,例如*.domain.com 与 domain.com 不匹配。因此,您需要获得至少包含 www.domain.com(或 *.domain.com)和 domain.com 的证书。
【解决方案3】:

以下会有所帮助。

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 <<======
}

【讨论】:

    【解决方案4】:

    为裸域提供特定的服务器块以及一般默认值。将首先使用更具体的。

        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
        }
    

    我将 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
        }
    

    为裸 example.com、www.example.com 和任何其他设置证书:

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

    【讨论】:

      猜你喜欢
      • 2016-11-08
      • 1970-01-01
      • 2018-02-02
      • 2017-09-03
      • 2015-10-23
      • 2018-09-26
      • 2018-12-10
      • 1970-01-01
      • 2015-02-16
      相关资源
      最近更新 更多