PowerDNS-re költözés BIND/OpenDNSSEC-ről DNSSEC-el

2016. augusztus 17, 15:01 | Molnár Péter

A leírás Debian 8 (jessie) rendszerhez készült. A PowerDNS 4-es verzióját használom a fejlesztő csomagtárából.

MySQL telepítés és beállítás

apt-get install mysql-server mysql-client

A példákban a MySQL-hez csatlakozáskor használt parancs az alábbi.

mysql -u root -p

PowerDNS 4 telepítése és beállítása

echo "deb http://repo.powerdns.com/debian jessie-auth-40 main" >> /etc/apt/sources.list.d/pdns.list
wget -O - https://repo.powerdns.com/FD380FBB-pub.asc | sudo apt-key add -
echo "Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600" > /etc/apt/preferences.d/pdns
apt-get update
apt-get install pdns-server pdns-backend-mysql

https://doc.powerdns.com/md/authoritative/installation/

Az adatbázis-felhasználó létrehozása.

mysql>
create database pdns;
grant all on pdns.* to pdnsusr@localhost identified by 'pdnspw';
grant usage on *.* to pdnsusr@localhost;

https://doc.powerdns.com/md/authoritative/howtos/#basic-setup-configuring-database-connectivity

Az adatbázisséma betöltése az adatbázisba.

mysql>
CREATE TABLE domains (
 id                    INT AUTO_INCREMENT,
 name                  VARCHAR(255) NOT NULL,
 master                VARCHAR(128) DEFAULT NULL,
 last_check            INT DEFAULT NULL,
 type                  VARCHAR(6) NOT NULL,
 notified_serial       INT DEFAULT NULL,
 account               VARCHAR(40) DEFAULT NULL,
 PRIMARY KEY (id)
) Engine=InnoDB;

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
 id                    INT AUTO_INCREMENT,
 domain_id             INT DEFAULT NULL,
 name                  VARCHAR(255) DEFAULT NULL,
 type                  VARCHAR(10) DEFAULT NULL,
 content               VARCHAR(64000) DEFAULT NULL,
 ttl                   INT DEFAULT NULL,
 prio                  INT DEFAULT NULL,
 change_date           INT DEFAULT NULL,
 disabled              TINYINT(1) DEFAULT 0,
 ordername             VARCHAR(255) BINARY DEFAULT NULL,
 auth                  TINYINT(1) DEFAULT 1,
 PRIMARY KEY (id)
) Engine=InnoDB;

CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX recordorder ON records (domain_id, ordername);

CREATE TABLE supermasters (
 ip                    VARCHAR(64) NOT NULL,
 nameserver            VARCHAR(255) NOT NULL,
 account               VARCHAR(40) NOT NULL,
 PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;

CREATE TABLE comments (
 id                    INT AUTO_INCREMENT,
 domain_id             INT NOT NULL,
 name                  VARCHAR(255) NOT NULL,
 type                  VARCHAR(10) NOT NULL,
 modified_at           INT NOT NULL,
 account               VARCHAR(40) NOT NULL,
 comment               VARCHAR(64000) NOT NULL,
 PRIMARY KEY (id)
) Engine=InnoDB;

CREATE INDEX comments_domain_id_idx ON comments (domain_id);
CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);

CREATE TABLE domainmetadata (
 id                    INT AUTO_INCREMENT,
 domain_id             INT NOT NULL,
 kind                  VARCHAR(32),
 content               TEXT,
 PRIMARY KEY (id)
) Engine=InnoDB;

CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);

CREATE TABLE cryptokeys (
 id                    INT AUTO_INCREMENT,
 domain_id             INT NOT NULL,
 flags                 INT NOT NULL,
 active                BOOL,
 content               TEXT,
 PRIMARY KEY(id)
) Engine=InnoDB;

CREATE INDEX domainidindex ON cryptokeys(domain_id);

CREATE TABLE tsigkeys (
 id                    INT AUTO_INCREMENT,
 name                  VARCHAR(255),
 algorithm             VARCHAR(50),
 secret                VARCHAR(255),
 PRIMARY KEY (id)
) Engine=InnoDB;

CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

PowerDNS beállítása a MySQL backend használatára.

echo "launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=pdnsusr
gmysql-dbname=pdns
gmysql-password=pdnspw" > /etc/powerdns/pdns.d/pdns.mysettings.conf

systemctl restart pdns

Zónák importálása PowerDNS adatbázisába

zone2sql --named-conf=/etc/bind/named.conf --gmysql --slave | mysql -u pdnsusr -p pdns

https://doc.powerdns.com/md/authoritative/migration/#from-zonefiles-to-powerdns

DNSSEC beállítása, kulcsok költöztetése

A SoftHSM-ből kinyerjük a kulcsokat. A CKA_ID kell a softhsm export-hoz.

$ ods-ksmutil key list --verbose
SQLite database set to: /var/lib/opendnssec/kasp.db
Keys:
Zone:         Keytype:  State:   Date of next transition (to):  Size:  Algorithm:  CKA_ID:     Repository:  Keytag:
example.com   ZSK       active   2016-10-09 07:32:33 (retire)   1024   8           hf78o4h...  SoftHSM      64812
example.com   KSK       active   2017-06-01 11:51:39 (retire)   2048   8           3892zhr...  SoftHSM      53675

A slot-ok listájából a következő lépésben szükség lesz a Token label-re.

softhsm --show-slots
Available slots:
Slot 0
          Token present: yes
          Token initialized: yes
          User PIN initialized: yes
          Token label: OpenDNSSEC

Az id az ods-ksmutil key list --verbose parancs example.com KSK sorából származik (CKA_ID).

softhsm --export ksk.pem --slot 0 --label "OpenDNSSEC" --pin 12345678 --id 3892zhr...

https://wiki.opendnssec.org/display/DOCS/Migrating+to+OpenDNSSEC

A PEM formátumot átalakítjuk BIND formátumra és felvesszük a kulcsot.

softhsm-keyconv --tobind --in ksk.pem --name example.com --ksk --algorithm RSASHA256
pdnsutil import-zone-key example.com Kksk+008+53675.private active ksk

A többi aktív KSK-t inaktiváljuk vagy töröljük. A 12-es id csak példa.

pdnsutil list-keys example.com
pdnsutil remove-zone-key example.com 12

NSEC3 beállítások átvitele OpenDNSSEC-ből PowerDNS-be az /etc/opendnssec/kasp.xml állomány <Denial> szekciójának áttekintésével kezdődik. Az <OptOut> és <Iterations> elemek tartalma egyértelműen átvihető. A többivel kapcsolatban az RFC 5155, valamint annak 10.3-as része az irányadó.

Részlet az /etc/opendnssec/kasp.xml állományból:

...
       <Denial>
           <NSEC3>
               <TTL>PT3600S</TTL>
               <!-- <OptOut/> -->
               <Resalt>P100D</Resalt>
               <Hash>
                   <Algorithm>1</Algorithm>
                   <Iterations>5</Iterations>
                   <Salt length="8"/>
               </Hash>
           </NSEC3>
       </Denial>
...

A fentieknek megfelelő lehetséges PowerDNS beállítás (lásd man pdnsutil):

pdnsutil set-nsec3 1 0 5 abcdef01

Két PowerDNS MySQL master-slave replikációval, SSL kapcsolattal

A PowerDNS javasolt replikációs módja az adatbázis-kezelő rendszer saját replikációja.

https://doc.powerdns.com/md/authoritative/modes-of-operation/#native-replication

SSL CA és tanúsítványok létrehozása

A MySQL kiszolgálók számára tanúsítványláncot hozunk létre.

A CA létrehozása.

mkdir mysqlcerts
cd mysqlcerts/
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem

A pdns1 nevű kiszolgáló tanúsítványának létrehozása.

openssl req -newkey rsa:2048 -days 3600 -nodes -keyout pdns1-key.pem -out pdns1-req.pem
openssl rsa -in pdns1-key.pem -out pdns1-key.pem
openssl x509 -req -in pdns1-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out pdns1-cert.pem

A pdns2 nevű kiszolgáló tanúsítványának létrehozása.

openssl req -newkey rsa:2048 -days 3600 -nodes -keyout pdns2-key.pem -out pdns2-req.pem
openssl rsa -in pdns2-key.pem -out pdns2-key.pem
openssl x509 -req -in pdns2-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out pdns2-cert.pem

A tanúsítványok ellenőrzése.

openssl verify -CAfile ca.pem pdns1-cert.pem pdns2-cert.pem

https://dev.mysql.com/doc/refman/5.5/en/creating-ssl-files-using-openssl.html

MySQL replikáció beállítás master

Master kiszolgáló beállítása.

echo "[mysqld]
bind-address            = 0.0.0.0
server-id               = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = pdns
binlog_format = MIXED

ssl-ca=/etc/mysql/ca.pem
ssl-cert=/etc/mysql/pdns1-cert.pem
ssl-key=/etc/mysql/pdns1-key.pem" >> /etc/mysql/conf.d/mymaster.cnf

systemctl restart mysql
mysql>
GRANT REPLICATION SLAVE ON *.* TO 'pdnsusrslave'@'%' IDENTIFIED BY 'pdnspwslave' require ssl;
FLUSH PRIVILEGES;
use pdns;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Új shell:

mysqldump -u root -p --opt pdns > pdns.sql

Vissza a MySQL-be:

mysql>
UNLOCK TABLES;
QUIT;

MySQL replikáció beállítás slave

mysql>
CREATE DATABSE pdns;
EXIT;
mysql -u root -p pdns < pdns.sql
echo "[mysqld]
bind-address = 0.0.0.0
server-id = 2
relay-log               = /var/log/mysql/mysql-relay-bin.log
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = pdns
binlog_format = mixed

ssl-ca=/etc/mysql/ca.pem
ssl-cert=/etc/mysql/pdns2-cert.pem
ssl-key=/etc/mysql/pdns2-key.pem" >> /etc/mysql/conf.d/myslave.cnf

systemctl restart mysql
mysql>
CHANGE MASTER TO MASTER_HOST='<MASTER_HOST>',MASTER_USER='pdnsusrslave', MASTER_PASSWORD='pdnspwslave', MASTER_LOG_FILE='mysql-bin.000035', MASTER_LOG_POS=790, MASTER_SSL=1, MASTER_SSL_CA='/etc/mysql/ca.pem', MASTER_SSL_CERT='/etc/mysql/pdns2-cert.pem', MASTER_SSL_KEY='/etc/mysql/pdns2-key.pem';
START SLAVE;
SHOW SLAVE STATUS\G

Ha nem működik:

mysql>
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
SLAVE STOP;
SLAVE START;

https://dev.mysql.com/doc/refman/5.5/en/replication-solutions-secure-connections.html