This commit is contained in:
Christoph Wiechert 2017-01-15 22:41:17 +01:00
commit 44392c0404
6 changed files with 437 additions and 0 deletions

2
.gitignore vendored Normal file

@ -0,0 +1,2 @@
.idea

32
Dockerfile Normal file

@ -0,0 +1,32 @@
FROM alpine
MAINTAINER Christoph Wiechert <wio@psitrax.de>
ENV REFRESHED_AT="2017-01-17" \
POWERDNS_VERSION=4.0.2 \
MYSQL_AUTOCONF=true \
MYSQL_HOST="mysql" \
MYSQL_PORT="3306" \
MYSQL_USER="root" \
MYSQL_PASS="root" \
MYSQL_DB="pdns"
RUN apk --update add mysql-client mariadb-client-libs libpq sqlite-libs libstdc++ libgcc && \
apk add --virtual build-deps \
g++ make mariadb-dev postgresql-dev sqlite-dev curl boost-dev && \
curl -sSL https://downloads.powerdns.com/releases/pdns-$POWERDNS_VERSION.tar.bz2 | tar xj -C /tmp && \
cd /tmp/pdns-$POWERDNS_VERSION && \
./configure --prefix="" --exec-prefix=/usr --sysconfdir=/etc/pdns \
--with-modules="bind gmysql gpgsql gsqlite3" --without-lua && \
make && make install && cd / && \
mkdir -p /etc/pdns/conf.d && \
addgroup -S pdns 2>/dev/null && \
adduser -S -D -H -h /var/empty -s /bin/false -G pdns -g pdns pdns 2>/dev/null && \
apk del --purge build-deps && \
rm -rf /tmp/pdns-$POWERDNS_VERSION /var/cache/apk/*
ADD schema.sql pdns.conf /etc/pdns/
ADD entrypoint.sh /
EXPOSE 53/tcp 53/udp
ENTRYPOINT ["/entrypoint.sh"]

56
README.md Normal file

@ -0,0 +1,56 @@
# PowerDNS Docker Container
[![Docker Stars](https://img.shields.io/docker/stars/psitrax/powerdns.svg)]()
[![Docker Pulls](https://img.shields.io/docker/pulls/psitrax/powerdns.svg)]()
[![Docker Automated buil](https://img.shields.io/docker/automated/psitrax/powerdns.svg)]()
[![ImageLayers Size](https://img.shields.io/imagelayers/image-size/psitrax/powerdns/latest.svg)]()
* Small Alpine based Image
* MySQL (default), Postgres, SQLight and Bind backend included
* Automatic MySQL database initialization
* Latest PowerDNS version (if not pls file an issue)
* Guardian process enabled
* Graceful shutdown using pdns_control
## Usage
```shell
# Start a MySQL Container
$ docker run -d \
--name pdns-mysql \
-e MYSQL_ROOT_PASSWORD=supersecret \
-v $PWD/mysql-data:/var/lib/mysql \
mariadb:10.1
$ docker run --name pdns \
--link pdns-mysql:mysql \
-p 53:53 \
-p 53:53/udp \
-e MYSQL_USER=root \
-e MYSQL_PASS=supersecret \
psitrax/powerdns \
--cache-ttl=120 \
--allow-axfr-ips=127.0.0.1 123.1.2.3
```
## Configuration
**Environment Configuration:**
* MySQL connection settings
* `MYSQL_HOST=mysql`
* `MYSQL_USER=root`
* `MYSQL_PASS=root`
* `MYSQL_DB=pdns`
* Want to disable mysql initialization? Use `MYSQL_AUTOCONF=false`
* Want to use own config files? Mount a Volume to `/etc/pdns/conf.d` or simply overwrite `/etc/pdns/pdns.conf`
**PowerDNS Configuration:**
Append the PowerDNS setting to the command as shown in the example above.
See `docker run --rm psitrax/powerdns --help`
## Maintainer
* Christoph Wiechert <wio@psitrax.de>

52
entrypoint.sh Executable file

@ -0,0 +1,52 @@
#!/bin/sh
set -e
# --help, --version
[ "$1" = "--help" ] || [ "$1" = "--version" ] && exec pdns_server $1
# treat everything expect -- as exec cmd
[ "${1:0:2}" != "--" ] && exec "$@"
# Set MySQL Credentials in pdns.conf
if $MYSQL_AUTOCONF ; then
sed -r -i "s/^[# ]*gmysql-host=.*/gmysql-host=${MYSQL_HOST}/g" /etc/pdns/pdns.conf
sed -r -i "s/^[# ]*gmysql-port=.*/gmysql-port=${MYSQL_PORT}/g" /etc/pdns/pdns.conf
sed -r -i "s/^[# ]*gmysql-user=.*/gmysql-user=${MYSQL_USER}/g" /etc/pdns/pdns.conf
sed -r -i "s/^[# ]*gmysql-password=.*/gmysql-password=${MYSQL_PASS}/g" /etc/pdns/pdns.conf
sed -r -i "s/^[# ]*gmysql-dbname=.*/gmysql-dbname=${MYSQL_DB}/g" /etc/pdns/pdns.conf
fi
MYSQLCMD="mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASS -r -N"
# wait for Database come ready
isDBup () {
echo "SHOW STATUS" | $MYSQLCMD 1>/dev/null
echo $?
}
RETRY=10
until [ `isDBup` -eq 0 ] || [ $RETRY -le 0 ] ; do
echo "Waiting for database to come up"
sleep 5
RETRY=$(expr $RETRY - 1)
done
if [ $RETRY -le 0 ]; then
>&2 echo Error: Could not connect to Database on $MYSQL_HOST:$MYSQL_PORT
exit 1
fi
# init database if necessary
echo "CREATE DATABASE IF NOT EXISTS $MYSQL_DB;" | $MYSQLCMD
MYSQLCMD="$MYSQLCMD $MYSQL_DB"
if [ "$(echo "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = \"$MYSQL_DB\";" | $MYSQLCMD)" -le 1 ]; then
echo Initializing Database
cat /etc/pdns/schema.sql | $MYSQLCMD
fi
trap "pdns_control quit" SIGHUP SIGINT SIGTERM
pdns_server "$@" &
wait

205
pdns.conf Normal file

@ -0,0 +1,205 @@
# allow-axfr-ips Allow zonetransfers only to these subnets
# allow-axfr-ips=0.0.0.0/0
# allow-recursion List of subnets that are allowed to recurse
#################################
allow-recursion=127.0.0.1
# allow-recursion-override Set this so that local data fully overrides the recursor
# allow-recursion-override=no
# cache-ttl Seconds to store packets in the PacketCache
cache-ttl=60
# chroot If set, chroot to this directory for more security
# chroot=/var/empty
# config-dir Location of configuration directory (pdns.conf)
config-dir=/etc/pdns
include-dir=/etc/pdns/conf.d
# config-name Name of this virtual configuration - will rename the binary image
# config-name=
# control-console Debugging switch - don't use
# control-console=no
# daemon Operate as a daemon
daemon=no
# default-soa-name name to insert in the SOA record if none set in the backend
# default-soa-name=a.misconfigured.powerdns.server
# default-ttl Seconds a result is valid if not set otherwise
# default-ttl=3600
# disable-axfr Disable zonetransfers but do allow TCP queries
disable-axfr=no
# disable-tcp Do not listen to TCP queries
# disable-tcp=no
# distributor-threads Default number of Distributor (backend) threads to start
distributor-threads=1
# do-ipv6-additional-processing Do AAAA additional processing
# do-ipv6-additional-processing=no
# fancy-records Process URL and MBOXFW records
# fancy-records=no
# guardian Run within a guardian process
guardian=yes
# launch Which backends to launch and order to query them in
launch=gmysql
#gmysql-host=mysql
#gmysql-port=3306
#gmysql-dbname=pdns
#gmysql-user=root
#gmysql-password=root
#gmysql-dnssec=no
# lazy-recursion Only recurse if question cannot be answered locally
# lazy-recursion=yes
# load-modules Load this module - supply absolute or relative path
# load-modules=
# local-address Local IP addresses to which we bind
local-address=0.0.0.0
# local-ipv6 Local IP address to which we bind
# local-ipv6=
# local-port The port on which we listen
local-port=53
# log-dns-details If PDNS should log DNS non-erroneous details
# log-dns-details=
# log-failed-updates If PDNS should log failed update requests
# log-failed-updates=
# logfile Logfile to use (Windows only)
# logfile=pdns.log
# logging-facility Log under a specific facility
# logging-facility=
# loglevel Amount of logging. Higher is more. Do not set below 3
loglevel=3
# master Act as a master
master=yes
# max-queue-length Maximum queuelength before considering situation lost
# max-queue-length=5000
# max-tcp-connections Maximum number of TCP connections
# max-tcp-connections=10
# module-dir Default directory for modules
# module-dir=/usr/lib/pdns
# negquery-cache-ttl Seconds to store packets in the PacketCache
negquery-cache-ttl=60
# no-shuffle Set this to prevent random shuffling of answers - for regression testing
# no-shuffle=off
# out-of-zone-additional-processing Do out of zone additional processing
# out-of-zone-additional-processing=yes
# pipebackend-abi-version Version of the pipe backend ABI
# pipebackend-abi-version=1
# query-cache-ttl Seconds to store packets in the PacketCache
# query-cache-ttl=20
# query-local-address Source IP address for sending queries
# query-local-address=
# query-logging Hint backends that queries should be logged
# query-logging=no
# queue-limit Maximum number of milliseconds to queue a query
# queue-limit=1500
# recursive-cache-ttl Seconds to store packets in the PacketCache
# recursive-cache-ttl=10
# recursor If recursion is desired, IP address of a recursing nameserver
# recursor=no
# send-root-referral Send out old-fashioned root-referral instead of ServFail in case of no authority
# send-root-referral=no
# setgid If set, change group id to this gid for more security
setgid=pdns
# setuid If set, change user id to this uid for more security
setuid=pdns
# skip-cname Do not perform CNAME indirection for each query
# skip-cname=no
# slave Act as a slave
# slave=no
# slave-cycle-interval Reschedule failed SOA serial checks once every .. seconds
# slave-cycle-interval=60
# smtpredirector Our smtpredir MX host
# smtpredirector=a.misconfigured.powerdns.smtp.server
# soa-expire-default Default SOA expire
# soa-expire-default=604800
# soa-minimum-ttl Default SOA mininum ttl
# soa-minimum-ttl=3600
# soa-refresh-default Default SOA refresh
# soa-refresh-default=10800
# soa-retry-default Default SOA retry
# soa-retry-default=3600
# soa-serial-offset Make sure that no SOA serial is less than this number
# soa-serial-offset=0
# socket-dir Where the controlsocket will live
socket-dir=/var/run
# strict-rfc-axfrs Perform strictly rfc compliant axfrs (very slow)
# strict-rfc-axfrs=no
# trusted-notification-proxy IP address of incoming notification proxy
# trusted-notification-proxy=
# urlredirector Where we send hosts to that need to be url redirected
# urlredirector=127.0.0.1
# version-string PowerDNS version in packets - full, anonymous, powerdns or custom
version-string=powerdns
# webserver Start a webserver for monitoring
webserver=no
# webserver-address IP Address of webserver to listen on
# webserver-address=127.0.0.1
# webserver-password Password required for accessing the webserver
# webserver-password=
# webserver-port Port of webserver to listen on
# webserver-port=8081
# webserver-print-arguments If the webserver should print arguments
# webserver-print-arguments=no
# wildcard-url Process URL and MBOXFW records
# wildcard-url=no

90
schema.sql Normal file

@ -0,0 +1,90 @@
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);