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

问题描述 投票:0回答:4

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

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

  • https://www.domain.com

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

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

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

我的服务器块如下(受到Nginx no-www到www和www到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
4个回答
6
投票

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


5
投票

我遇到过类似的情况,这就是我解决重定向的方法

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

希望这有帮助!

在nginx中使用if条件

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


4
投票

@steffen ulrich正确书写

如果您没有

example.com
重定向的证书
https://example.com
https://www.example.com
不起作用,因为 在浏览器获得重定向之前,它必须成功建立 SSL 连接(https 是 SSL 内的 http)并且失败,因为 证书不匹配。

这是一个例子:

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

1
投票

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

    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

© www.soinside.com 2019 - 2024. All rights reserved.