这里有点卡住了。我想要一个简单易用的 Nginx“包含”代码片段,该片段要求包含位置的 HTTP AUTH,并且如果尚未重定向到 HTTPS,则强制重定向到 HTTPS。
我想到了这个:
# /etc/nginx/snippets/requirelogin-staff.conf
if ($https != "on") {
return 301 https://$server_name$request_uri;
}
auth_ldap "Login Required";
auth_ldap_servers staff;
并像这样使用它(为简洁起见,这是一个愚蠢的例子,现实世界中我们有 django 服务 / 和 /static/ 作为资源文件快捷方式):
location / {
include snippets/requirelogin-staff.conf;
try_files $uri $uri/index.html $uri.html =404;
location /static {
alias /var/www/webroot/liv/static;
}
}
它对于任何通过位置处理的事情都非常有用 /
wget -S 显示它首先发出 301 重定向到相同的 URL,但使用 https 协议。然后它正确地返回 401。
问题出在 /static 下的 URL
身份验证通过指令继承开始。
但似乎“if ($https != "on")...”并没有被继承到嵌套的位置块中。
因此 wget -S 直接转到 401,邀请用户使用不安全的连接登录,这当然是一件坏事。
我可以明白为什么“if”有问题(try_files 也没有继承)。
但这让我很为难。
有没有人能建议一种更干净的方法?一条规则是(理想情况下)我希望在一个或多个位置用一行简洁的“include”来要求 AUTH,以避免错误。
继承也不错——同样可以避免错误。当然,我们可以在每个位置块上运行“include”,而且它确实有效。但是如果我们保护“/”,那么我们就能够知道我们已经保护了整个站点,并且开发人员无意中添加另一个位置块不会突然打开安全漏洞。
非常感谢,
蒂姆
答案1
嵌套位置块不会继承if
、try_files
、proxy_pass
和等命令。其他设置 等会被继承。uwsgi_pass
auth_ldap
https://stackoverflow.com/a/32126596
我找不到任何官方文档来说明哪些类型的配置语法是“命令”,哪些是常规配置项。嵌套位置的继承行为似乎没有记录。
更清洁的方法
不要使用嵌套位置,因为继承行为没有记录,而且没有人会自信地在将来做出改变。只需重复自己,但要用包含来重复自己。也许您可以创建另一个“standard-behavior.conf”的包含,并将 try_files 之类的内容放入其中。
location /static {
include snippets/requirelogin-staff.conf;
try_files $uri $uri/index.html $uri.html =404;
alias /var/www/webroot/liv/static;
}
location / {
include snippets/requirelogin-staff.conf;
try_files $uri $uri/index.html $uri.html =404;
}
答案2
301 重定向可以强制你的整个网站使用 https,如果这是有意为之,那么你不应该在端口 80 上提供除 301 重定向之外的任何服务,
{ # Http Redirect
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$server_name$request_uri;
}
请记住,如果您使用 301 指令,则所有内容都必须是 HTTPS,并且每个子域也必须是 HTTPS - 这不是坏事。另外,请仔细检查服务器名称在站点定义中使用它之前就已经定义了 - 我没有在您的示例配置中看到它。