如何在 nginx 中强制或重定向到 SSL?

如何在 nginx 中强制或重定向到 SSL?

我在子域名上有一个注册页面,例如:https://signup.example.com

它应该只能通过 HTTPS 访问,但我担心人们可能会以某种方式通过 HTTP 偶然发现它并得到 404。

我的 nginx 中的 html/server 块如下所示:

html {
  server {
    listen 443;
    server_name signup.example.com;

    ssl                        on;
    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    ssl_session_timeout 30m;

    location / {
      root /path/to/my/rails/app/public;
      index index.html;
        passenger_enabled on;
    }
  }
}

我可以添加什么,以便将访问的人http://signup.example.com重定向到https://signup.example.com?(仅供参考,我知道有 Rails 插件可以强制执行,SSL但希望避免这种情况)

答案1

根据nginx 陷阱,最好省略不必要的捕获,而改用$request_uri。在这种情况下,附加一个问号以防止 nginx 将任何查询参数加倍。

server {
    listen      80;
    server_name signup.mysite.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
}

答案2

最好的方法如下官方指南是通过使用return指示:

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

答案3

如果您想将所有内容保存在一个服务器块中,这是正确且最有效的方法:

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

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

上述所有其他操作,使用“rewrite”或“if ssl_protocol”等都会变得更慢、更糟糕。

这里是一样的,但效率更高,通过只在 http 协议上运行重写,它避免了在每次请求时检查 $scheme 变量。但说真的,这是一件小事,你不需要将它们分开。

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

    server_name www.example.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;
}

答案4

还有一种变体,它保留了 Host: 请求标头,并遵循了nginx 陷阱

server {
    listen   10.0.0.134:80 default_server;

    server_name  site1;
    server_name  site2;
    server_name  10.0.0.134;

    return 301 https://$host$request_uri;
}

结果如下。请注意,使用$server_name而不是$host总是会重定向到https://site1

# curl -Is http://site1/ | grep Location
Location: https://site1/

# curl -Is http://site2/ | grep Location
Location: https://site2/


# curl -Is http://site1/foo/bar | grep Location
Location: https://site1/foo/bar

# curl -Is http://site1/foo/bar?baz=qux | grep Location
Location: https://site1/foo/bar?baz=qux

相关内容