我在子域名上有一个注册页面,例如: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
答案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