Host your own DNS with PowerDNS on CentOS 7

First tutorial for LET, please let me know where I can improve.

Host your own DNS with PowerDNS on CentOS 7

This tutorial will show you how to configure your own DNS server on CentOS 7 using PowerDNS.

Step 1. Prereqs

We will run PowerDNS with the MySQL backend, so we must install and configure that first.

Step 1.1 Install MariaDB

MariaDB is a replacement for MySQL used by CentOS.

First install MariaDB.

yum install mariadb-server mariadb

Then enable it and start it.

# systemctl enable mariadb

# systemctl start mariadb

Step 1.2 Configure MariaDB

mysql_secure_installation

Answer the default to all questions, and make a root password and write it down.

Step 2. Prepare the repositories and install PowerDNS

PowerDNS is available in the CentOS repos, but it is an old version. So let's grab the updated one from PowerDNS's repo.

# yum install epel-release yum-plugin-priorities

# curl -o /etc/yum.repos.d/powerdns-auth-40.repo https://repo.powerdns.com/repo-files/centos-auth-40.repo

# yum install pdns pdns-backend-mysql

This downloads and installs the epel repository, then the PowerDNS repository, then installs pdns and the mysql plugin.

Step 3. Configre the database

Step 3.1 Configure a MySQL database and user for PowerDNS

# mysql -u root -p

Then enter your MySQL root password you created earlier.

Execute the following commands:

CREATE DATABASE powerdns;

CREATE USER 'powerdns'@'localhost' IDENTIFIED BY 'mysecretpassword';

GRANT ALL PRIVILEGES ON powerdns.* TO 'powerdns'@'localhost';

Step 3.2 Configure the PowerDNS database

Execute the following commands, still in the MySQL shell. Copy and pasting is recommended.

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 BIGINT 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);

You can then execute the following to quit the MySQL shell.

quit;

Step 4. Configure PowerDNS

Open the configuration file using vi or nano. It is located at /etc/pdns/pdns.conf

Locate the line that says launch= and change it to launch=gmysql

Then add the following 4 lines

gmysql-host=127.0.0.1
gmysql-user=powerdns
gmysql-dbname=powerdns
gmysql-password=mysecretpassword

Replace the password with the one that you created earlier for the PowerDNS user.

Step 5. Enable and start PowerDNS

# systemctl enable pdns

# systemctl start pdns

Step 6. Allow through the firewall

If you're using firewalld, you'll have to execute:

# firewall-cmd --permanent --add-service=dns

# firewall-cmd --reload

Congrats, you now have a functioning DNS server! To add entries, I recommend using a frontend such as PowerDNS-Admin, which can be found at https://github.com/ngoduykhanh/PowerDNS-Admin

Top News