设置 nginx,要求除给定源 IP 之外的所有 IP 都满足特定位置条件

设置 nginx,要求除给定源 IP 之外的所有 IP 都满足特定位置条件

我正在寻找一种设置,其中我希望除一个源 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
    }
}

相关内容