Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I've got a varnish configuration file which looks like this:

 backend web1 { .host = "1.2.3.1" ; ... }
 backend web2 { .host = "1.2.3.2" ; ... }
 backend web3 { .host = "1.2.3.3" ; ... }
 backend web4 { .host = "1.2.3.4" ; ... }


 director default_director round-robin {
   { .backend = web1; }
   { .backend = web2; }
   { .backend = web3; }
   { .backend = web4; }
 }

 include "blacklist.vcl";

 sub vcl_recv
 {
     if (client.ip ~ blacklist ) {
          error 403 "You're blacklisted";
     }
     ..
 }

The blacklist entry consists of sites that I don't want to access my server, obviously.

Unfortunately my blacklist file is large, and getting larger by the day/week:

  $ wc -l varnish/blacklist.vcl 
  6664 varnish/blacklist.vcl

I've switched from blocking /32s to blocking /24s to cut down on the list, but I still find that I cannot restart varnish in less than 5 seconds.

Is there anything else that I can do to load a blacklist? I realize I could use iptables but that is also slow for such a large entry - since I have to wipe them all out and reload them when there are any changes.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

This may not be what you are looking for if you only want to solve the time it takes to restart Varnish - but for reloading configuration, I have the following solution for you;

The Varnish configuration is converted to C-source code, and compiled upon loading. So the time it takes to load the configuration includes compilation time. This is most likely what's causing the long wait for you.

You can use varnishadmin to load a new configuration, like this:

# varnishadm
vcl.load my_alias_2013-04-13 /etc/varnish/config.vcl
vcl.use my_alias_2013-04-13

The above will also produce very helpful debug information if there's something syntactically wrong with the VCL. It will not clear your cache, nor interrupt the service at all. vcl.use basically loads a built .so-file and changes some pointers in memory - making it very easy to do during runtime without having to restart the whole service.

share|improve this answer

Varnish is particularly bad with this, the C code it generates to do this is in effect a linear search -- just as bad as adding individual rules to iptables.

But, you can use iptables and make it fast too.

Use ipset instead. IPSets are fast hash lookups of ips, it is very fast for finding a ip in a large number of addresses.

Create an ipset with the command:

ipset create myset hash:ip

This will generate the set where you put your addresses.

Next, add your ips to the set..

ipset add myset 1.1.1.1
ipset add myset 1.1.1.2
ipset add myset 1.1.1.3
ipset add myset 1.1.1.4
...

Finally, add a rule to IPtables to use this set to perform a match.

iptables -N VARNISH_BL
iptables -I VARNISH_BL -m set --match-set myset src -j REJECT
iptables -I INPUT -m tcp -p tcp --dport 80 -m conntrack --ctstate NEW -j VARNISH_BL
iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

You can dump the set for later reinitialization (after a reboot for example) with ipset save myset which prints to stdout. You can also of course add more IPs to the set at any time using ipset add.

Also you might actually want your IP blacklist to auto-expire. ipset can do this too by specifying a default timeout for any IP added to the set at creation time with: ipset create myset hash:net timeout 86400

The default permits up to 65535 hosts in one set, but check the man page, you can create bigger sets using the maxelem parameter.

share|improve this answer
    
Cheer for that - because I'm running a cluster it is hard to keep iptables in sync, whereas I can commit a global blacklist.vcl to revision control and deploy that easily. Regardless I might have to explore this further. –  Steve Kemp Apr 13 '13 at 11:34
1  
conntrack-tools.netfilter.org can keep connection state in sync. As for table rules, they are pretty static since you dont need to change this setup regularly so manual changes should suffice. You could sync the ip sets using a script and a cron job. –  Matthew Ife Apr 13 '13 at 13:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.