Mirror Coordination

Bandwidth limit

You are encouraged to put some bandwidth limit on your ClamAV mirror vhost.

Many mirror sysadmins running the Apache HTTP Server find the Bandwidth Mod useful for this purpose.

Here is an example config that will do the following:

  • Limit .cvd downloads to 40KB/s
  • Limit .cdiff downloads to 400KB/s
  • Allow max 50 simultaneous connections
  • Minimum download speed 20KB/s

Apache

<IfModule mod_bw>
  BandWidthModule On
  ForceBandWidthModule On
  LargeFileLimit .cvd 1 40000
  LargeFileLimit .cdiff 1 400000
  MaxConnection all 50
  MinBandwidth all 20000
</IfModule>

Note You can also use mod_cband to limit the download-speed. The Source is available at http://sourceforge.net/projects/cband/ Just run

./configure
make
make install

Add the module to your apache-config by manually adding it to /etc/apache2/httpd.conf

LoadModule cband_module  /usr/lib/apache2/modules/mod_cband.so

Edit the config for the vhost and add

<IfModule mod_cband.c>
  CBandSpeed 20kb/s 100 300
  CBandRemoteSpeed 20kb/s 100 300
</IfModule>

This limits the download speed to 20kb/s, allows 100 requests/second and a maximum of 300 connections.

To improve mod_cband’s performance add.

CBandScoreFlushPeriod 1
CBandRandomPulse On

to /etc/httpd/conf/httpd.conf

Done. Now restart apache.

If you would like a scoreboard, set something like.

<IfModule mod_cband.c>
  CBandSpeed 20kb/s 100 300
  CBandRemoteSpeed 20kb/s 100 300
  <Location /cband-status>
    SetHandler cband-status
  </Location>
</IfModule>

Create the directory for CBandScoreboard and make it writeable by the apache-user.

 $ chown wwwrun.www /srv/www/scoreboard/

The status page can be found on http://your-domain/cband-status.

With mod_cband you can also limit the download speed based on monthly traffic or the source-ip. For more information see http://codee.pl/cband_documentation.html

Thanks to Florian Schaal

Lighttpd

$HTTP["url"] =~ "\.cvd$" {
  server.max-connections = 50
  connection.kbytes-per-second = 40
}
$HTTP["url"] =~ "\.cdiff$" {
  server.max-connections = 50
  connection.kbytes-per-second = 400
}

Nginx

location / {
  root /home/clamavdb/public_html;
  location ~ \.cvd$ {
      limit_rate 40k;
  }
  location ~ \.cdiff$ {
      limit_rate 400k;
  }
}

A customer example for Nginx

limit_conn_zone $server_port zone=cvds:1m;  
limit_conn_zone $server_port zone=cdiffs:1m;  
limit_conn_log_level info;  

server {
       server_name database.clamav.net ~^db\..*\.clamav\.net clamav.<hostname>.org;
       listen 80;

       access_log /var/log/nginx/clamav.log;

       location / {
               root /srv/www/clamav;
               index index.html;

               #deny abusers
               deny 80.66.20.180;
               deny 80.66.20.181;
               deny 194.0.92.9;

               location ~ \.cvd$ {
                       limit_conn cvds 25;
                       limit_rate 40k;
               }

               location ~ \.cdiff$ {
                       limit_conn cdiffs 5;
                       limit_rate 400k;
               }

               # deny requests from versions <= 0.88 or devel
               if ( $http_user_agent ~* "^clam(av|win)\/(0\.[67]|devel-200[0-8]|devel-0\.[0-8]).*$" ) {
                       return 404;
               }

               # deny requests from versions <= 0.94 (not supported anymore)
               if ( $http_user_agent ~* "^clam(av|win)\/(0.9[01234]).*$" ) {
                       return 404;
               }
       }
}

With this, I have two zones, which I can configure independently and where I limit CVD downloads to 25 connections with each up to 40k. The cdiffs are limited to 5 connections at a time to up to 400k each. This results in about 2MB/s or 5TB a month. If we stay way under my 10TB limit, I will allow some more connections.

The trick is to use a static value like $server_port as a counter instead of $remote_address.

Reducing traffic

The centrally maintained blacklist

We provide a configuration file for Apache and Lighttpd which lists.

  • IP addresses that are reported by our mirrors as abusers
  • obsolete ClamAV installations

The names of the files are.

  • local_blacklist_apache - written following Apache mod_access syntax, it can be used as an .htaccess file
  • local_blacklist_lighttpd - meant to be included into lighttpd config.

Our script (clam-clientsync) by default excludes all files with a local_* prefix, so you won’t see this file on your mirror.

You can write your own script to regularly download this file and use it on your webserver.

If you are running Apache and mod_access is enabled (most common setup), this can be as simple as this.

#!/bin/bash
. $HOME/etc/clam-clientsync.conf
export RSYNC_PASSWORD
rsync $RSYNC_USER@rsync.clamav.net::$MODULE/local_blacklist_apache $TO/.htaccess

Lighttpd

#!/bin/bash
. $HOME/etc/clam-clientsync.conf
export RSYNC_PASSWORD
rsync $RSYNC_USER@rsync.clamav.net::$MODULE/local_blacklist_lighttpd /path/local_blacklist_lighttpd

You will need to include local_blacklist_lighttpd into main.conf, like this.

$HTTP["host"] =~ "^(clamav\.yourhostname\.tld|.*\.clamav\.net)$" {                     
    include "/path/local_blacklist_lighttpd"

Additional tweaks

Manually blackList old versions of ClamAV

We kindly ask our mirrors to support as many old versions of ClamAV as possible. However we understand that this can eat a lot of resources and not every mirror can afford it. Hereby we provide some config. examples for various web servers.

Apache HTTP Server

SetEnvIfNoCase User-Agent "^clamav/0.6" bad_clamav 
SetEnvIfNoCase User-Agent "^clamav/devel-2008" bad_clamav
SetEnvIfNoCase User-Agent "^ClamWin/0.6" bad_clamav
<Location "/">
  Order allow,deny
  Allow from all
  Deny from env=bad_clamav
</Location>

Lighttpd

$HTTP["useragent"] =~ "^clam(av|Win)\/(0.[67]|.*devel).*$" {
  url.access-deny = ( "" )
}

Nginx

if ( $http_user_agent ~* "^clam(av|win)\/(0\.[67]|devel-200[0-8]|devel-0\.[0-8]).*$" ) {
  return 404;
}

Block outdated clients

Due to numerous connects of outdated clients (> 300,000 / day), we add single IP temporarily to the firewall.

Requirements.

Configure Apache HTTP-Server

The Access Log of apache must send to syslog-ng:

$ mknod /var/log/apache/access.log p

Apache HTTP Server (httpd.conf or vhost.conf)

The logformat and the accesslog must be defined like.

LogFormat "%h %v %l %u %t \"%r\" %>s \"%{Referer}i\" \"%{User-Agent}i\"" syslogCustomLog= =/var/log/apache2/access.log syslog

As long as the log file runs only through the pipe, no entries are stored. The configuration used here evaluates merely the log file. To receive an Access Log as a file, you must extend either syslog-ng by a destination or the apache-config by a CustomLog.

Configure syslog-ng

source s_apache_access {  pipe("/var/log/apache2/access.log");  };destination d_clamav-403 {  file("/proc/net/xt_recent/clamav-403" template("+${APACHE.SRC-IP}\n"));  };filter f_clamav_403 {  message('clamav.net')  and message(' 403 ');  };parser p_apache_src_ip {  csv-parser(columns("APACHE.SRC-IP") delimiters(': ')  flags(escape-none,greedy)  template("${MSGHDR}") );  };log {  source(s_apache_access); filter(f_clamav_403); parser(p_apache_src_ip); destination(d_clamav-403);  };

Iptables

iptables -A INPUT -p tcp --dport 80 -m recent --rcheck --name clamav-403 --seconds 3600 --hitcount 5 -j DROP

how it works

Syslog-ng filters apache messages with the contents clamav.net and 403. As destination /proc/net/xt_recent/clamav-403 is defined. The template adds the IP to the firewall. With reach from “hitcount” the IP is blocked “seconds”.

If you replace the rcheck here with an update statement, the block will last even longer. The rcheck option means: we will block you for the next hour. While update means: we don’t want to see you for an hour, but if we see you again during this time, we’ll block you again. It means that you actually need to be quiet for 60 minutes to be able to log in again.

By default xt_recent stores 100 IP addresses. You can change the limit with “modprobe ipt_recent ip_list_tot=10000” (here 10000). This is only possible before the first iptables rule is put on.

Use.

$ chmod 600 /sys/module/xt_recent/parameters/ip_list_tot
$ echo 10000 > /sys/module/xt_recent/parameters/ip_list_tot
$ chmod 400 /sys/module/xt_recent/parameters/ip_list_tot

to change ip_list_tot “on-the-fly”

If you use ipt_recent instead of xt_recent, be sure to modify the filenames and path.

Credits: Valentijn Sessink