我试图按如下方式设置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
在这种情况下如何设置条件?
答案 0 :(得分:10)
您可以在auth_basic
子句中设置if
配置,如下所示:
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。
答案 1 :(得分:4)
我目前无法对此进行测试,但是这样会有效吗?
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
- 检查客户端是否已经过验证
- 如果不是,请重写为使用基本身份验证的备用域
就像我说的那样,我现在无法测试它,但我会尝试解决它!如果有帮助,请告诉我,我很有兴趣看看它是否有效。
答案 2 :(得分:3)
当客户端证书失败时,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这些规则可能无法正常工作或干扰较大配置的其他部分。
答案 3 :(得分:1)
忘记它,它将无效。
失败的原因是因为if
不是人们应该相信的一般配置模块的一部分。 if
是重写模块的一部分,auth_basic
是另一个模块。你不能拥有带有基本身份验证的动态虚拟主机。
您可以拥有带有自己错误页面的动态虚拟主机。以下示例是为自定义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;
}
/404.html
。HTTP_NOT_FOUND
root
以匹配网站error_pages
目录。location @fallback_404
中配置后备404页面:在此位置,root
已更改为/var/www/
,因此它将从该路径而不是$site_root
中读取文件/var/www/404.html
。注意:根据Nginx文档:
指定给定位置只能用于内部 要求。对于外部请求,客户端错误404(未找到)是 回。内部请求如下:
- 由error_page,index,random_index和try_files指令重定向的请求;
- 来自上游服务器的“X-Accel-Redirect”响应头字段重定向的请求;
- 由ngx_http_ssi_module模块的“include virtual”命令和ngx_http_addition_module模块形成的子请求 指令;
- 请求由重写指令更改。
此外:
每个请求都有10个内部重定向限制以防止 请求在错误配置中发生的处理周期。 如果达到此限制,则错误500(内部服务器错误)为 回。在这种情况下,“重写或内部重定向周期” 消息可以在错误日志中看到。
点击this link了解更多信息,希望有所帮助。
答案 4 :(得分:0)
您可以尝试使用地图。
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
但始终是 alsa 定义的,并且 auth_basic
和 auth_basic_user_file
始终位于 server {
块内。