Inhaltsverzeichnis
Raspberry PI als DNS Applicance für PowerDNS
PowerDNS
PowerDNS besteht aus dem:
- PowerDNS Server - advanced and high performance authoritative-only nameserver
- PowerDNS Recursor - high performance recursing/non authoritative name server
- Einer Datenbank wie PostgreSQL
Für Pidora steht PowerDNS als Packet zur Verfügung. Als Datenbank kommt PostgreSQL zum Einsatz
Installation
yum install pdns pdns-recursor pdns-backend-postgresql pdns-tools
Eine PostgreSQL Datenbank einrichten
DB Software installieren
yum install postgresql-server postgresql postgresql-contrib
Datenbank anlegen
Service starten und Datenbank anlegen:
systemctl enable postgresql
postgresql-setup initdb
systemctl start postgresql
Data Location: /var/lib/pgsql/data
DB anlegen:
su - postgres psql psql (9.3.4) TYPE "help" FOR help. postgres=# CREATE USER powerdns WITH PASSWORD 'powerdns1234'; postgres=# CREATE DATABASE pdns OWNER powerdns;
PowerDNS Schema Object anlegen (siehe https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/#postgresql-specifics für die aktuellste Version!):
postgres=# \connect pdns You are now connected to database "pdns" as user "postgres". #SQL block weise ausführen: CREATE TABLE domains ( id SERIAL PRIMARY KEY, 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, CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) ); CREATE UNIQUE INDEX name_index ON domains(name); CREATE TABLE records ( id SERIAL PRIMARY KEY, domain_id INT DEFAULT NULL, name VARCHAR(255) DEFAULT NULL, type VARCHAR(10) DEFAULT NULL, content VARCHAR(65535) DEFAULT NULL, ttl INT DEFAULT NULL, prio INT DEFAULT NULL, change_date INT DEFAULT NULL, disabled BOOL DEFAULT 'f', ordername VARCHAR(255), auth BOOL DEFAULT 't', CONSTRAINT domain_exists FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE, CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) ); CREATE INDEX rec_name_index ON records(name); CREATE INDEX nametype_index ON records(name,type); CREATE INDEX domain_id ON records(domain_id); CREATE INDEX recordorder ON records (domain_id, ordername text_pattern_ops); CREATE TABLE supermasters ( ip INET NOT NULL, nameserver VARCHAR(255) NOT NULL, account VARCHAR(40) NOT NULL, PRIMARY KEY(ip, nameserver) ); CREATE TABLE comments ( id SERIAL PRIMARY KEY, domain_id INT 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, CONSTRAINT domain_exists FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE, CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) ); 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 SERIAL PRIMARY KEY, domain_id INT REFERENCES domains(id) ON DELETE CASCADE, kind VARCHAR(32), content TEXT ); CREATE INDEX domainidmetaindex ON domainmetadata(domain_id); CREATE TABLE cryptokeys ( id SERIAL PRIMARY KEY, domain_id INT REFERENCES domains(id) ON DELETE CASCADE, flags INT NOT NULL, active BOOL, content TEXT ); CREATE INDEX domainidindex ON cryptokeys(domain_id); CREATE TABLE tsigkeys ( id SERIAL PRIMARY KEY, name VARCHAR(255), algorithm VARCHAR(50), secret VARCHAR(255), CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT))) ); CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm); # Ergebnis kontrollieren: pdns=# \d List of relations Schema | Name | Type | Owner --------+-----------------------+----------+---------- public | comments | table | postgres public | comments_id_seq | sequence | postgres public | cryptokeys | table | postgres public | cryptokeys_id_seq | sequence | postgres public | domainmetadata | table | postgres public | domainmetadata_id_seq | sequence | postgres public | domains | table | postgres public | domains_id_seq | sequence | postgres public | records | table | postgres public | records_id_seq | sequence | postgres public | supermasters | table | postgres public | tsigkeys | table | postgres public | tsigkeys_id_seq | sequence | postgres (13 rows) grant all on table comments to powerdns; grant all on table comments_id_seq to powerdns; grant all on table cryptokeys to powerdns; grant all on table cryptokeys_id_seq to powerdns; grant all on table domainmetadata to powerdns; grant all on table domainmetadata_id_seq to powerdns; grant all on table domains to powerdns; grant all on table domains_id_seq to powerdns; grant all on table records to powerdns; grant all on table records_id_seq to powerdns; grant all on table supermasters to powerdns; grant all on table tsigkeys to powerdns; grant all on table tsigkeys_id_seq to powerdns; pdns-# \q
DB auf localhost erlauben
vi /var/lib/pgsql/data/postgresql.conf #einkommentieren! listen_addresses='localhost' port = 5432 # aus indent wird trust! # sonst fehler "psql: FATAL: Ident authentication failed for user "powerdns"" vi /var/lib/pgsql/data/pg_hba.conf host all all 127.0.0.1/32 trust
siehe auch http://www.cyberciti.biz/tips/postgres-allow-remote-access-tcp-connection.html
Neu starten mit:
systemctl stop postgresql systemctl start postgresql systemctl status postgresql
Testen mit password Eingabe im Prompt:
psql -h localhost -d pdns -U powerdns -W
PowerDNS Dienst einrichten
Datei pdns.conf und /etc/pdns bearbeiten:
cd /etc/pdns vi pdns.conf query-local-address=192.168.178.100 # Back-end settings load-modules=gpgsql launch=gpgsql # PostgreSQL back-end settings gpgsql-host=localhost gpgsql-dbname=pdns gpgsql-user=powerdns gpgsql-password=powerdns1234
DNS Forwarding einrichten
Datei pdns.conf unter /etc/pdns bearbeiten:
cd /etc/pdns vi pdns.conf #my local internet nameserver recursor=192.168.178.1 allow-recursion=10.10.10.0/8,192.168.0.0/16 lazy-recursion=yes
testen mit:
dig @192.168.178.100 www.oracle.de
Monitoring einrichten
siehe http://doc.powerdns.com/monitoring.html
Datei pdns.conf und /etc/pdns bearbeiten:
cd /etc/pdns vi pdns.conf webserver=yes webserver-address=168.178.250 webserver-password=powerdns1234 webserver-port=8081 # Nur in Testumgebungen webserver-print-arguments=yes
webserver-print-arguments nur in Test Umgebungen verwenden! Alle Parameter inkl. passwort werden angezeigt!
Service starten
systemctl enable pdns systemctl start pdns #prüfen systemctl status pdns
Service überwachen
Ist der Webserver aktiviert kann über die URL: http:/192.168.178.100:8081/ die Monitoring Oberfläche aufgerufen werden.
User: powerdns und das zuvor in der Konfiguration gesetzte Password.
Eine erste Domain per manuell einfügen
Im folgenden Bespiel wird die notwendige DNS Auflösung für ein Oracle Real Application Cluster hinterlegt.
SQL zusammenstellen und die Daten in der DB einfügen:
#Anmelden mit Password Prompt psql -h localhost -d pdns -U powerdns -W #domain hinzufügen INSERT INTO domains(name, TYPE) VALUES('pipperr.local', 'NATIVE'); #id der DOMAIN ermitteln und merken SELECT * FROM domains; #SOA record hinzufügen INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES (1, 'pipperr.local', 'SOA', 'ns1.pipperr.local', 86400, 2015031301); #NS record INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'ns1.pipperr.local', 'NS', 'ns1.pipperr.local', 86400, 2015031301); #A record INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'ns1.pipperr.local', 'A', '192.168.178.100', 3600, 2015031301); #Einträge für das RAC Cluster IN der DOMAIN #A record für racdb01 INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'racdb01.pipperr.local' , 'A', '10.10.10.190', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'racdb01-vip.pipperr.local' , 'A', '10.10.10.192', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'racdb01-priv.pipperr.local', 'A', '10.1.1.192', 3600, 2015031301); #A record für racdb02 INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'racdb02.pipperr.local' , 'A', '10.10.10.194', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'racdb02-vip.pipperr.local' , 'A', '10.10.10.196', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'racdb02-priv.pipperr.local' , 'A', '10.1.1.196', 3600, 2015031301); #A mit doppelten Name für Oracle Scan Listener INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'scanracdb.pipperr.local', 'A', '10.10.10.200', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(1, 'scanracdb.pipperr.local', 'A', '10.10.10.210', 3600, 2015031301);
Auf die Schreibweise des Typs achten, GROSSBUCHSTABEN verwenden!
testen mit:
dig @192.168.178.100 -tAXFR pipperr.local ; <<>> DiG 9.9.4-P2-RedHat-9.9.4-12.P2.fc20 <<>> @192.168.178.100 -tAXFR pipperr.local ; (1 server found) ;; global options: +cmd pipperr.local. 86400 IN SOA ns1.pipperr.local. hostmaster.pipperr.local. 2015031301 10800 3600 604800 3600 racdb01-priv.pipperr.local. 3600 IN A 10.1.1.192 racdb01.pipperr.local. 3600 IN A 10.10.10.190 racdb02-priv.pipperr.local. 3600 IN A 10.1.1.196 racdb02-vip.pipperr.local. 3600 IN A 10.10.10.196 racdb01-vip.pipperr.local. 3600 IN A 10.10.10.192 racdb02.pipperr.local. 3600 IN A 10.10.10.194 scanracdb.pipperr.local. 3600 IN A 10.10.10.200 scanracdb.pipperr.local. 3600 IN A 10.10.10.210 ns1.pipperr.local. 3600 IN A 192.168.178.100 pipperr.local. 86400 IN NS ns1.pipperr.local. pipperr.local. 86400 IN SOA ns1.pipperr.local. hostmaster.pipperr.local. 2015031301 10800 3600 604800 3600 ;; Query time: 186 msec ;; SERVER: 192.168.178.100#53(192.168.178.100) ;; WHEN: Sat Mar 14 12:33:55 CET 2015 ;; XFR size: 12 records (messages 3, bytes 466) #alternativ abfragen mit host -l pipperr.local | sort ns1.pipperr.local has address 192.168.178.100 pipperr.local name server ns1.pipperr.local. racdb01-priv.pipperr.local has address 10.1.1.192 racdb01-vip.pipperr.local has address 10.10.10.192 racdb01.pipperr.local has address 10.10.10.190 racdb02-priv.pipperr.local has address 10.1.1.196 racdb02-vip.pipperr.local has address 10.10.10.196 racdb02.pipperr.local has address 10.10.10.194 scanracdb.pipperr.local has address 10.10.10.200 scanracdb.pipperr.local has address 10.10.10.210
Reverse DNS Einträge hinzufügen
#Reverse Einträge hinzufügen INSERT INTO domains(name, TYPE) VALUES('178.168.192.in-addr.arpa', 'NATIVE'); INSERT INTO domains(name, TYPE) VALUES('10.10.10.in-addr.arpa', 'NATIVE'); INSERT INTO domains(name, TYPE) VALUES('1.1.10.in-addr.arpa', 'NATIVE'); #id SELECT * FROM domains; #SOA INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(2, '178.168.192.in-addr.arpa','SOA', 'ns1.pipperr.local', 86400, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(2, '178.168.192.in-addr.arpa', 'NS', 'ns1.pipperr.local', 86400, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '10.10.10.in-addr.arpa' , 'SOA', 'ns1.pipperr.local', 86400, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '10.10.10.in-addr.arpa' , 'NS' , 'ns1.pipperr.local', 86400, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(4, '1.1.10.in-addr.arpa' , 'SOA', 'ns1.pipperr.local', 86400, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(4, '1.1.10.in-addr.arpa' , 'NS' , 'ns1.pipperr.local', 86400, 2015031301); #PTR INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '190.10.10.10.in-addr.arpa', 'PTR', 'racdb01.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '194.10.10.10.in-addr.arpa', 'PTR', 'racdb02.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '192.10.10.10.in-addr.arpa', 'PTR', 'racdb01-vip.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '196.10.10.10.in-addr.arpa', 'PTR', 'racdb02-vip.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '200.10.10.10.in-addr.arpa', 'PTR', 'scanracdb.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(3, '210.10.10.10.in-addr.arpa', 'PTR', 'scanracdb.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(4, '190.1.1.10.in-addr.arpa', 'PTR', 'racdb01-priv.pipperr.local', 3600, 2015031301); INSERT INTO records(domain_id, name, TYPE, content, ttl, change_date) VALUES(4, '194.1.1.10.in-addr.arpa', 'PTR', 'racdb01-priv.pipperr.local', 3600, 2015031301);
Testen mit:
dig -x 10.10.10.196 .. ;; ANSWER SECTION: 196.10.10.10.in-addr.arpa. 3600 IN PTR racdb02-vip.pipperr.local. .. host -i 10.10.10.196 196.10.10.10.in-addr.arpa domain name pointer racdb02-vip.pipperr.local.