Master


setuid=pdns
setgid=pdns
launch=gsqlite3
gsqlite3-database=/etc/pdns/pdns.db
experimental-json-interface=yes
experimental-api-key=changeme
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
allow-axfr-ips=10.0.0.0/8
allow-recursion=10.0.0.0/8
disable-axfr=no
experimental-logfile=/var/log/pdns.log
loglevel=5
master=yes
recursor=8.8.8.8


super Slave


slave=yes
slave-cycle-interval=10
launch=gsqlite3
gsqlite3-database=/etc/pdns/pdns.db
experimental-api-key=changeme
experimental-json-interface=yes
webserver=yes
webserver-address=0.0.0.0
recursor=8.8.8.8
guardian=yes
setuid=pdns
setgid=pdns


SQLite Schema


PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE comments (
  id                    INTEGER PRIMARY KEY,
  domain_id             INTEGER NOT NULL,
  name                  VARCHAR(255) NOT NULL,
  type                  VARCHAR(10) NOT NULL,
  modified_at           INT NOT NULL,
  account               VARCHAR(40) DEFAULT NULL,
  comment               VARCHAR(65535) NOT NULL,
  FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE cryptokeys (
 id                     INTEGER PRIMARY KEY,
 domain_id              INT NOT NULL,
 flags                  INT NOT NULL,
 active                 BOOL,
 content                TEXT,
 FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE domainmetadata (
 id                     INTEGER PRIMARY KEY,
 domain_id              INT NOT NULL,
 kind                   VARCHAR(32) COLLATE NOCASE,
 content                TEXT,
 FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE domains (
  id                    INTEGER PRIMARY KEY,
  name                  VARCHAR(255) NOT NULL COLLATE NOCASE,
  master                VARCHAR(128) DEFAULT NULL,
  last_check            INTEGER DEFAULT NULL,
  type                  VARCHAR(6) NOT NULL,
  notified_serial       INTEGER DEFAULT NULL,
  account               VARCHAR(40) DEFAULT NULL
);
CREATE TABLE records (
  id                    INTEGER PRIMARY KEY,
  domain_id             INTEGER DEFAULT NULL,
  name                  VARCHAR(255) DEFAULT NULL,
  type                  VARCHAR(10) DEFAULT NULL,
  content               VARCHAR(65535) DEFAULT NULL,
  ttl                   INTEGER DEFAULT NULL,
  prio                  INTEGER DEFAULT NULL,
  change_date           INTEGER DEFAULT NULL,
  disabled              BOOLEAN DEFAULT 0,
  ordername             VARCHAR(255),
  auth                  BOOL DEFAULT 1,
  FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE supermasters (
  ip                    VARCHAR(64) NOT NULL,
  nameserver            VARCHAR(255) NOT NULL COLLATE NOCASE,
  account               VARCHAR(40) NOT NULL
);
CREATE TABLE tsigkeys (
 id                     INTEGER PRIMARY KEY,
 name                   VARCHAR(255) COLLATE NOCASE,
 algorithm              VARCHAR(50) COLLATE NOCASE,
 secret                 VARCHAR(255)
);
CREATE INDEX comments_domain_id_index ON comments (domain_id);
CREATE INDEX comments_nametype_index ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX domainidindex ON cryptokeys(domain_id);
CREATE INDEX domainmetaidindex ON domainmetadata(domain_id);
CREATE UNIQUE INDEX ip_nameserver_pk ON supermasters(ip, nameserver);
CREATE UNIQUE INDEX name_index ON domains(name);
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX orderindex ON records(ordername);
CREATE INDEX rec_name_index ON records(name);
COMMIT;


Super Slave


INSERT INTO "supermasters" VALUES('10.0.0.11','dns1','master');


.dump


# echo ".dump" | sqlite3 /etc/pdns/pdns.db | grep 'testlocal'


INSERT INTO "records" VALUES(1,1,'testlocal','SOA','dns-1.testlocal. hostmaster.dns.testlocal. 2016010805 10800 3600 1814400 86400',86400,0,NULL,0,NULL,1);

INSERT INTO "records" VALUES(2,2,'0.0.10.in-addr.arpa','SOA','dns-1.testlocal. hostmaster.testlocal. 2016011402 10800 3600 1814400 86400',86400,0,NULL,0,NULL,1);

INSERT INTO "records" VALUES(11,1,'testlocal','NS','dns-1.testlocal',86400,0,NULL,0,NULL,1);
INSERT INTO "records" VALUES(12,1,'testlocal','NS','dns-2.testlocal',86400,0,NULL,0,NULL,1);

INSERT INTO "records" VALUES(13,1,'dns-1.testlocal','A','10.0.0.11',86400,0,NULL,0,NULL,1);
INSERT INTO "records" VALUES(14,1,'dns-2.testlocal','A','10.0.0.12',86400,0,NULL,0,NULL,1);

INSERT INTO "records" VALUES(15,2,'11.0.0.10.in-addr.arpa','PTR','dns-1.testlocal',86400,0,NULL,0,NULL,1);
INSERT INTO "records" VALUES(16,2,'12.0.0.10.in-addr.arpa','PTR','dns-2.testlocal',86400,0,NULL,0,NULL,1);


notify


# pdns_control notify testlocal
Added to queue


master
dns-2.testlocal.domain > dns-1.testlocal.18698: 26797 notify Refused*- 0/0/0 (27)

slave
dns-2.testlocal.domain > dns-1.18698: 26797 notify Refused*- 0/0/0 (27)


logs


Apr  4 12:32:59 dns-2 pdns[5539]: Done launching threads, ready to distribute questions
Apr  6 10:41:23 dns-2 pdns[5539]: Received NOTIFY for testlocal from 10.0.0.11 for which we are not authoritative
Apr  6 10:41:23 dns-2 pdns[5539]: Unable to find backend willing to host testlocal for potential supermaster 10.0.0.11. 4 remote nameservers: 
Apr  6 10:41:23 dns-2 pdns[5539]: dns-1.testlocal
Apr  6 10:41:23 dns-2 pdns[5539]: dns-2.testlocal
Apr  6 10:41:23 dns-2 pdns[5539]: 10.0.0.11
Apr  6 10:41:23 dns-2 pdns[5539]: 10.0.0.12
Apr  6 11:03:14 dns-2 pdns[5539]: AXFR of domain 'testlocal' initiated by 10.0.0.11
Apr  6 11:03:14 dns-2 pdns[5539]: AXFR of domain 'testlocal' denied: client IP 10.0.0.11 has no permission
Apr  6 11:03:14 dns-2 pdns[5539]: AXFR of domain 'testlocal' failed: 10.0.0.11 cannot request AXFR