=====Raspberry PI als DNS Applicance für PowerDNS=====
=== PowerDNS ===
PowerDNS besteht aus dem:
* PowerDNS Server - advanced and high performance authoritative-only nameserver
* https://doc.powerdns.com/md/recursor/
* PowerDNS Recursor - high performance recursing/non authoritative name server
* https://doc.powerdns.com/md/authoritative/
* Einer Datenbank wie PostgreSQL
* https://doc.powerdns.com/md/authoritative/backend-generic-mypgsql/
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.
==== GUI====
* https://github.com/PowerDNS/pdnscontrol
=== Unter Linux x86 ===
siehe => [[linux:power_dns|PowerDNS - Ein Alternative für BIND unter Linux 6]]
==== Quellen ====
Siehe:
* https://www.powerdns.com/downloads.html
* https://doc.powerdns.com/md/
PowerDNS mit PostGreSQL
* http://www.mad-hacking.net/documentation/linux/applications/dns/index.xml
PostGreSQL
* https://fedoraproject.org/wiki/PostgreSQL