我正在寻找一种设置,其中我希望除一个源 IP 之外的所有 IP 都拥有 SSL 客户端证书。
我的想法是设置
ssl_verify_client optional;
并在位置中添加一个复杂的 if 语句。但是我不知道如何编写这样的 if 语句。
# this requires ssl client certificates for all locations
location / {
if ($ssl_client_verify != "SUCCESS") {
return 403;
...
}
# now what to write to require ssl certs except if source IP is e.g. 1.2.3.4
location /two {
if (?????) {
return 403;
...
}
编辑:附加信息
开关ssl_验证客户端该值optional
告诉客户端,他们可以但不必发送客户端证书。
因此通过检查变量$var_ssl_client_verify我可以查看客户端证书是否已出示且有效 ( SUCCESS
)。此规则适用于所有没有指定源 IP 的客户端。对于一个特定的源 IP,我不想验证客户端证书。
我需要的是类似
if ($ssl_client_verify != "SUCCESS" and source_ip != 1.2.3.4 ) {
return 403;
}
编辑2:我将标题从 更改为 ,
setup nginx to require client certs for all but a given source IP
因为
setup nginx to require certain conditions of a location for all but a given source IP
我真正遇到的问题与客户端证书无关,而是与组合 if 语句并根据源 IP 地址进行条件过滤有关。
答案1
Nginx for 语句不支持多个条件if
。因此,作为一种解决方法,并且在我们的用例中评估客户端 IP,可以采用与在https://www.nginx.com/blog/rate-limiting-nginx/#Advanced-Configuration-Examples基本上,解决方案如下...
geo $limit {
default 1;
1.2.3.4 0; #please replace the example IP with the actual IP.
}
ssl_verify_client optional;
ssl_client_certificate /path/to/cert.pem;
map $limit $limit_key {
0 "SUCCESS";
1 $ssl_client_verify;
}
server {
# ... other directives
location / {
if ( $limit_key != 'SUCCESS' ) { return 403; }
# ... other directives
}
}
基本上,我们为特定 IP 的变量分配值“SUCCESS”。对于其他每个 IP,我们分配实际值$ssl_client_verify
。
替代答案
ssl_verify_client optional;
ssl_client_certificate /path/to/cert.pem;
server {
# ... other directives
# initial value of $variable is the actual value of $ssl_client_verify
set $variable $ssl_client_verify;
# here we re-assign $variable with "SUCCESS" for our specific IP
# please replace 1.2.3.4 with the actual IP
if ( $remote_addr = "1.2.3.4" ) {
set $variable "SUCCESS";
}
location / {
if ( $variable != 'SUCCESS' ) { return 403; }
# ... other directives
}
}