自学内容网 自学内容网

安装部署PowerDNS--实现内网DNS解析

PDNS是PowerDNS的缩写,是一个开源的DNS服务器软件。PowerDNS具有高性能、灵活性和可扩展性,可用于搭建各种规模的DNS解析服务。它支持多种后端数据库(如MySQL、PostgreSQL等),提供高度定制化的配置选项,并具有强大的扩展性和插件系统。PowerDNS还支持DNSSEC(DNS安全扩展)和其他先进的DNS功能,使其成为许多组织和服务提供商的首选DNS解决方案之一。

  • 部署mysql, 本文中pdns采用mysql作为后端记录存储数据库
[root@pdns131 ~]# wget http://repo.mysql.com/mysql57-community-release-el7-11.noarch.rpm
[root@pdns131 ~]# rpm -ivh mysql57-community-release-el7-11.noarch.rpm
[root@pdns131 ~]# yum -y install mysql-community-server --nogpgcheck
[root@pdns131 ~]# service mysqld  start
[root@pdns131 ~]# cat /var/log/mysqld.log  找到默认的密码
[root@pdns131 ~]# mysql -uroot -p
如果直接修改密码,Mysql默认安全机制极高,需要有大小写,数字,特殊符号等复杂程度组合,这时我们需要修改下Mysql的安全配置
mysql> set global validate_password_policy = 0;   ---安全机制降低
mysql> set global validate_password_length = 4;   --长度修改4位
mysql> set password = password('test123');   --- 设置Mysql密码
mysql> show variables like 'validate_password%';  ---查看配置是否生效
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'test123' WITH GRANT OPTION; 

mysql> create database powerdns;
mysql> CREATE USER 'powerdns'@'%' IDENTIFIED BY 'test123';
mysql> GRANT ALL on powerdns.* to 'powerdns'@'%';
mysql> grant process on powerdns.* to powerdns@'%';
mysql> flush privileges;

  • 下载pdns repo源
[root@pdns131 ~]# yum install epel-release yum-plugin-priorities -y
[root@pdns131 ~]# curl -o /etc/yum.repos.d/powerdns-auth-49.repo https://repo.powerdns.com/repo-files/centos-auth-49.repo
  • 安装pdns及其关联包
[root@pdns131 ~]# yum install pdns pdns-recursor pdns-backend-mysql -y
  • 基于之上部署的mysql,初始化pdns相关数据库和表
[root@pdns131 ~]# mysql -uroot -ptest123
mysql> create database powerdns;
mysql> use powerdns
mysql> source /usr/share/doc/pdns-backend-mysql-4.9.1/schema.mysql.sql
mysql> ALTER TABLE records ADD COLUMN create_time  timestamp NULL DEFAULT CURRENT_TIMESTAMP  AFTER auth;   -- 添加create_time字段记录加入解析的记录时间 (可选)
  • 修改pdns配置文件, 添加如下内容
[root@pdns131 ~]# grep -v '#' /etc/pdns/pdns.conf

# 如下两行默认已存在
setgid=pdns
setuid=pdns

# 添加如下内容
#数据库设置
launch=gmysql
gmysql-host=127.0.0.1
gmysql-dbname=powerdns
gmysql-user=powerdns
gmysql-password=test123
gmysql-port=3306

#DNS服务监听设置
local-address=0.0.0.0
local-port=54

#api及web服务配置
api=yes
api-key=qwerasdf
webserver=yes
webserver-address=0.0.0.0
# 如果pdns-admin docker部署在这个pdns节点上,可能会不走192.168网段,需要设置为0.0.0.0
webserver-allow-from=0.0.0.0/0  
webserver-port=8081

# 只有这些 IP 地址或网络掩码将能够执行 不带 TSIG 的 AXFR,0.0.0.0/0表示全部。
allow-axfr-ips=192.168.1.0/24
# 允许来自这些 IP 范围的 DNS 更新。0.0.0.0/0表示全部。
allow-dnsupdate-from=192.168.1.0/24, 192.169.0.0/16

log-dns-queries=yes
log-dns-details=yes
log-timestamp=yes

Master pdns 节点,需要在pdns.conf里面加入如下配置. slave节点不需要

primary=yes

# 每300s检测一次,如果有记录更新,那么就去同步slave (有更新时,主从同步周期,需要设置also-notify)
xfr-cycle-interval=300
also-notify=192.168.1.132:54, 192.168.1.133:54

# 添加之后可以手动采用pdns_control notify xxx.com来同步zone
# 不加此行,也可以通过pdns_control notify-host xxx.com 192.168.1.132:54来同步zone

slave pdns节点,需要在pdns.conf里面添加如下配置. master节点不需要

secondary=yes
  • 开启pdns服务
[root@pdns131 ~]# systemctl enable pdns --now

补充:如果一个pdns节点即作为master,又作为slave,那么可同时配上primary=yes和secondary=yes,以及作为master时需要同步的also-notify、xfr-cycle-interval 。对于这个pdns节点来讲,有的域名我是master,有的域名我是slave(特殊需求章节可以使用)

pdns部署策略

pdns部署策略,主要两种:

  1. native模式,见pdns-admin章节第5步,创建domain时,类型选择为navtive。部署多套单节点pdns,后端mysql数据库采用主从同步。当一个节点修改后(更新mysql数据库),其他节点自动也查到最新的解析结果。这种方式不建议跨机房部署
  2. master/slave模式,

见pdns-admin章节第5步,创建damain时,类型选择对应的master/slave。采用pdns的axfr同步,配置后之后。pdns会周期性的检测序列号有没更新,如果发现更新,则同步给slave pdns。(本质是把自己mysql库里面的关联域名的记录全部刷到slave pdns的mysql数据库)

注:

  • 检测序列记录在对应域名SOA记录的content字段里面,第3段,下面截图900前面那个
  • 创建domain时,SOA-EDIT-API

不要选择DEFAULT(下图日期这种),尾巴两位是当天的自增,如果修改超过99次,会覆盖前面的日期位,第二天再操作时会被复位。要选择INCREASE。

pdns主从同步方式

pdns有多种主从同步方式,可以自动,也可以手动,也可以定期扫描差异后notify slave pdns。本质上是将主pdns对应的后端mysql记录,同步到slave pdns的对应数据库里面去(删除域名下所有的记录,插入全部的新的)

方式一:主pdns对应后端数据库里面的域名SOA记录content字段,第4个部分为主从同步周期,默认为为10800(3个小时),可以修改成1800s或者3600s(自动同步)。

方式二:pdns主配置文件里面配置also-notify (slave pdns的ip:port)和 xfr-cycle-interval (同步周期),建议设置为300/600, (自动同步)

方式三:手动同步,pdns.conf里面设置了pdns的角色之后primary/secondary 之后,使用pdnsutil命令来。(手动同步)

  例如:

pdns_control notify xxx.compdns_control notify-host xxx.com 192.168.1.132:54 (slave ip:port)

方式四:在slave pdns节点对应的pdns-admin里面手动点击同步。见 pdns-admin章节第8步 (手动同步)

pdns-admin部署

pdns-admin是一个基于Web的管理界面,用于管理PowerDNS(pdns)服务器。它提供了一个直观的用户界面,让您可以轻松地管理您的DNS服务器和域名记录。通过pdns-admin,您可以执行诸如添加、编辑和删除DNS记录.

  • 部署docker
[root@pdns131 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@pdns131 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@pdns131 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@pdns131 ~]# sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
[root@pdns131 ~]# yum -y install docker-ce docker-compose
l
[root@pdns131 ~]# systemctl start docker
[root@pdns131 ~]# systemctl enable docker
[root@pdns131 ~]# docker network create pdns
[root@pdns131 ~]# vi /etc/docker/daemon.json
[root@pdns131 ~]# cat /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.agsvpt.work",
        "https://docker.agsv.top",
        "https://mirror.baidubce.com",
        "https://registry.docker-cn.com",
        "https://docker.m.daocloud.io",
        "https://hub-mirror.c.163.com"
    ],
    "insecure-registries": []
}

[root@pdns131 ~]# systemctl daemon-reload
[root@pdns131 ~]# systemctl restart docker
  • 拉取pdns-amdin镜像及运行
[root@pdns131 ~]# mkdir /data/pdnsadmin/data -p
[root@pdns131 ~]# chmod 777 /data/pdnsadmin/data -R
[root@pdns131 ~]# mkdir /root/pdns-admin -p
[root@pdns131 ~]# cd /root/pdns-admin
[root@pdns131 pdns-admin]# vi docker-compose.yml
[root@pdns131 pdns-admin]# cat docker-compose.yml
---
version: '3'

services:
  powerdnsadmin:
    hostname: pdnsadmin
    container_name: pdnsadmin
    image: ngoduykhanh/powerdns-admin:0.3.0
    restart: always
    ports:
      - 9191:80
    networks:
      - pdns
    volumes:
      - /data/pdnsadmin/data:/data
    logging:
      driver: json-file
      options:
        max-file: '3'
        max-size: '10m'

networks:
  pdns:
    driver: bridge


[root@pdns131 pdns-admin]# docker-compose up -d
  • 配置pdns-admin

首次运行,需要在登录页创建一个管理员账号,打开http://192.168.1.131:9191/login,点击Create an account,创建即可。创建完成后使用此账号登录

  • 设置pdns api的地址和api key,在pdns.conf文件里面可以找到对应的端口和api key值。

Slave 节点部署pdns-admin,需要配置slave节点的api地址和对应的api-key

  • 添加一个master域,type选择master (主pdns节点的pdns-admin操作)

  • 进入mysql数据库,修改records表的SOA记录属性(非必须,建议修改)

可以看到有一条SOA记录,content的10800为主从pdns数据自动同步周期,3个小时时间太长,可以修改为15分钟或者其他时长。

mysql> select * from records;   
mysql> update records set content=REPLACE(content,10800,900) where type='SOA' and name='testabc.com';

SOA content:

primary: default-soa-name 表示该Zone的解析服务器
hostmaster: hostmaster@domain-name 表示该域名的所有者, 该信息的第一个点表示为@
serial(序列号): 是域名记录的版本,每更改一次域名的任何DNS记录,版本号就会自动加一,这时secondary dns就会知道DNS记录发生更改,以便重新同步。
refresh(刷新时间): 告诉secondary dns多久应该查询primary dns,看看DNS记录是否有更新。每次查询时,secondary dns会向primary dns请求SOA记录。如果记录中的serial number跟secondary dns已有的序列号不一样,则会向primary dns请求传送域名的当前的DNS记录。
retry(重试时间): 如果想primary dns请求传送域名当前的DNS记录失败后,间隔重试时间后再次重试请求。一般来说,retry小于refresh。
expire:(过期时间): 在过期时间之前,secondary dns会继续请求DNS记录,并且在此时间里,secondary dns会根据已有的记录应答相关的DNS查询。如果到了过期时间后,secondary dns会停止应答该域名的DNS查询。
default_ttl 域名所有记录的最小生存时间值。当用户DNS查询到记录后,将存在缓存中,直到至少过了这个时间才将缓存刷新重新查询。
  • 然后就可以添加解析记录了(要先save,再apply changes,否则不会保存)

以上主节点pdns-admin已配置完成。

  • slave节点部署pdns-admin

从节点后续只是添加/删除dns的时候会用到pdns-admin,此操作可以用命令替代。平时基本不用到,可以不用部署pdns-admin. slave pdns-admin只能查看,不可编辑记录

如需部署,方法和主节点一样,只是在第4和第5步有所差异,见截图。打开从节点的pdns-admin地址,例如http://192.168.1.132:9191/login

设置pdns 节点api信息

如果slave节点不部署pdns-admin,可以参考create-secondary-zone/delete-zone命令进行操作。

常用参考命令:

列出域名所有解析:pdnsutil list-zone testxxx.com

添加A记录:pdnsutil add-record testaaa.com www A 300 10.100.100.102 (TTL: 300)

删除A记录:pdnsutil delete-rrset testaaa.com www A

创建native域:pdnsutil create-zone testxxx.com (native类型)

创建master域:(没有直接创建master域的命令。需要先建native域,转成master,然后设置SOA-EDIT-API属性)

pdnsutil create-zone testxxx.com

pdnsutil set-kind testxxx.com primary

pdnsutil set-meta testxxx.com SOA-EDIT-API INCREASE (此步需要操作,否则没有自增序号,影响主从同步)

创建slave域:pdnsutil create-secondary-zone testttt.com 192.168.1.131:54 (指定主pdns节点/端口)

删除域名:pdnsutil delete-zone testxxx.com

pdns-recursor 部署

pdns-recursor是PowerDNS项目中的一部分,是一个高性能的递归DNS解析器。它设计用于处理递归DNS查询,为客户端提供DNS解析服务。pdns-recursor具有缓存功能,可以提高性能并减少对上游DNS服务器的查询次数。它还支持DNSSEC(DNS安全扩展)和其他安全功能,可以提供更安全的DNS解析服务。

建议每个pdns搭配一个pdns-recursor。通过recursor配置文件的recursor.forward_zones.forwarders转发给pdns来进行解析处理。未匹配到的,递归到外部处理。

  • 下载pdns-recursor repo源
[root@pdns131 ~]# curl -o /etc/yum.repos.d/powerdns-rec-51.repo https://repo.powerdns.com/repo-files/el-rec-51.repo
  • 安装pdns-recursor
[root@pdns131 ~]# yum install pdns-recursor -y
  • 配置pdns-recursor
[root@pdns131 ~]# cat /etc/pdns-recursor/recursor.conf
dnssec:
  validation: off
incoming:
  listen:
    - 0.0.0.0:53
    - '[::]:53'
  allow_from: [127.0.0.0/8, 10.0.0.0/8]
recursor:
  extended_resolution_errors: true
  forward_zones:
    - zone: testabc.com
      forwarders:
        - 192.168.1.131:54
        - 192.168.1.132:54
        - 192.168.1.133:54
      recurse: true
      notify_allowed: true

    - zone: testxxx.cn
      forwarders:
        - 192.168.130.1
      recurse: true
      notify_allowed: true

  forward_zones_recurse: [{zone: xx.testabc.com, forwarders: [ 192.168.130.1 ] }, {zone: ., forwarders: [ 223.5.5.5, 114.114.114.114 ] }]


outgoing:
  # source_address:
  #  - 0.0.0.0
  #  - '::'
logging:
  loglevel: 6
  quiet: false
  # trace: yes

###注意###
# dnssec.validation 建议设置为off。 DNSSEC 通过建立一个直到根 DNS 名称服务器的信任链来防止中间人攻击。这个信任链确保访问者要求的 DNS 记录在途中没有被篡改。

# incoming.allow_from 为允许过来查询的段
# recursor.forward_zones.zone.forwarders 表示要把这个域名转到具体的ip:port。可以配多个,其中某个不可用之后,仍然可以解析,建议这里配多个后端pdns
# 转发可以通过forward_zones 的zone来进行配置,也可以通过forward_zones_recurse里面写具体的域名。 数组里面的顺序不影响。 最后的zone: . 转发不要写到forward_zones里面,否则影响解析结果
# logging.quiet, 默认为true,建议设置为false,否则看不到日志。日志记录在/var/log/messages
# logging.trace, 需要调试看详细日志的时候打开,日常运行不需要打开,否则日志非常多。此配置项调试问题很有用

# pdns-recursor, 只要节点联网,如果没有找到要转发的域,自动转发到外网,不用额外配置转发目的dns
# 设置{zone: ., forwarders: [ 223.5.5.5, 114.114.114.114 ] } 是为了在没有匹配到的时候,递归给指定的dns处理。否则会由recursor启动时获取到的其他dns ip处理(可打开logging.trace 分析解析过程)

# 改了配置,不要用systemctl restart,可能不生效。最好先stop,然后再start
  • 开启pdns-recursor
[root@pdns131 ~]# systemctl enable pdns-recursor --now
  • 在TTL时间内,会直接将缓存的结果响应回去,如果想清理本地的缓存,可以使用rec_control
# 清除 www.example.com 域名缓存
[root@pdns131 pdns]# rec_control wipe-cache www.example.com

# 如果需要清除相关域名的所有记录,如某些子域 example.com的子域,在名称后面加上 $ 
[root@pdns131 pdns]# rec_control wipe-cache example.com$

# DNS缓存记录转存
[root@pdns131 pdns]# rec_control dump-cache /tmp/cache

dnsdist 部署

dnsdist是一个高性能的、轻量级的DNS负载均衡器和DNS解析器。它通常用于在大规模的DNS环境中分发和负载均衡DNS请求,以提高性能和可用性。

  • 下载dnsdist repo源
[root@pdns227 ~]# curl -o /etc/yum.repos.d/powerdns-dnsdist-19.repo https://repo.powerdns.com/repo-files/el-dnsdist-19.repo
  • 安装dnsdist
[root@pdns227 ~]# yum install dnsdist -y
  • 配置dnsdist,cat /etc/dnsdist/dnsdist.conf 基于实际情况添加如下内容
-- 设置监听端口
addLocal("0.0.0.0:53",{ reusePort=true })

-- 设置ACL,允许列表内的IP来进行解析
setACL({'10.0.0.0/8', '192.168.0.0/16'})

-- 设置下游转发和缓存服务器,qps=100 限制qps为100
-- dnsdist每秒对各个后端recursor/dns进行探活,如果采用dnsdist -> recursor -> pdns。只探活到recursor的ip&端口,后端pdns不可达时,仍然会给到这个active的recursor, recursor后端的pdns建议配多个
newServer({address="192.168.1.131"})
newServer({address="192.168.1.132", qps=100})
newServer({address="192.168.1.133"})


-- setServerPolicy 定义负载均衡策略
-- 查询将被发送到第一个可用的服务器, 基本都给到第一个,不推荐
-- setServerPolicy(firstAvailable)

-- 查询将被发送到当前具有最少未完成查询的服务器,实测一段时间,可能把流量都给到某一个, 不推荐
-- setServerPolicy(leastOutstanding)

-- 循环轮询, (分配相对均匀,但是缓存效率会打折, 但是负载很均匀) 推荐
-- setServerPolicy(roundrobin)

-- 随机发送给可用的服务器, 对于某域名可能在节点1的缓存,但是随机到节点2来解析,又得缓存。(分配相对均匀,但是缓存效率会打折) 推荐
-- setServerPolicy(wrandom)

-- whash,类似weighted policy,激活节点不变,固定域名(固定hash值)会被固定dns节点解析. 推荐
setServerPolicy(whashed)

-- chash,固定域名(固定hash值)会被固定dns节点解析, 实测,三个节点分配不均匀,不推荐
-- setServerPolicy(chashed)


-- 开启webserver 主要是放开接口,Prometheus拿监控数据
-- webserver("127.0.0.1:8083")

-- 设置webserver配置
-- setWebserverConfig({password=hashPassword("test.com123"), apiKey=hashPassword("xxdfadsfdsgldsgh2xxx"), acl="10.0.0.0/8"})


-- 添加域名欺骗
addAction(AndRule({QTypeRule(DNSQType.A), makeRule('xx.testabc.com')}),SpoofAction("172.17.10.10"))
  • 开启dnsdist
[root@pdns227 ~]# systemctl enable dnsdist --now

特殊需求: 多个解析ip,随机的返回其中一个

  • pdns配置文件里面配置enable-lua-records=yes
  • 数据库records表插入对应的lua解析记录,例如:

INSERT INTO records (domain_id, name, type, content, ttl)

VALUES ( 6, 'www.testabc.com', 'LUA',

'A "pickclosest({''192.168.1.110'',''192.168.1.111'',''192.168.1.112'',''10.100.96.15''})"',

300

);


原文地址:https://blog.csdn.net/liuy5277/article/details/140472354

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!