Varnish purge configuration causing startup errors - caching

I'm having a problem with the purge configuration in Varnish. I have a purge URL configured as below, but on attempting to start the service I get an error, also below. If I comment out this piece of config, the service starts without issue. Does anyone have any ideas where I'm going wrong?
Cheers.
sub vcl_recv {
#purge all
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
if (req.url ~ "varnish/index/purgeall/key/#Fj1nzljh") {
purge_hash( ".*" );
}
}
The error message on start reads:
user#ubuntu:/var/www$ sudo service varnish start
* Starting HTTP accelerator varnishd [fail]
storage_file: filename: /var/lib/varnish/ubuntu/varnish_storage.bin size 1024 MB.
Message from VCC-compiler:
Expected an action, 'if', '{' or '}'
(input Line 18 Pos 7)
purge_hash( ".*" );
------##########---------
Running VCC-compiler failed, exit 1
VCL compilation failed
mark#ubuntu:/var/www$ sudo service varnish start
* Starting HTTP accelerator varnishd [fail]
storage_file: filename: /var/lib/varnish/ubuntu/varnish_storage.bin size 1024 MB.
Message from VCC-compiler:
Expected an action, 'if', '{' or '}'
(input Line 18 Pos 7)
purge_hash( ".*" );

The correct way to do this in 3.0.x is something like this:
acl our_lan {
"localhost";
"10.0.0.0"/8;
"192.168.0.0"/16;
}
sub vcl_recv {
# ...
if (req.request == "PURGE") {
if (! (client.ip ~ our_lan)) {
error 405 "Not allowed.";
}
return (lookup);
}
# ...
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 200 "OK: but URL not in cache.";
}
}
YMMV.

purge_hash seems to have been removed in latest versions of varnish http://www.varnish-cache.org/trac/changeset/e20226fa977bb3e05d49b4e497a0b9f64ca5f272
it seems that you want to clear the whole cache, you can achieve it with the other purge functions

Related

Varnish. how to clean all cache over curl

curl command:
curl -X PURGE <URL>
so it is possible to clear only one page
how to clean the all cache by using CURL?
Add this VCL and then you can use "curl -X BANRE ." to clear the cache.
sub vcl_recv {
if (req.method == "BANRE") {
# Same ACL check as above:
if (!client.ip ~ purge) {
return(synth(403, "Not allowed."));
}
ban("req.url ~ " + req.url).
return(synth(200, "Ban added"));
}
}
(varnish 3) I was able to clear the all cache so
if (req.request == "BAN") {
if (!client.ip ~ purge) {
# Not from an allowed IP? Then die with an error.
error 405 "This IP is not allowed to send PURGE requests.";
}
ban("req.http.host == " +req.http.host+" && req.url ~ "+req.url);
error 200 "Ban added";
}
curl -X BAN http://domain.com/.

How do I access Varnish admin area?

This is a stupid question, sorry... I have tried googling and to no avail.
I thought it would just be visiting example.com:6082 but that doesn't seem to load anything.
# # Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
Also, as a side question (I'm still working on getting it working), will varnish cache ANY file type, even if it's an RSS feed or a .php file or anything?
Varnish doesn't have an admin area. The admin port is for the CLI varnishadm tool. It will normally pick up the port automatically. You can also use the admin port to connect to Varnish from custom tools and issue admin commands.
Check out the docs for the varnishadm tool. Here's an example of specifying the port:
varnishadm -T localhost:6028
There is a tool called the VAC (Varnish Administration Console) that provides a web based admin console, but it's quite expensive, and is part of Varnish Plus.
As for the other part of your question, Varnish will cache anything it thinks is safe to cache. It doesn't look so much at file types, but more at HTTP headers. If the user sends cookies for example, Varnish won't cache the page by default as the cookies may indicate the user is on a dynamic page. Varnish also only caches GET requests by default.
Check out the default vcl. For version 3:
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
/* Not cacheable by default */
return (pass);
}
return (lookup);
}

PURGE on a Varnish 3.0.3 cluster

I have a website www.mysite.com running behind a load balancer. There are two servers in the load balancer cluster. Each runs Varnish 3.0 and Apache/PHP (I know varnish could load balance for me - but we have a preference for a different LB tech).
Every now and again I need to purge an URL or two...
In my VCL I have 127.0.0.1 as a trusted URL for PURGEs. And a standard purge config:
vcl_recv:
....
if (req.request == "PURGE") {
# Allow requests from trusted IPs to purge the cache
if (!client.ip ~ trusted) {
error 405 "Not allowed.";
}
return(lookup); # #see vcl_hit;
}
...
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged (via vcl_hit)";
}
if (!(obj.ttl > 0s)) {
return (pass);
}
return (deliver);
}
sub vcl_miss {
if (req.request == "PURGE"){
purge;
error 404 "Not in Cache";
}
return (fetch);
}
Now from a shellscript I want to invalidate an URL.
curl -X PURGE http://127.0.0.1/product-47267.html
Doesnt work, but
curl -X PURGE http://www.mysite.com/product-47267.html
Does work. Problem here is - I need to invalidate on each local machine in cluster - not have the request go out and back in via the load balancer (because I dont know which machine will take the PURGE).
Hope this makes sense
LW
You need to connect to localhost but Varnish still need to know which Host you want to PURGE.
I'm not sure but try something like the following :
curl -X PURGE -H "Host: www.mysite.com" http://127.0.0.1/product-47267.html

varnish exclude url

I have a varnish 3.xx server which currently works.
Varnish is caching the login page of my site.
www.mysite.com/staff
but it may have different urls depending on the staff members link, for example
www.mysite.com/staff/index.php?/Tickets/Ticket/View/222200
My varnish config file is set as follows to exclude caching the staff page, but it is not working, as it is caching the login page and it is will not login untill i restart varnish to clear it's cache.
sub vcl_recv {
# Allow purge only from internal users
if (req.request == "PURGE") {
if (!client.ip ~ internal_net) {
error 405 "Not allowed.";
}
return (lookup);
# Exclude the following
if (req.url ~ "^/login\.php" ||
req.url ~ "^/search\.php" ||
req.url ~ "^/admin(.*)" ||
req.url ~ "^/admin(.*)" ||
req.url ~ "^/search(.*)" ||
req.url ~ "^/visitor(.*)" ||
req.url ~ "^/staff(.*)" ||
req.url ~ "^/staff\.php"
) {
return(pass);
}
if (req.http.cookie ~ "vb(.*)" ||
req.http.cookie ~ "bb(.*)" ||
req.http.cookie ~ "SWIFT_(.*)" ||
req.url ~ "\?(.*\&)?s=[a-fA-F0-9]{32}(\&|$)" ||
req.http.cookie ~ "bb_password") {
return(pass);
} else {
unset req.http.cookie;
}
}
Do you perhaps have another method to exclude and entire directory from being cached?
IE: everything from /staff no matter what the suffix is after that must not be cached
The exclusion should work perfectly the way you have implemented it. However if the code you pasted is your actual VCL you have an open if() statement in the PURGE section.
sub vcl_recv {
# Allow purge only from internal users
if (req.request == "PURGE") {
if (!client.ip ~ internal_net) {
error 405 "Not allowed.";
}
return (lookup);
# Exclude the following
should read
sub vcl_recv {
# Allow purge only from internal users
if (req.request == "PURGE") {
if (!client.ip ~ internal_net) {
error 405 "Not allowed.";
}
return (lookup);
}
# Exclude the following
Varnish should not accept invalid VCL though, so if the error does not exist in your actual VCL, please update the question with your entire VCL.

Using a second backend with Varnish 1.0.3-2 in case of 404 from first backend

We used to have a caching proxy setup using a very early version of Varnish (0.5ish, I think) which used the 'restart' action to send requests to a second backend in the case of a 404 on the first.
The new version of Varnish doesn't seem to support this - the 'restart' action no longer seems to be supported, and the 'req.restarts' variable is no longer recognised. Is such behaviour possible?
The documentation seems to be out of date, as do many of the online examples. man 7 vcl seems to reflect current behaviour though.
If it's not possible with Varnish, can you suggest another solution?
Here are the relevant bits of our old Varnish config:
sub vcl_recv {
# remove cookies
remove req.http.Cookie;
if (req.restarts == 0) {
set req.backend = backend1;
} else if (req.restarts == 1) {
set req.backend = backend2;
}
# remove any query strings
set req.url = regsub(req.url, "\?.*", "");
# force lookup even when cookies are present
if (req.request == "GET" && req.http.cookie) {
lookup;
}
}
sub vcl_fetch {
# we might set a cookie from the Rails app
remove obj.http.Set-Cookie;
# force minimum ttl of 1 year
if (obj.ttl < 31536000s) {
set obj.ttl = 31536000s;
}
if (obj.status != 200 && obj.status != 302) {
restart;
}
}
It seems this behaviour has been reinstated in more recent versions of Varnish.

Resources