Question: 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?

Answer: 
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>
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?