setup nginx to require certain conditions of a location for all but a given source IP

I'm looking for a setup where I'd like to have SSL client certificates for all but one source IP.

My idea is to set

 ssl_verify_client optional;

and to add an elaborate if statement to the locations. However I don't know how to write such an if statement.

  # 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; 
    ...
  }

Edit: Additional information

The switch ssl_verify_client with the value optional tells clients, that they can but don't have to send client certificates.

So by checking the variable $var_ssl_client_verify I can see whether a client certificate was presented and valid (SUCCESS) or not. This rule shall be applied for all clients, that do not have a given source IP. For one specific source IP I do not want to verify client certificates.

What I need is something like

    if ($ssl_client_verify != "SUCCESS" and source_ip != 1.2.3.4 ) { 
       return 403; 
    }

Edit 2: I changed the title from setup nginx to require client certs for all but a given source IP to setup nginx to require certain conditions of a location for all but a given source IP as what I am really struggling with has nothing to do with client certificates, but with combining if statements and filtering conditionally on the source IP address.


Multiple conditions aren't supported in Nginx for if statement. So, as a workaround and as client IP is evaluated in our usecase, the solution could be achieved similar to how it was achieved at https://www.nginx.com/blog/rate-limiting-nginx/#Advanced-Configuration-Examples . Basically, the solution goes like this...

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
    }
}

Basically, we assign the value "SUCCESS" to the variable for a specific IP. For every other IP, we assign the actual value of $ssl_client_verify.

Alternative Answer

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
    }
}