Konstantin Palkin
Konstantin Palkin

Reputation: 31

Varnish-Cache Time based access

I have in Apache something like this

    RewriteCond %{REMOTE_HOST} !^11\.22\.33\.[12]\d\d$ #As example allows from 100 till 200
    RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1$
    RewriteCond %{TIME} <20140113090000
    RewriteRule ^/access-on-monday/ http://www.mysite.com/ [NC,L,R=302]

which works perfect.

I need same for Varnish. Because server behind LoadBalancer it gets X-Forwarded-For header with real client IP. I still check %{REMOTE_HOST} in Apache because rpaf_module is installed. I added next in Varnish with helping ipcast vmod

    import ipcast;
    acl office {
        "localhost";
        "11.22.33.100"/24; //Let's think that it matches with 11.22.33.100 - 11.22.33.200
    }
    sub vcl_recv {
            if (req.http.X-Forwarded-For !~ ",") {
                set req.http.xff = req.http.X-Forwarded-For;
            } else {
                set req.http.xff = regsub(req.http.X-Forwarded-For, "^[^,]+.?.?(.*)$", "\1");
            }
            if (ipcast.clientip(req.http.xff) != 0) {
                error 400 "Bad request";
            }
            if (!client.ip ~ office) {
                set req.http.X-Redir-Url = "http://" + req.http.Host + "/";
                error 751 "Found";
            }
    }

Then in vcl_error I make redirect but it doesn't matter here. My question is it possible to make timebased access like in Apache?

Upvotes: 1

Views: 577

Answers (1)

Doomsday
Doomsday

Reputation: 2668

You are limited with simple VCL but Varnish allow to do much more than simple statements. You can enhance and drive your workhorse with inline-C or VMODs, and do this job in C.

For example, if you want to do add timebased access from :

backend server_available_in_2014 {
  .host="127.0.0.1";
  .port="8080";
}

sub vcl_recv {
   set req.backend = server_available_in_2014; # IT MUST BE AVAILABLE ONLY in 2014
}

You can convert your date 201401010000 into an UNIX timestamp 1389617122, and write simple inline-C :

backend server_available_in_2014 {
    .host="127.0.0.1";
    .port="8080";
}

C{
double TIM_real(void);
}C

sub vcl_recv {
    C{
            if (TIM_real() > 1389617122.0) {
                    VRT_l_req_backend(sp, VGCDIR(_server_available_in_2014));
            }
    }C
}

TIM_real() is returning a current timestamp (look at varnish/lib/libvarnish/time.c) and VRT_l_req_backend statement is exactly the same as set req.backend = server_available_in_2014;, but written in C instead of VCL.

If you want more tweaks, you can compile your VCL into C by executing the following command: varnishd -f default.vcl -C

Upvotes: 1

Related Questions