Private nameservers are for local, internal use by an organization. SURBL public nameservers are generously run by a network of volunteers at ISPs, universities, Internet security companies, and other organizations for the benefit of the Internet community. Servers are generally located in large, well-connected datacenters. SURBL data are made available via free, public DNS queries for small- to medium-sized organizations of fewer than 1,000 users. Larger organizations or commercial applications should sign up for data feed access and mirror the zone file locally as described here.
The multi.surbl.org zone file is about 100 megabytes in size and may take up to an hour to rsync the first time. Later rsyncs complete within a minute and use a few tens to hundreds of kbytes to transfer file differences.
/usr/local/sbin/rbldnsd \
-u rbldns:rbldns \
-r /usr/local/etc/rbldnsd \
-b 10.10.10.10/53 \
-a \
multi.surbl.org:dnset:multi.surbl.org.rbldnsd \
multi.surbl.org:acl:surbl.org.acl
(Replace 10.10.10.10 with your nameserver IP address.)
multi.surbl.org is the only zone that should be served or used by applications.
The -a option allows rbldnsd to not serve authority information, which is appropriate since the servers are already known as authoritative due to the delegations from the parent zone. As a result of -a, the size of replies will be decreased dramatically, significantly reducing network traffic by eliminating this large amount of unnecessary information.
-c and -t options are strictly-speaking not necessary since the checking interval for new zone files is 1 minute by default, and the SURBL zone files include TTLs for all records, overriding command-line -t values.
For a private nameserver the config would look something like:
/usr/local/sbin/rbldnsd \
-u rbldns:rbldns \
-r /usr/local/etc/rbldnsd \
-b 10.10.10.10/53 \
-a \
surbl.internal.mydomain.com:dnset:multi.surbl.org.rbldnsd
Where the public nameserver ACL would not be used,
and where the domain should be your own domain or subdomain,
ideally one not visible from the outside world.
The IP would usually be from your LAN or intranet.
#!/bin/tcsh # rsync the zone files only if this program is not already running if ( -z /usr/local/etc/rbldnsd/lockfile ) then echo "rsync is running" > /usr/local/etc/rbldnsd/lockfile /usr/local/bin/rsync -aq "server.name.here::surbl/multi.surbl.org.rbldnsd" /usr/local/etc/rbldnsd/ /usr/local/bin/rsync -aq "server.name.here::surbl/surbl.org.acl" /usr/local/etc/rbldnsd/ echo -n "" > /usr/local/etc/rbldnsd/lockfile endifIt only rsyncs if a lockfile is empty.
#!/bin/bash
LOCK_DIR="/tmp"
basename=$(basename $0)
print_usage() {
echo "Usage: ${basename} [-s sleep [-t timeout] "
echo "Run COMMAND with simple file locking. "
echo " -s sleep"
echo " Sleep between 0 and the number of seconds specified before running command."
echo " -t timeout"
echo " Attempt to kill the old process if the lock is older than the specified number of seconds."
echo
exit
}
while [ "${1}" == "-s" ] || [ "${1}" == "-t" ]; do
opt="${1}"
shift
if [ -z "$(expr "${1}" + 0)" ] || [ "${1}" -lt 0 ]; then
echo "Invalid number of seconds."
print_usage
fi
case "${opt}" in
"-s") sleep="${1}" ;;
"-t") timeout="${1}" ;;
esac
shift
done
if [ -z "$*" ]; then
print_usage
else
cmd=$*
fi
# set timeout to zero if not set
if [ -z "${timeout}" ]; then
timeout=0
fi
lock="${LOCK_DIR}/$(basename ${1}).$(echo ${cmd} | md5sum | cut -d" " -f1).lock"
# remove stale lock file
if [ "${timeout}" -gt 0 ]; then
if [ -f "${lock}" ]; then
rm "${lock}" && echo "removed stale lock ${lock}"
fi
elif (find -wholename "${lock}" -mmin +$(( ${timeout}/60 )) ) 2> /dev/null; then
rm "${lock}" && echo "removed stale lock ${lock}: more than $(( ${timeout}/60 )) minutes old"
fi
# if no lock, write lock and do work
if (set -o noclobber; echo -n > "${lock}") 2> /dev/null; then
echo $$ >> "${lock}"
echo $(date +%s) >> "${lock}"
echo $cmd >> "${lock}"
if [ "${sleep}" -gt 0 ]; then
sleep $(expr ${RANDOM} % ${sleep})
fi
${cmd}
rm "${lock}"
elif [ -n "${timeout}" ]; then
read -d! lockpid locktime lockcmd < <(cat "${lock}" 2>/dev/null || echo NOFILE 0 0)
if [ -n "$(expr "${locktime}" + 0)" ] && [ $(( $(date +%s)-${locktime} )) -gt "${timeout}" ]; then
# Try to kill grand children, children and then parent
pkill -P $(pgrep -d, -P ${lockpid}) > /dev/null 2>&1 || \
pkill -P ${lockpid} > /dev/null 2>&1 || \
(kill ${lockpid}; rm "${lock}") > /dev/null 2>&1
fi
fi
1/5 * * * * rbldns lockf -st0 /var/run/rsync_surbl.lock /usr/local/sbin/rsync_surbl.sh
It's also possible to have a split horizon function using BIND forwarding to an internal IP on a server that runs both BIND and rbldnsd on different IPs. In that case the internal uses would query the internal IP and public uses would query the public IP. Using different internal and public IPs facilitates isolating the traffic and functions, and it makes setting up different firewall policies simpler. Since DNS runs on port 53 and rsync on port 873 traffic can and should be isolated by port in your firewall.
The main issue is the rare DDOS attack against the public nameservers. This really hasn't happened to any major extent, but if it does, it can be useful to block the (abusive) public DNS queries while still allowing internal DNS queries and rsync of the zone files for internal use.
surbl.internal.mydomain.com:dnset:multi.surbl.org.rbldnsdThe mapping above would tell rbldnsd to serve the contents of the multi.surbl.org rbldnsd zone file using a different domain name: surbl.internal.mydomain.com. The local mail filtering application would need to be configured to query the data using surbl.internal.mydomain.com as the list name.
You should use an internal domain that's not visible to the outside world. This will also prevent anyone outside from querying your internal mirror, as would using non-routable network numbering, appropriate firewall policies, etc. For a private nameserver, the internal domain name should match in all of the places appropriate to your particular system:
dig test.surbl.org.multi.surbl.org @your.server.hereAlso test some web sites seen in recent unsolicited messages, for example, domain_to_test.com.multi.surbl.org (For private nameservers use your internal surbl domain name instead of multi.surbl.org.)
dig multi.surbl.org @your.server.here soato confirm that the zone files are updating and have a recent serial number compared to any of the other public nameservers. If the zone file serial numbers are not updating then the cron job or rsync are not working correctly. (For private nameservers use your internal surbl domain name instead of multi.surbl.org.)
However to see some general statistics about how much trafffic is being generated and how much ham and spam is being detected, install a monitoring script which feeds into a monitoring and graphing program such as MRTG.
Unrelated to rbldnsd, there are many stats programs for SpamAssassin that will show the relative performance of the different rules, including those using SURBLs. Links to many of the stats programs can be found at the SpamAssassin site.
It is also possible to use BIND to serve the zones directly, but rbldnsd is much more CPU- and memory-efficient than BIND.
In other words, when rbldnsd is running on its own IP address, set it up as an entirely independent name server, even if it happens to run on a server also running BIND (on a different address). For public nameservice, SURBL will delegate DNS traffic for the SURBL zones to the IP address rbldnsd is bound to.
If using BIND 8 and a separate IP address for rbldnsd, be sure to set the listen-on option in order to tell BIND not to listen on the address that you intend to run rbldnsd on. This is explained in the NJABL rbldnsd document and in SURBL's rbldnsd with BIND on FreeBSD document.