Bypass cache from single IP with NGINX

user204197 asked:

I want to setup NGINX to serve content from the cache to everybody but one IP address.

The 2 goals I want to achieve are:

  1. make sure that from the specified IP I never hit the cache but will be served the actual file on disk (so if I remove the file it should immediately give a 404)
  2. for all the other IPs: if content is requested that is not yet in the cache immediately load it from file and store it in the cache (so if I remove the file it should served for the duration of the cache)

This is my configuration so far:

server {
    listen                      80;
    listen                      127.0.0.1:9999 default;
    server_name                 storage.example.com;
    charset                     utf-8;
    autoindex                   off;

    access_log                  "/var/log/nginx/storage.access.log";
    udplog_tag                  "www.example.com/storage";

    set_real_ip_from            127.0.0.0/8;
    set_real_ip_from            unix:;
    real_ip_header              X-Real-IP;

    server_name_in_redirect     off;
    port_in_redirect            off;

    location /a/ {
        alias           "/storage/public/a/";
    }

    location /b/ {
        alias           "/storage/public/b/";
    }
}

server {
    listen          80;
    server_name     static.example.com;
    charset         utf-8;
    autoindex       off;

    access_log      "/var/log/nginx/static.access.log";
    udplog_tag      "www.example.com/static";

    location / {
        proxy_set_header      Host "$host";
        proxy_pass            http://127.0.0.1:9999/;
        proxy_set_header      X-Real-IP $remote_addr;
        proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 15;
        proxy_send_timeout    60;
        proxy_read_timeout    60;
        include               proxy_cache;
        proxy_redirect        default;
    }
}

This is the content of the included file proxy_cache:

proxy_cache             cache;
proxy_cache_key         "$scheme://$host$uri";
proxy_cache_use_stale   error;
proxy_next_upstream     off;
proxy_cache_min_uses    1;
proxy_cache_valid       200 302 1h;
proxy_cache_valid       301 1d;
proxy_cache_valid       any 30m;
proxy_buffers           128 4k;

What I would like to do is something similar:

if ( $remote_addr != "ip to exclude" ) 
 { include proxy_cache; }

Unfortunately this doesn’t work. Any help is greatly appreciated. Thank you.

My answer:


Bypassing the cache is done with proxy_cache_bypass. It will cause the cache to be bypassed if any value you pass to it is nonzero.

But before you can do that, you need a variable to pass to it. In your case this can be done with a geo directive to examine the remote IP address. (It could also be done with a map, which is a more general directive along the same lines.)

So, first place within your http block:

geo $ip_cache_bypass {
    default         0;
    192.0.2.81      1;
}

Then in your proxy configuration directives:

proxy_cache_bypass $ip_cache_bypass;

The cache will then be bypassed for the IP address 192.0.2.81. You can add as many IP addresses or CIDR ranges as you wish in the geo block.


View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.