2

I've been working on this for a while and can't seem to find any solution.

I have varnish sitting in front of my nginx server, with CloudFlare sitting in front.

When I issue a curl -X PURGE host CloudFlare picks it up and of course denies it with a 503 error. If I use direct.host to bypass CloudFlare it hits the Varnish server and it accepts the request but it does nothing since direct.host isn't used so there is nothing in the cache for that url.

I am using WordPress and there is a WordPress Varnish Purge plugin, it says to add the following line to wp-config.php:

define('VHP_VARNISH_IP','127.0.0.1')

This is specifically to work with proxy servers and/or CloudFlare to make sure the request goes to the Varnish server rather than CloudFlare, but that doesn't seem to help.

Anyone see this before and have any idea?

masegaloeh
  • 18,236
  • 10
  • 57
  • 106
Michael
  • 123
  • 3
  • You should provide your VCL configuration and the headers of the curl request & response in order to trace the problem. – NITEMAN Oct 17 '13 at 06:29
  • Here is the config, I replaced my public IP to a placeholder. If I turn off CloudFlare, the purge works fine and I get a 200 purge. If I do not turn off Cloudflare, I get a 403 unauthorized error reported by CloudFlare. default.vcl - http://pastebin.com/JcjgWRyE – Michael Oct 18 '13 at 22:29

3 Answers3

3

Your problem is that the purge request is being handled by ClodFlare instead of Varnish.

Keep in mind that:

  • In Varnish 3 you should be using purge; instead of set obj.ttl = 0s;
  • Varnish will resolve the object using vcl_hash. In Varnish 3 this means, by default [1], that the req.url will be used along with HTTP "Host" header or, if not present, the server IP:

    sub vcl_hash {
      hash_data(req.url);
      if (req.http.host) {
        hash_data(req.http.host);
      } else {
        hash_data(server.ip);
      }
      return (hash);
    }
    
  • You can override vcl_hash to match your needs

Please take a look at the documentation [2] and Varnish Book info [3] on Bans & Purges

In my opinion you have to options:

  1. Issue the purges directly to Varnish circumventing CloudFlare, directly using curl -H "Host: _host_wich_has_the_url_to_purge" -X PURGE http://_varnish_ip_:_varnish_port/_url_to_purge_
  2. Try to add the CloudFlare IP ranges to your acl purge (not recommended) and instruct CloudFlare to pass such requests to Varnish.

[1] https://www.varnish-cache.org/docs/3.0/reference/vcl.html#examples

[2] https://www.varnish-cache.org/docs/3.0/tutorial/purging.html

[3] https://www.varnish-software.com/static/book/Cache_invalidation.html#removing-a-single-object

NITEMAN
  • 314
  • 1
  • 5
0

FWIW the plugin says to put in the IP of your Varnish server (in http://wordpress.org/plugins/varnish-http-purge/faq/ ). "Your Varnish IP must be one of the IPs that Varnish is listening on. If you use multiple IPs, or if you've customized your ACLs, you'll need to pick on that doesn't conflict with your other settings. For example, if you have Varnish listening on a public and private IP, you'll want to pick the private. On the other hand, if you told Varnish to listen on 0.0.0.0 (i.e. "listen on every interface you can") you would need to check what IP you set your purge ACL to allow (commonly 127.0.0.1 aka localhost), and use that (i.e. 127.0.0.1)."

When you run the purge command manually, i.e. via CURL, what do you put in to make it work?

Ipstenu
  • 101
0

Cloudflare, when you hand them your DNS, will set up direct.yourdomain.com. You should be able to issue the PURGE directly to that address, which will bypass Cloudflare and hit your Varnish server directly. Make sure any ACL blocks that you have allow the address that you're sending the PURGE from, however.

Aaron Brady
  • 121
  • 3