静看光阴荏苒
不管不顾不问不说也不念

Docker部署PowerDNS Authoritative Server

我几年前写过一篇部署PowerDNS权威服务器的文章,最近需要搭建一个,然后翻出来看了下发现写的不够完善,而且纯手动部署太麻烦了,遂决定重新记录下使用Docker部署的步骤,另外主要补充一下:主从同步、DNSSEC的配置。

首先还是需要到域名注册商添加胶水记录(Glue Record),我使用的是spaceship,这家的用户面板不叫胶水记录,叫个人名称服务器,说实话有时候挺烦这种自己瞎起名字的行为。。害我在他们的这个面板里面找半天:

由于spaceship的限制,这里至少要添加2条胶水记录,如果你不打算部署2台服务器(主从同步),可以把两条记录的值都指向同一台服务器的IP,之后更改域名的NS服务器为刚设置的“个人名称服务器”:

本文示例:91.99.72.72为主(primary)服务器,49.13.168.202为从(secondary)服务器,在两台服务器内都安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

在主(primary)服务器创建目录新建compose文件:

mkdir /opt/pdns-mysql && cd /opt/pdns-mysql && nano docker-compose.yml

写入如下内容,需要修改的地方写了注释:

services:
  mariadb:
    image: mariadb:lts
    container_name: pdns-mariadb
    restart: unless-stopped
    networks:
      - pdns
    environment:
      - MARIADB_ROOT_PASSWORD=setyourpdnsmasterdbpassword # 设置数据库ROOT用户的密码
    volumes:
      - ./mariadb-data:/var/lib/mysql:Z
    healthcheck:
      test: ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized']
      timeout: 10s
      retries: 5

  phpmyadmin:
    image: phpmyadmin
    restart: unless-stopped
    networks:
      - pdns
    ports:
      - 8988:80
    environment:
      - PMA_HOST=mariadb

  pdns-master:
    image: pschiffe/pdns-mysql:latest
    container_name: pdns-master
    hostname: ns1.ohsb.cc # 设置PDNS主服务器的主机名,务必与你的胶水记录保持一致
    restart: unless-stopped
    networks:
      pdns:
        ipv4_address: 172.89.64.74
    depends_on:
      mariadb:
        condition: service_healthy
    environment:
      - PDNS_gmysql_host=mariadb
      - PDNS_gmysql_port=3306
      - PDNS_gmysql_user=root
      - PDNS_gmysql_password=setyourpdnsmasterdbpassword # 设置连接数据库ROOT用户的密码
      - PDNS_gmysql_dbname=powerdns
      - PDNS_gmysql_dnssec=yes
      - PDNS_primary=yes
      - PDNS_api=yes
      - PDNS_api_key=setyourpdnsapikey # 设置PDNS API KEY
      - PDNS_webserver=yes
      - PDNS_webserver_address=0.0.0.0
      - PDNS_webserver_allow_from=0.0.0.0/0,::/0
      - PDNS_webserver_password=setyourwebserverpassword # 设置PDNS WEB密码
      - PDNS_version_string=anonymous
      - PDNS_default_ttl=1500
      - PDNS_allow_axfr_ips=49.13.168.202 # 设置为从服务器的公网IP
      - PDNS_only_notify=49.13.168.202 # 设置为从服务器的公网IP
    ports:
      - '53:53'
      - '53:53/udp'
      - '8081:8081'
    volumes:
      - /etc/localtime:/etc/localtime:ro

  pdns-admin:
    image: pschiffe/pdns-admin
    container_name: pdns-admin
    restart: unless-stopped
    depends_on:
      mariadb:
        condition: service_healthy
    networks:
      - pdns
    ports:
      - '8989:8080'
    environment:
      - PDNS_ADMIN_SQLA_DB_HOST=mariadb
      - PDNS_ADMIN_SQLA_DB_PORT=3306
      - PDNS_ADMIN_SQLA_DB_USER=root
      - PDNS_ADMIN_SQLA_DB_PASSWORD=setyourpdnsmasterdbpassword # 设置连接数据库ROOT用户的密码
      - PDNS_ADMIN_SQLA_DB_NAME=powerdnsadmin
      - PDNS_API_URL="http://pdns-master:8081/"
      - PDNS_API_KEY=setyourpdnsapikey # 设置连接到PDNS Master的API KEY
      - PDNS_VERSION=5.0
    volumes:
      - /etc/localtime:/etc/localtime:ro

networks:
  pdns:
    ipam:
      config:
        - subnet: 172.89.0.0/16
          gateway: 172.89.0.1

在从(secondary)服务器创建目录新建compose文件:

mkdir /opt/pdns-slave && cd /opt/pdns-slave && nano docker-compose.yml

写入如下内容,需要修改的地方写了注释:

services:
  mariadb:
    image: mariadb:lts
    container_name: pdns-mariadb
    restart: unless-stopped
    networks:
      - pdns
    environment:
      - MARIADB_ROOT_PASSWORD=setyourpdnsmasterdbpassword # 设置数据库ROOT用户的密码
    volumes:
      - ./mariadb-data:/var/lib/mysql:Z
    healthcheck:
      test: ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized']
      timeout: 10s
      retries: 5

  phpmyadmin:
    image: phpmyadmin
    restart: unless-stopped
    networks:
      - pdns
    ports:
      - 8988:80
    environment:
      - PMA_HOST=mariadb

  pdns-slave:
    image: pschiffe/pdns-mysql:latest
    container_name: pdns-slave
    hostname: ns2.ohsb.cc # 设置PDNS从服务器的主机名,务必与你的胶水记录保持一致,从服务器必须设置,否则无法与主服务器同步!
    restart: unless-stopped
    networks:
      pdns:
        ipv4_address: 172.89.64.75
    depends_on:
      mariadb:
        condition: service_healthy
    environment:
      - PDNS_gmysql_host=mariadb
      - PDNS_gmysql_port=3306
      - PDNS_gmysql_user=root
      - PDNS_gmysql_password=setyourpdnsmasterdbpassword # 设置连接数据库ROOT用户的密码
      - PDNS_gmysql_dbname=powerdnsslave
      - PDNS_gmysql_dnssec=yes
      - PDNS_secondary=yes
      - PDNS_autosecondary=yes
      - PDNS_webserver=yes
      - PDNS_webserver_address=0.0.0.0
      - PDNS_webserver_allow_from=0.0.0.0/0,::/0
      - PDNS_webserver_password=setyourwebserverpassword # 设置PDNS WEB密码
      - PDNS_version_string=anonymous
      - PDNS_default_ttl=1500
      - PDNS_disable_axfr=yes
      - PDNS_allow_notify_from=91.99.72.72 # 设置为主服务器的公网IP
      - SUPERMASTER_IPS=91.99.72.72 # 设置为主服务器的公网IP
    ports:
      - '53:53'
      - '53:53/udp'
      - '8081:8081'
    volumes:
      - /etc/localtime:/etc/localtime:ro

networks:
  pdns:
    ipam:
      config:
        - subnet: 172.89.0.0/16
          gateway: 172.89.0.1

配置项太多,这里我也懒得详细说明了,打字太累= =为了方便理解,我没有给敏感内容(域名、服务器IP等信息)脱敏,这套配置是我目前从测试服务器1:1复制下来的。只要你按照注释来配置,肯定能跑起来的,并且功能都是正常的。

启动主、从服务器的所有服务:

docker compose up -d

配置DNSSEC,首先打开PowerDNS-Admin(91.99.72.72:8989)注册一个账号,第一个注册的账号自动成为管理员。

在PowerDNS-Admin添加Zone,Zone Name:你的域名,Zone Type选择:Primary,一定要选择Primary,Primary,Primary!

按如图所示添加2条NS记录以及2条A记录:

启用DNSSEC:

会回显类似如图的信息:

DNSKEY不用管,你可以简单理解为这是公钥。我们需要注意的是DS下面的内容,这实际上代表两条DS记录:

41411 13 2 48e9394892ee2da8...
41411 13 4 9a9382822735e648...

41411是“密钥标签”,13是“算法”,2和4是“摘要类型”,后面一长串是“摘要”。按照这个格式在spaceship内添加两条DS记录:

实际上只添加一条DS记录也是可以的,这个取决于你自己。检查DNSSEC是否生效,可以安装如下软件包:

apt install bind9-dnsutils

测试:

delv ns1.ohsb.cc
delv ns2.ohsb.cc

如果输出的内容有fully validated,则说明DNSSEC工作正常:

检查主从同步是否正常,可以使用compose内部署的phpmyadmin登录到服务器数据库,查看两个数据库内的数据是否一致:

总结下部署过程中遇到的问题。从服务器无法同步,报错:

Unable to find backend willing to host ohsb.cc for potential autoprimary 91.99.72.72. Remote nameservers

这是从服务器的Docker容器没有设置正确的hostname导致的,见此issue

在spaceship设置了DNSSEC的DS记录后,spaceship面板的DNS传播状态异常。这是由于PowerDNS内的NS记录配置错误导致的。我在spaceship配置了两个NS服务器,那么PowerDNS-Admin内也应该有两条NS记录,必须要保持一致。

参考资料:

https://hub.docker.com/r/pschiffe/pdns-mysql
https://github.com/pschiffe/docker-pdns/blob/master/docker-compose-mysql.yml
https://doc.powerdns.com/authoritative/settings.html
https://doc.powerdns.com/authoritative/backends/generic-mysql.html#gmysql-dnssec

赞(0)
未经允许不得转载:荒岛 » Docker部署PowerDNS Authoritative Server
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

分享创造快乐

广告合作资源投稿