使用ansible部署主从DNS服务器

时间:2023-01-20 22:00:48

很早之前访问网络资源可以使用IP地址,为了降低用户访问网络资源的门槛,域名系统(Domain Name System,DNS)技术应运而生。这是一项用于管理和解析域名与IP地址对应关系的技术。本次实验我将使用ansible+bind搭建DNS主、从服务器

一、 准备工作

1、 实验拓扑

::: hljs-center

使用ansible部署主从DNS服务器

:::

节点 IP地址 说明
DNS-server 192.168.0.100 DNS主服务器
DNS-slave 192.168.0.101 DNS从服务器
DNS-client 192.168.0.102 测试客户端

2、 bind软件介绍

BIND(Berkeley Internet Name Domain,伯克利因特网名称域)服务是全球范围内使用最广泛、最安全可靠且高效的域名解析服务程序。可以使用bind配置DNS主、从、缓存服务器,这里我使用bind配置DNS主服务器和从服务器。

3、 使用参数说明

参数 说明
listen-on port 53 { x.x.x.x; }; 监听ip
allow-query { x.x.x.x; }; 允许查询范围
recursion 是否支持递归查询
zone "xxx.xxx" IN {}; 域名信息

二、 ansible文件

1、 目录结构

[root@mmx_ansible dns_automating_bind]# tree .
.
├── ansible.cfg
├── inventory.yml
├── named-primary.conf.j2
├── named-secondary.conf.j2
├── primary_dns.yml
├── secondary_dns.yml
├── set_init.yml
├── test.yml
└── zone-file
    ├── mmx.com.local
    ├── mmx.com.local1
    ├── mmx.com.local2
    ├── mmx.com.local3
    └── mmx.com.zone

2、 配置文件

ansible.cfg

[defaults]
inventory=./inventory.yml
remote_user=root

3、主机清单文件

inventory.yml

dns_lab:
  hosts:
    primary_dns:
      ansible_host: 192.168.0.100
      ansible_ssh_password: XX
      ansible_user: XX
      host_name: primary_dns
    secondary_dns:
      ansible_host: 192.168.0.101
      ansible_ssh_password: XX
      ansible_user: XX
      host_name: secondary_dns
    dns_client:
      ansible_host: 192.168.0.102
      ansible_ssh_password: XX
      ansible_user: XX
      host_name: dns_client

4、 准备文件

4.1 变量说明

变量 说明
master_ip 主节点IP
slave_ip 从节点IP
type DNS服务类型

4.2 主节点配置

named-primary.conf.j2

# dns配置文件
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
	# listen-on port 53 { 192.168.0.100; };
	listen-on port 53 { {{ master_ip }} };
	listen-on-v6 port 53 { ::1; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
	statistics-file "/var/named/data/named_stats.txt";
	memstatistics-file "/var/named/data/named_mem_stats.txt";
	secroots-file	"/var/named/data/named.secroots";
	recursing-file	"/var/named/data/named.recursing";
	# allow-query     { localhost; };
	allow-query     { any; };

	/* 
	 - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
	 - If you are building a RECURSIVE (caching) DNS server, you need to enable 
	   recursion. 
	 - If your recursive DNS server has a public IP address, you MUST enable access 
	   control to limit queries to your legitimate users. Failing to do so will
	   cause your server to become part of large scale DNS amplification 
	   attacks. Implementing BCP38 within your network would greatly
	   reduce such attack surface 
	*/
	recursion yes;

	dnssec-enable yes;
	dnssec-validation yes;

	managed-keys-directory "/var/named/dynamic";

	pid-file "/run/named/named.pid";
	session-keyfile "/run/named/session.key";

	/* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
	include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
	type hint;
	file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

zone "mmx.com" IN {
        type {{ type }};
        file "mmx.com.zone";
        # 不同之处在于,如下两行允许从服务器进行通信
        allow-transfer { {{  slave_ip }} };
        also-notify { {{  slave_ip }}};
};
zone "0.168.192.in-addr.arpa" IN {
        type {{ type }};
        file "mmx.com.local";
        # 不同之处在于,如下两行允许从服务器进行通信
        allow-transfer { {{  slave_ip }} };
        also-notify { {{  slave_ip }}};
};
zone "1.1.1.in-addr.arpa" IN {
        type {{ type }};
        file "mmx.com.local1";
        # 不同之处在于,如下两行允许从服务器进行通信
        allow-transfer { {{  slave_ip }} };
        also-notify { {{  slave_ip }}};
};
zone "2.2.2.in-addr.arpa" IN {
        type {{ type }};
        file "mmx.com.local2";
        # 不同之处在于,如下两行允许从服务器进行通信
        allow-transfer { {{  slave_ip }} };
        also-notify { {{  slave_ip }}};
};
zone "3.3.3.in-addr.arpa" IN {
        type {{ type }};
        file "mmx.com.local3";
        # 不同之处在于,如下两行允许从服务器进行通信
        allow-transfer { {{  slave_ip }} };
        also-notify { {{  slave_ip }}};
};

4.3 从节点配置

named-secondary.conf.j2

# dns配置文件
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
	# listen-on port 53 { 127.0.0.1;192.168.0.1; };
	listen-on port 53 { {{ slave_ip }} };
	listen-on-v6 port 53 { ::1; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
	statistics-file "/var/named/data/named_stats.txt";
	memstatistics-file "/var/named/data/named_mem_stats.txt";
	secroots-file	"/var/named/data/named.secroots";
	recursing-file	"/var/named/data/named.recursing";
	# allow-query     { localhost; };
	allow-query     { any; };

	/* 
	 - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
	 - If you are building a RECURSIVE (caching) DNS server, you need to enable 
	   recursion. 
	 - If your recursive DNS server has a public IP address, you MUST enable access 
	   control to limit queries to your legitimate users. Failing to do so will
	   cause your server to become part of large scale DNS amplification 
	   attacks. Implementing BCP38 within your network would greatly
	   reduce such attack surface 
	*/
	recursion yes;

	dnssec-enable yes;
	dnssec-validation yes;

	managed-keys-directory "/var/named/dynamic";

	pid-file "/run/named/named.pid";
	session-keyfile "/run/named/session.key";

	/* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
	include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
	type hint;
	file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

zone "mmx.com" IN {
		# 类型修改为slave,监听masters为主DNS地址
        type {{ type }};
        file "mmx.com.zone";
        masters { {{  master_ip }} };
        also-notify { {{  master_ip }} };
};
zone "0.168.192.in-addr.arpa" IN {
		# 类型修改为slave,监听masters为主DNS地址
        type {{ type }};
        file "mmx.com.local";
        masters { {{  master_ip }} };
        also-notify { {{  master_ip }} };
};
zone "1.1.1.in-addr.arpa" IN {
		# 类型修改为slave,监听masters为主DNS地址
        type {{ type }};
        file "mmx.com.local1";
        masters { {{  master_ip }} };
        also-notify { {{  master_ip }} };
};
zone "2.2.2.in-addr.arpa" IN {
		# 类型修改为slave,监听masters为主DNS地址
        type {{ type }};
        file "mmx.com.local2";
        masters { {{  master_ip }} };
        also-notify { {{  master_ip }} };
};zone "3.3.3.in-addr.arpa" IN {
		# 类型修改为slave,监听masters为主DNS地址
        type {{ type }};
        file "mmx.com.local3";
        masters { {{  master_ip }} };
        also-notify { {{  master_ip }} };
};

4.4 正向解析文件

mmx.com.zone

; 正向解析文件
$TTL 3h
mmx.com. IN SOA ns.mmx.com. root.mmx.com.(
1
1h
2h
24h
1h)
mmx.com.        IN NS   ns.mmx.com.
ns.mmx.com.     IN A    192.168.0.100
www.mmx.com.    IN A    1.1.1.1
ftp.mmx.com.    IN A    2.2.2.2

mmx.com.        IN MX 0 mail.mmx.com.
mail.mmx.com.   IN A    3.3.3.3

www1.mmx.com.   IN CNAME www.mmx.com.
ftp1.mmx.com.   IN CNAME ftp.mmx.com.

4.5 反向解析文件

mmx.com.local

; 反向解析文件1
$TTL 3h
0.168.192.in-addr.arpa. IN SOA ns.mmx.com. root.mmx.com.(
1
1h
2h
24h
1h)

0.168.192.in-addr.arpa. IN NS  ns.mmx.com.
100.0.168.192.in-addr.arpa. IN PTR  ns.mmx.com.

mmx.com.local1

; 反向解析文件2
$TTL 3h
1.1.1.in-addr.arpa. IN SOA ns.mmx.com. root.mmx.com.(
1
1h
2h
24h
1h)

1.1.1.in-addr.arpa. IN NS  ns.mmx.com.
1.1.1.1.in-addr.arpa. IN PTR www.mmx.com.

mmx.com.local2

; 反向解析文件3
$TTL 3h
2.2.2.in-addr.arpa. IN SOA ns.mmx.com. root.mmx.com.(
1
1h
2h
24h
1h)

2.2.2.in-addr.arpa. IN NS  ns.mmx.com.
2.2.2.2.in-addr.arpa. IN PTR ftp.mmx.com.

mmx.com.local3

; 反向解析文件4
$TTL 3h
3.3.3.in-addr.arpa. IN SOA ns.mmx.com. root.mmx.com.(
1
1h
2h
24h
1h)

3.3.3.in-addr.arpa. IN NS  ns.mmx.com.
3.3.3.3.in-addr.arpa. IN PTR mail.mmx.com.

5、 playbook

5.1 主节点

primary_dns.yml

---
- name: primary server is deployed
  hosts: primary_dns
  become: yes
  vars:
    type: "master"
    master_ip: "192.168.0.100;"
    slave_ip: "192.168.0.101;"


  tasks:
    - name: bind is installed(确保bind安装)
      yum:
        name: bind
        state: present
    
    - name: named configuration is correct(修改配置文件)
      template:
        src: named-primary.conf.j2
        dest: /etc/named.conf
        owner: root
        group: named
        mode: '0640'
        setype: named_conf_t
      notify:
        - restart named
      changed_when: false
    
    - name: primary zone files are correct(主要zone文件)
      copy:
        src: zone-file/
        dest: /var/named/
        owner: root
        group: named
        mode: '0640'
        setype: named_zone_t
      notify:
        - reload named

    - name: named is started and enabled(开启&&开机启动dns服务)
      service:
        name: named
        state: started
        enabled: yes
    
    - name: firewalld is started and enabled(确保防火墙开启)
      service:
        name: firewalld
        state: restarted
        enabled: yes
    
    - name: dns is enabled on the firewalld(放行dns服务)
      ansible.posix.firewalld:
        service: dns
        state: enabled
        permanent: yes
        immediate: yes


  handlers:
      # 重启named服务
    - name: restart named
      service:
        name: named
        state: restarted

    - name: reload named
      service:
        name: named
        state: reloaded

5.2 从节点

secondary_dns.yml

---
- name: primary server is deployed
  hosts: secondary_dns
  become: yes
  vars:
    type: "slave"
    master_ip: "192.168.0.100;"
    slave_ip: "192.168.0.101;"

  tasks:
    - name: bind is installed(确保bind安装)
      yum:
        name: bind
        state: present
    
    - name: named configuration is correct(修改配置文件)
      template:
        src: named-secondary.conf.j2
        dest: /etc/named.conf
        owner: root
        group: named
        mode: '0640'
        setype: named_conf_t
      notify:
        - restart named

    - name: named is started and enabled(开启&&开机启动named服务)
      service:
        name: named
        state: started
        enabled: yes
    
    - name: firewalld is started and enabled(确保防火墙开启)
      service:
        name: firewalld
        state: started
        enabled: yes
    
    - name: dns is enabled on the firewalld(放行dns服务)
      ansible.posix.firewalld:
        service: dns
        state: enabled
        permanent: yes
        immediate: yes


  handlers:
      # 重启named服务
    - name: restart named
      service:
        name: named
        state: restarted

    - name: reload named
      service:
        name: named
        state: reloaded

6、 执行playbook

6.1 主节点

[root@mmx_ansible dns_automating_bind]# ansible-playbook primary_dns.yml 

PLAY [primary server is deployed] *****************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************
ok: [primary_dns]

TASK [bind is installed(确保bind安装)] ************************************************************************************************************************************
ok: [primary_dns]

TASK [named configuration is correct(修改配置文件)] ***********************************************************************************************************************
ok: [primary_dns]

TASK [primary zone files are correct(主要zone文件)] ***********************************************************************************************************************
ok: [primary_dns]

TASK [named is started and enabled(开启&&开机启动dns服务)] ****************************************************************************************************************
ok: [primary_dns]

TASK [firewalld is started and enabled(确保防火墙开启)] *******************************************************************************************************************
changed: [primary_dns]

TASK [dns is enabled on the firewalld(放行dns服务)] ***********************************************************************************************************************
ok: [primary_dns]

PLAY RECAP ****************************************************************************************************************************************************************
primary_dns                : ok=7    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

6.2 从节点

[root@mmx_ansible dns_automating_bind]# ansible-playbook secondary_dns.yml 

PLAY [primary server is deployed] *****************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************
ok: [secondary_dns]

TASK [bind is installed(确保bind安装)] ************************************************************************************************************************************
ok: [secondary_dns]

TASK [named configuration is correct(修改配置文件)] ***********************************************************************************************************************
ok: [secondary_dns]

TASK [named is started and enabled(开启&&开机启动named服务)] **************************************************************************************************************
ok: [secondary_dns]

TASK [firewalld is started and enabled(确保防火墙开启)] *******************************************************************************************************************
ok: [secondary_dns]

TASK [dns is enabled on the firewalld(放行dns服务)] ***********************************************************************************************************************
ok: [secondary_dns]

PLAY RECAP ****************************************************************************************************************************************************************
secondary_dns              : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

三、测试

3.1 临时修改客户端DNS地址

[root@dns_client ~]# vim /etc/resolv.conf
nameserver 192.168.0.100
nameserver 192.168.0.101

3.2 dig测试ip地址

[root@dns_client ~]# dig -x 3.3.3.3 | egrep -v '^$|^;'
3.3.3.3.in-addr.arpa.   10800   IN      PTR     mail.mmx.com.
3.3.3.in-addr.arpa.     10800   IN      NS      ns.mmx.com.
ns.mmx.com.             10800   IN      A       192.168.0.100

3.3 dig测试域名

[root@dns_client ~]# dig -t A ftp1.mmx.com | egrep -v '^$|^;'
ftp1.mmx.com.           10800   IN      CNAME   ftp.mmx.com.
ftp.mmx.com.            10800   IN      A       2.2.2.2
mmx.com.                10800   IN      NS      ns.mmx.com.
ns.mmx.com.             10800   IN      A       192.168.0.100

3.4 模拟主节点故障测试

# 停止主节点bind服务
[root@primary_dns ~]# systemctl stop named.service

# 使用nslookup测试,发现服务器地址变成从DNS服务器IP
[root@dns_client ~]# nslookup mail.mmx.com.
Server:         192.168.0.101
Address:        192.168.0.101#53

Name:   mail.mmx.com
Address: 3.3.3.3