我正在尝试设置Nginx服务器如下:
首先,服务器应该检查用户是否提供客户端SSL证书(通过ssl_client_certificate)。如果提供了SSL证书,则授予对站点的访问权限,
如果未提供SSL证书,则要求用户通过auth_basic输入密码和日志。
我能够同时配置两种身份验证方法。但是这个配置是多余的。
要检查用户是否提供其SSL证书,我尝试这样配置:
18: if ($ssl_client_verify != SUCCESS) {
19: auth_basic "Please login";
20: auth_basic_user_file .passfile;
21: }
但是Nginx返回一个错误:
"auth_basic"指令在…/ssl.conf:19中不被允许
在这种情况下如何设置条件?
您可以在if
子句中这样设置auth_basic
配置:
server {
listen 443;
auth_basic_user_file .htpasswd;
ssl_client_certificate ca.cert;
ssl_verify_client optional;
...
location / {
...
if ($ssl_client_verify = SUCCESS) {
set $auth_basic off;
}
if ($ssl_client_verify != SUCCESS) {
set $auth_basic Restricted;
}
auth_basic $auth_basic;
}
}
现在,如果没有提供客户端证书(或者验证失败),身份验证将返回到HTTP Basic。
我无法测试这目前,但会这样的工作吗?
server {
listen 80;
server_name www.example.com example.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
...
if ($ssl_client_verify != SUCCESS) {
rewrite ^ http://auth.example.com/ permanent;
}
location / {
...
}
}
server {
listen 80;
server_name auth.example.com;
location / {
auth_basic "Please login";
auth_basic_user_file .passfile;
}
}
基本上:
-接受所有初始请求(无论您使用的是什么名称,在端口80上)并重写为ssl
-检查是否有客户端被验证。
-如果没有,重写到使用基本认证的备用域
就像我说的,我现在不能测试它,但我会试着去做的!让我知道它是否有帮助,我很想看看它是否有效。
您可以尝试使用地图。
map $ssl_client_verify $var_auth_basic {
default off;
SUCCESS "Please login";
}
server {
....
auth_basic $var_auth_basic;
auth_basic_user_file .passfile;
,这样的值取决于$ssl_client_verify
,但也总是被定义,auth_basic
和auth_basic_user_file
总是在server {
块内。
Nginx无法在客户端证书失败时退回到基本身份验证。作为一种替代方法,您可以使用变量来限制访问:
location / {
if ($ssl_client_verify = "SUCCESS") {
set $authorized 1;
}
if ($authorized != 1) {
error_page 401 @basicauth;
return 401;
}
}
location @basicauth {
auth_basic "Please login";
auth_basic_user_file .passfile;
set $authorized 1;
rewrite /(.*) /$1;
}
*请记住,IfIsEvil和这些规则可能会不正确地工作或干扰更大配置的其他部分。
算了吧,行不通的
它失败的原因是因为if
不是一般配置模块的一部分。if
是重写模块的一部分,auth_basic
是另一个模块。
另一方面…
您可以使用带有自己错误页面的动态vhost。下面的示例是为自定义404页面设计的,但您可以在代码中实现它。
server {
listen 80;
server_name _;
set $site_root /data/www/$host;
location / {
root $site_root;
}
error_page 404 =404 /404.html;
location /404.html {
root $site_root/error_files;
internal;
error_page 404 =404 @fallback_404;
}
location @fallback_404 {
root /var/www/;
try_files /404.html =404;
internal;
}
error_log /var/log/nginx/error.log info;
access_log /var/log/nginx/access.log;
}
会发生什么…
- 你告诉Nginx在
HTTP_NOT_FOUND
的情况下使用/404.html
。 - 更改位置
root
以匹配网站error_pages
目录。 内部重定向返回404 http代码 - 在
location @fallback_404
中配置回退404页面:在此位置,root
被更改为/var/www/
,因此它将从该路径读取文件,而不是从$site_root
- 在最后阶段,代码返回
/var/www/404.html
,如果存在404 http代码。
注意:根据Nginx文档:
也指定给定的位置只能用于内部请求。对于外部请求,客户端错误404 (Not Found)是返回。内部请求如下:
- 请求由error_page、index、random_index和try_files指令重定向;
- 请求由"X-Accel-Redirect"响应头字段重定向;
- 由ngx_http_ssi_module模块的" include virtual "命令和ngx_http_addition_module模块形成的子请求指令;
- 请求被重写指令改变。
:
每个请求的内部重定向限制为10个在不正确的配置中可能出现的请求处理周期。如果达到此限制,则错误500(内部服务器错误)是返回。在这种情况下,"重写或内部重定向周期"消息可以在错误日志中看到。
点击此链接了解更多信息,希望对您有所帮助。