I need to setup an authoritative DNS for 500K zones. About 90% of the zones are identical (except for the domain name of course).

I have only found PowerDNS appropriate for this task - using Pipe Backend with Perl script that answers static response for any domain as a secondary Backend.

Are there any other alternatives?


Another option might be to create a default zone file like the following:

$TTL 3600
@   IN  SOA ns1.company.com hostmaster.company.com (
@   IN  NS  ns1.company.com
@   IN  NS  ns2.company.com

@   IN  MX  10 mail.company.com

@   IN  A
www IN  A

Presuming that the above was called /etc/bind/default.zone, you can then add zone entries like:

zone "domain1.com" {
    type master;
    file "/etc/bind/default.zone";
zone "domain2.com" {
    type master;
    file "/etc/bind/default.zone";

In this case, if you query either domain1.com or domain2.com you'll get the info from the default zone.

However, please be aware, I only done this in the small scale, and it hasn't been tested with 500K zones up, so I'm not sure now Bind will structure it in memory. So for example, I'm not sure if it will only load the one zone file and point all the zones at it, or if it will load the same zone file 500K times!

  • Thinking on this further, even if the primary name server does the smart thing and only loads the one file into memory, a server you're doing an AXFR transfer wouldn't be as smart! You'd have to update zones on the different servers independent of AXFR. – Niall Donegan Jan 9 '11 at 17:32
  • It would be even better to have default zone for all unspecified domains, so only the exceptions (the 10%) are loaded. I believe I can set up slave to query master to update locale cache (no AXFR). – eitanpo Jan 9 '11 at 17:46
  • Have a look at serverfault.com/questions/132023/… – Niall Donegan Jan 9 '11 at 18:24
  • Didn't work for me. I set "." zone as master on default.txt and added the wildcard A records, but didn't get any response even for ".". I did succeed doing this with Windows DNS, but then I don't have SOA. I guess the same problem will be with BIND, even after making it work. – eitanpo Jan 10 '11 at 8:36
  • This technique is cool (I wrote an article about it in bortzmeyer.org/identical-domains-with-bind.html ) but, in 2012, you should be aware that it will not work properly with DNSSEC (because the good practice is probably to have a different key per zone). – bortzmeyer Nov 6 '12 at 21:06

I have eventually used PowerDNS, but with SQL backend. I have changed the SQL statements and added fallback to a 'default' domain if the requested domain was not found.

Works perfectly. The latency is almost never above 5 (some additional configuration tweaks are required).

  • Are you aware that with PowerDNS you can run several SQL backends - even several mysql backends - at once? Having one classically configured and one with your tweaks would enable to you superimpose the data provided there on any domain you'd need it. – ZaphodB Jul 27 '11 at 12:57
  • Yes, I aware. Using several sql backends will increase the number of queries to the database, and I have managed to limit the number of queries to minimum. – eitanpo Aug 24 '11 at 9:39

for powerdns set default a record with empty name

nano /etc/pdns/pdns.conf

gmysql-any-query=select COALESCE(b.content,c.content,d.content,e.content,f.content) content, \
COALESCE(b.ttl,c.ttl,d.ttl,e.ttl,f.ttl) ttl, \
COALESCE(b.prio,c.prio,d.prio,e.prio,f.prio) prio, \
COALESCE(b.type,c.type,d.type,e.type,f.type) type, \
COALESCE(b.domain_id,c.domain_id,d.domain_id,e.domain_id,f.domain_id) domain_id, \
a.mydomain name \
from \
(select '%s' mydomain) a \
left outer join records b on b.name = SUBSTRING_INDEX(a.mydomain, '.', -4) and b.type = 'A' \
left outer join records c on c.name = SUBSTRING_INDEX(a.mydomain, '.', -3) and c.type = 'A' \
left outer join records d on d.name = SUBSTRING_INDEX(a.mydomain, '.', -2) and d.type = 'A' \
left outer join records e on e.name = SUBSTRING_INDEX(a.mydomain, '.', -1) and e.type = 'A' \
left outer join records f on f.name = SUBSTRING_INDEX(a.mydomain, '.', 0) and f.type = 'A' \
limit 1;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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