Search code examples
nginxnginx-reverse-proxywhitelist

When using Nginx reverse proxy, how can I set IP whitelist based on request URI parameter?


My url like this:

http://myserver/app/inf?ConId=Obj%3Acom.aaa.bbb%3A3712 # Only IP in whitelist can access
http://myserver/app/...... # all user can access

When the parameter of ConId is Obj%3Acom.aaa.bbb%3A3712, I need to restrict only specific IP can access my server.

I tried the following Nginx configuration but not working.

 location / {
            if ( $arg_ConId = "Obj%3Acom.aaa.bbb%3A3712" ) { 
                allow 192.168.1.104;
                deny  all;
            }
            proxy_pass http://192.168.234.130:80;
            add_header Access-Control-Allow-Origin *;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            allow all;
        }

Please help, thanks!


Thanks @araisch,my final working Nginx Configuration is:

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    
    #keepalive_timeout  0;
    keepalive_timeout  65;
    
    server {
        listen       80;
        server_name  localhost;
        error_page  403              /403.html;
        
        location = /403.html {
            root html;
        }
        
        if ($arg_ConId  = "Obj%3Acom.aaa.bbb%3A3712") {
           set $BLOCKING A;
        }
        if ($remote_addr != "192.168.3.11") {
           set $BLOCKING "${BLOCKING}B";
        }
        if ($BLOCKING = AB) {
           return 403;
           break;
        }
                
        location / {
            proxy_pass http://192.168.234.130:80;
            add_header Access-Control-Allow-Origin *;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            allow all;
        }

    }
}

Solution

  • Could use something like:

    if ($arg_ConId = "Obj%3Acom.aaa.bbb%3A3712") {
       set $BLOCKING A;
    }
    if ($remote_addr != 192.168.1.104) {
       set $BLOCKING "${BLOCKING}B";
    }
    if ($BLOCKING = AB) {
       return 403;
       break;
    }
    

    in server block.

    Problems in your code:

    • if Directives in location are considered as evil due to nginx` strange declaration rules. They're doing most of the time strange things, so try to avoid it.
    • $arg_ContainerOID does not catch an argument named "ConId"

    Remark: This is not working in dockerized nginx in bridge mode, because the real IP is masked by the firewall.