Search code examples
nginxwebserver

NGINX user agent blocking for specific subdirectory


I'm trying to block a certain user agent from accessing a certain subdirectory in NGINX.

I tried doing this:

       location ~ /subdir {
       if ( $http_user_agent ~ (BOT)) {
        return 403;
    }
       }

This however blocks everyone from accessing said directory, as if the if directive is being completely ignored. I don't understand why this isn't working.


Solution

  • With complex Nginx configurations, adding another location block is never simple. It may be easier to implement this using map blocks instead.

    The map block must be placed in http context, for example, just above the start of the server block.

    map $request_uri $target_subdir {
    ~*^/subdir/   1;
    }
    
    map $http_user_agent $access_denied {
    ~*BOT         $target_subdir;
    }
    
    server {
        ...
        if ($access_denied) { return 403; }
        ...
    }
    

    The map blocks are cascaded. If the user agent matches, then the requested URI is evaluated. Only if both return true will the access be denied.