dns基础知识

https://github.com/skyao/learning-dns

SRV

DNS SRV 是 DNS 记录中一种,用来查询指定服务的地址。与常见的A记录、CNAME 不同的是,SRV中除了记录服务器的地址,还记录了服务的端口,并且可以设置每个服务地址的优先级和权重。RFC-2782 给出DNS SRV的建议标准,它是在2000年的时候提出来的。
访问服务的时候,本地的服务从 DNS 服务器查询到一个地址列表,根据优先级和权重,从中选取一个地址作为本次请求的目标地址。
一个支持SRV的 LDAP client 通过查询域名,可以得知 LDAP 服务的 IP 地址和服务端口:

  1. _ldap._tcp.example.com

这个域名的格式是 rfc-2782 中推荐的格式,_ldap表示LDAP服务,_tcp表示通过TCP协议访问LDAP服务。
SRV 的 DNS 类型代码为 33。SRV的记录格式为:

  1. _Service._Proto.Name TTL Class SRV Priority Weight Port Target
  2. Service: 服务名称,前缀“_”是为防止与DNS Label(普通域名)冲突。
  3. Proto: 服务使用的通信协议,_TCP_UDP、其它标准协议或者自定义的协议。
  4. Name: 提供服务的域名。
  5. TTL: 缓存有效时间。
  6. CLASS: 类别
  7. Priority: 该记录的优先级,数值越小表示优先级越高,范围0-65535
  8. Weight: 该记录的权重,数值越高权重越高,范围0-65535
  9. Port: 服务端口号,0-65535
  10. Target: host 地址。

客户端查询到多条记录的时候,使用优先级最高的记录。对相同优先级的记录,按照权重选择,记录的权重越高,被选择的可能性越高。
选择的时候,将所有记录的权重值累加,得到一个选择区间[0,sum],每个记录在[0,sum]中占据一段连续的、长度为自身权重值区间。然后生成一个[0,sum]中的随机数,随机数落在的区间所属的记录就是被选择的记录。

注意事项

  1. 在使用DNS SRV的时候,要注意DNS Client是否按照预期的方式处理收到的SRV记录。当前DNS SRV只能够负责提供服务地址列表,对这个列表如何解读,完全取决于Client的实现。
  2. rfc-1035中规定,通过UDP协议传输DNS响应时,UDP报文的负载不能超过512字节,在添加 SRV 记录的时候,要特别注意。通过TCP传输时没有512字节的限制。
  3. 当一个服务地址有多个相同优先级的SRV记录的时候,Client会按照这些SRV的权重分配请求。下一次向服务发起的请求可能发送到了不同的地址。
  4. 在通过SRV记录的权重来分配请求的时候,使用的是本地缓存的DNS记录,所以不能实时地感知到服务的地址列表变化。除非将 TTL 设置的非常短暂,但这样将会频繁地查询DNS服务器。

    Client查询服务地址的过程

    rfc-2782中已经做了很好地介绍,这里就不表述了。

    配置举例

    下面是DNS中 master file,可以看到有 example.com 域名提供了一个名为_foobar._tcp 的服务,这个服务有两个 SRV 记录,分别指向了 sys-box.example.com:1099 和 server.example.com:1099
    1. $ORIGIN example.com.
    2. @ SOA server.example.com. root.example.com. (
    3. 2019030102 3600 3600 604800 86400 )
    4. NS server.example.com.
    5. NS ns1.ip-provider.net.
    6. NS ns2.ip-provider.net.
    7. ;
    8. _foobar._tcp SRV 0 1 1099 slow-box.example.com.
    9. SRV 0 3 1099 fast-box.example.com.
    10. ; if neither slow-box or fast-box is up, switch to
    11. ; using the sys-box and the server
    12. SRV 1 0 1099 sys-box.example.com.
    13. SRV 1 0 1099 server.example.com.
    14. server A 172.30.79.10
    15. slow-box A 10.30.79.11
    16. sys-box A 10.30.79.12
    17. fast-box A 10.30.79.13
    18. ; NO other services are supported
    19. *._tcp SRV 0 0 0 .
    20. *._udp SRV 0 0 0 .

    Debian系列

    1. 安装

  1. apt-get update
  2. apt-get install bind9

2. 配置缓存转发

打开打开/etc/bind/named.conf.options,修改后如下:

  1. acl goodclients {
  2. 192.168.1.0/24;
  3. localhost;
  4. localnets;
  5. };
  6. options {
  7. directory "/var/cache/bind";
  8. // If there is a firewall between you and nameservers you want
  9. // to talk to, you may need to fix the firewall to allow multiple
  10. // ports to talk. See http://www.kb.cert.org/vuls/id/800113
  11. // If your ISP provided one or more IP addresses for stable
  12. // nameservers, you probably want to use them as forwarders.
  13. // Uncomment the following block, and insert the addresses replacing
  14. // the all-0's placeholder.
  15. // forwarders {
  16. // 0.0.0.0;
  17. // };
  18. //========================================================================
  19. // If BIND logs error messages about the root key being expired,
  20. // you will need to update your keys. See https://www.isc.org/bind-keys
  21. //========================================================================
  22. dnssec-validation auto;
  23. auth-nxdomain no; # conform to RFC1035
  24. listen-on-v6 { any; };
  25. //added
  26. listen-on { 192.168.1.110;};
  27. recursion yes ;
  28. allow-query { goodclients;};
  29. allow-transfer { none; }; # disable zone transfers by default
  30. forwarders {
  31. 223.5.5.5; # alidns
  32. 223.6.6.6; # alidns
  33. };
  34. forward only ;
  35. };

3. 配置local文件

named.conf.local 文件默认是空的。本文在配置文件中分别定义一条正向解析一条反向解析。配置文件修改后类似如下:

  1. //domain->ip
  2. zone "local.com" in {
  3. type master;
  4. file "/var/cache/bind/db.local.com";
  5. };
  6. //ip->domain
  7. zone "1.168.192.in-addr.arpa" in {
  8. type master;
  9. file "/var/cache/bind/reverse/db.1.168.192";
  10. };

4. 定义区域配置文件

配置文件定义后类似如下,分别是正向和反向两个解析记录。按照自己需求修改相应的区域和区域解析记录,IP等信息。

正向记录
sudo vim /var/cache/bind/db.local.com

  1. $TTL 604800
  2. @ IN SOA local.com. root.local.com. (
  3. 2 ; Serial
  4. 604800 ; Refresh
  5. 86400 ; Retry
  6. 2419200 ; Expire
  7. 604000) ; Negative Cache TTL
  8. ;
  9. ; name servers
  10. @ IN NS ns.local.com.
  11. @ IN A 192.168.1.110
  12. ;ns records
  13. ns IN A 192.168.1.110
  14. ;host records
  15. www IN A 192.168.1.110
  16. api IN A 192.168.1.100

反向记录
sudo vim /var/cache/bind/db.1.168.192

  1. $TTL 604800
  2. @ IN SOA local.com. root.local.com. (
  3. 2 ; Serial Number
  4. 604800 ; Refresh
  5. 86400 ; Retry
  6. 2419200 ; Expire
  7. 86400 ); ; Minimum
  8. @ IN NS local.com.
  9. 66 IN PTR www.local.com.
  10. 66 IN PTR api.local.com.

5. 检查配置、重启

  1. hejun@ubuntu:/var/cache/bind$named-checkconf
  2. hejun@ubuntu:/var/cache/bind$named-checkzone local.com /var/cache/bind/db.local.com
  3. zone local.com/IN: loaded serial 2
  4. OK
  5. hejun@ubuntu:/var/cache/bind$named-checkzone db.1.168.192 /var/cache/bind/db.1.168.192
  6. zone db.1.168.192/IN: loaded serial 2
  7. OK

分别检查了语法和区域配置文件,没有报错。重启bind服务。

  1. sudo service bind9 restart

到这里DNS服务器的配置就完成了,可以使用dig命令测试。

6.配置路由器首选DNS

Ubuntu20.04为例
修改/etc/resolvconf/resolv.conf.d/head 文件

  1. # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
  2. # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
  3. # 127.0.0.53 is the systemd-resolved stub resolver.
  4. # run "systemd-resolve --status" to see details about the actual nameservers.
  5. # 添加自定义的dns地址即可,优先级从上到下
  6. nameserver 192.168.1.110

使配置生效

  1. resolvconf -u
  2. sysetmctl restart network # 或是NetworkManager,看具体情况

上面的更改不太对,应该修改/etc/systemd/resolved.conf

  1. # Entries in this file show the compile time defaults.
  2. # You can change settings by editing this file.
  3. # Defaults can be restored by simply deleting this file.
  4. #
  5. # See resolved.conf(5) for details
  6. [Resolve]
  7. DNS=192.168.0.159
  8. DNS=114.114.114.114
  9. FallbackDNS=1.1.1.1
  10. #Domains=
  11. #LLMNR=no
  12. #MulticastDNS=no
  13. #DNSSEC=no
  14. #DNSOverTLS=no
  15. #Cache=no-negative
  16. #DNSStubListener=yes
  17. #ReadEtcHosts=yes

重启systemd-resolve

  1. systemd restart systemd-resolved.service

Redhat系列

Centos 下dns服务安装是 yum install bind
启动的服务是 system start named

  1. yum -y install bind bind-utils
  2. systemctl start named.service // 启动服务
  3. systemctl enable named // 设为开机启动

1.1. 查看named进程是否正常启动

  1. ps -eaf|grep named // 检查进程
  2. ss -nult|grep :53 // 检查监听端口

如图:

搭建DNS服务器 - 图1

1.2. 开放 TCP 和 UDP 的 53 端口

  1. firewall-cmd --permanent --add-port=53/tcp
  2. firewall-cmd --permanent --add-port=53/udp
  3. firewall-cmd --reload // 重新加载防火墙配置,让配置生效

2.1. 修改主要文件 /etc/named.conf

修改前先备份: cp -p /etc/named.conf /etc/named.conf.bak // 参数-p表示备份文件与源文件的属性一致。
修改配置:vi /etc/named.conf , 配置内容如下:

  1. options {
  2. listen-on port 53 { any; };
  3. listen-on-v6 port 53 { any; };
  4. directory "/var/named";
  5. dump-file "/var/named/data/cache_dump.db";
  6. statistics-file "/var/named/data/named_stats.txt";
  7. memstatistics-file "/var/named/data/named_mem_stats.txt";
  8. allow-query { any; };
  9. /* 本地没有找到,就去100.125.1.250上找*/
  10. forwarders { 100.125.1.250;};
  11. /*
  12. - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
  13. - If you are building a RECURSIVE (caching) DNS server, you need to enable
  14. recursion.
  15. - If your recursive DNS server has a public IP address, you MUST enable access
  16. control to limit queries to your legitimate users. Failing to do so will
  17. cause your server to become part of large scale DNS amplification
  18. attacks. Implementing BCP38 within your network would greatly
  19. reduce such attack surface
  20. */
  21. recursion yes;
  22. dnssec-enable yes;
  23. dnssec-validation yes;
  24. /* Path to ISC DLV key */
  25. bindkeys-file "/etc/named.iscdlv.key";
  26. managed-keys-directory "/var/named/dynamic";
  27. pid-file "/run/named/named.pid";
  28. session-keyfile "/run/named/session.key";
  29. };

检查一波

  1. named-checkconf // 检查named.conf是否有语法问题

2.2. 配置正向解析和反向解析

2.2.1. 修改/etc/named.rfc1912.zones

添加配置: vi /etc/named.rfc1912.zones , 配置内容如下:

  1. zone "reading.zt" IN {
  2. type master;
  3. file "named.reading.zt";
  4. allow-update { none; };
  5. };
  6. zone "0.168.192.in-addr.arpa" {
  7. type master;
  8. file "named.192.168.0";
  9. allow-update { none; };
  10. };

2.2.2. 添加正向解析域

基于 name.localhost 模板,创建配置文件:cp -p /var/named/named.localhost /var/named/named.reading.zt
配置正向域名解析文件 named.reading.zt : vi /var/named/named.reading.zt ,配置内容如下:
reading.zt 表示域名可以自定义

  1. $TTL 1D
  2. @ IN SOA @ rname.invalid. (
  3. 0 ; serial
  4. 1D ; refresh
  5. 1H ; retry
  6. 1W ; expire
  7. 3H ) ; minimum
  8. NS @
  9. A 127.0.0.1
  10. AAAA ::1
  11. mirror A 192.168.0.233
  12. test A 192.168.0.232

表示mirror.reading.zt 解析到 192.168.0.233 mirror 后面可以添加TTL 值 一般是600
mirror 600 A 192.168.0.233
说明:

授权 named 用户 chown :named /var/named/named.reading.zt
检查区域文件是否正确 named-checkzone "reading.zt" "/var/named/named.reading.zt" ,如图:
reading.zt为域名可以自定义
搭建DNS服务器 - 图2

2.2.3. 添加反向解析域

基于 name.localhost 模板,创建配置文件: cp -p /var/named/named.localhost /var/named/named.192.168.0
配置反向域名解析文件 named.192.168.0 : vi /var/named/named.192.168.0

  1. $TTL 1D
  2. @ IN SOA @ rname.invalid. (
  3. 0 ; serial
  4. 1D ; refresh
  5. 1H ; retry
  6. 1W ; expire
  7. 3H ) ; minimum
  8. NS @
  9. A 127.0.0.1
  10. AAAA ::1
  11. 233 PTR mirror.reading.zt
  12. 232 PTR test.reading.zt

233 表示192.168.0.233 解析到 mirror.reading.zt
当然也可以将文件名从 /var/named/named.192.168.0 改为 /var/named/named.192.168,并在文件中配置 0.232 PTR mirror.reading.zt 来实现相同的效果。
授权 named 用户 chown :named /var/named/named.192.168.0
检查区域文件是否正确 named-checkzone "0.168.192.in-addr.arpa" "/var/named/named.192.168.0" ,如图:

搭建DNS服务器 - 图3

2.2.4. 重启 named 服务,让配置生效

重启 named 服务,让配置生效 systemctl restart named

3.1. 注册域名解析服务器到配置文件

配置 ifcfg-xxxx vi /etc/sysconfig/network-scripts/ifcfg-enp0s3 , 具体内容如下:

  1. TYPE=Ethernet
  2. PROXY_METHOD=none
  3. BROWSER_ONLY=no
  4. BOOTPROTO=static
  5. DEFROUTE=yes
  6. IPADDR=192.168.0.236
  7. NETMASK=255.255.255.0
  8. GATEWAY=192.168.0.1
  9. DNS1=192.168.0.236 // 新增,本机就是域名解析服务器
  10. DNS2=8.8.8.8
  11. DNS3=114.114.114.114
  12. IPV4_FAILURE_FATAL=no
  13. IPV6INIT=yes
  14. IPV6_AUTOCONF=yes
  15. IPV6_DEFROUTE=yes
  16. IPV6_FAILURE_FATAL=no
  17. IPV6_ADDR_GEN_MODE=stable-privacy
  18. NAME=enp0s3
  19. UUID=1639f78b-d515-4110-80ad-f1700bf7db84
  20. DEVICE=enp0s3
  21. ONBOOT=yes
  22. ZONE=public

如图:

搭建DNS服务器 - 图4

重启网络服务,让配置生效 systemctl restart network.service
有些机器没有network 而是NetworkManger
此时可以用nmcli设置dns

3.2. 使用 nslookup 测试

bind-utils 软件包本身提供了测试工具 nslookup

3.3.1. 正向域名解析测试

nslookup test.reading.zt , 或者,如下图:

搭建DNS服务器 - 图5

3.3.2. 反向域名解析测试

nslookup 192.168.0.232 , 或者,如下图:

搭建DNS服务器 - 图6