Hello,
I've been messing with the DLZ engines in Bind to move my DNS system to a MySQL database. I've run up against a snag in this process.
I want to run two separate instances of the mysql dlz engine. Why? Because I am also using my DNS server as an effective network-wide spam-blocker. I have a mySQL database containing a list of domain names of known spam sites. Basically, I have a dlz configuration wherein it simply looks up the domain to see if it's in the list; if so, it returns static values redirecting accesses to 127.0.0.1. Additionally, I then want a "real" DNS database with actual IPs and hostnames for my local network.
Take a look at this setup:
Code:
options {
directory "/home/named";
pid-file "/var/run/named/named.pid";
forwarders {
208.67.222.222;
216.114.192.10;
};
recursion yes;
};
dlz "AdBlockZone" {
database "mysql
{socket=/var/run/mysql/mysql.sock host=localhost dbname=dns user=dns pass=***}
{select d from spam_domains where d = '%zone%'}
{select '127.0.0.1' /* null address '%record%', '%zone%' */}
{select ttl, type, data, resp, serial, refresh, retry, expire, minimum from spam_auth /* pseudo authority for %zone% */}
";
};
dlz "MySQLMain" {
database "mysql
{socket=/var/run/mysql/mysql.sock host=localhost dbname=dns user=dns pass=***}
{select d from domains where d = '%zone%'}
{select ttl,type,data from records where domain = '%zone%' and host = '%record%'}
{select ttl, type, data, resp, serial, refresh, retry, expire, minimum from records where host = '%host%' and (type = 'SOA$
";
};
The first dlz definition is for my ad blocking database. Notice how it simply requests if the domain exists in the "spam" table; if so, it returns the IP of the local host. (The spam_auth table is a static table of a pseudo-authority recordset to satisfy named.) The second dlz definition is for my actual DNS records.
(By the way, those comments on the sql statements for the adblocking zone are to satisfy the engine's need to find the reference tokens in the SQL statement. It wouldn't start if I didn't put those there, stating "couldn't find required token %zone%" or whatever)
To help people understand, spam_domains is simply a table like thos:
Code:
+--------------------------+
| d |
+--------------------------+
| ad.doubleclick.net |
| www.gatorcorporation.com |
+--------------------------+
(except that it's 10,000+ records long!)
When I try to run named with this configuration, I get:
Code:
Jun 3 01:21:44 millions named[10963]: starting BIND 9.5.0 -u named
Jun 3 01:21:44 millions named[10963]: loading configuration from '/etc/named.conf'
Jun 3 01:21:44 millions named[10963]: /etc/named.conf:19: 'dlz' redefined near 'dlz'
Jun 3 01:21:44 millions named[10963]: loading configuration: already exists
Jun 3 01:21:44 millions named[10963]: exiting (due to fatal error)
Me being big on efficiency, it seems pointless to add a huge load of records to my MySQL databases just to represent the over 10,000 blocked ad domains, and still use that same database to store my actual DNS records. Not to mention being a serious PITA to manage my own DNS records, this would slow down access to actual DNS records.
What I'd expect is that BIND would try the first dlz def; if it can't get a result from it, try the second, and so on. Is BIND really limited to just one dlz definition? If so, what's my solution? I thought about running *two* BINDs and forwarding one to the other but this seems inefficient as well.
If I remove either dlz definition the other one works without problems. I simply want it to first look at my own domains, if it doesn't find it there look in the ad blocking set, if it doesn't find it there hit the forwarders.
So, to sum it up: Can BIND 9 accept two external dynamic DNS lookups in one server?
Thanks for your help,
FM