关于 DNS 的折腾,实在多的很。所以彻底的整理一篇记录。
1 、 DNS
域名解析服务,Domain Name System 。重要到在网络中无处不在。规模异常庞大却只有几个点运行的服务系统,网络协议中棘手的半壁江山(另一半是 tcp)
我们总是用到它,但总是又当它不存在。负载均衡,流量管控,中间人攻击,DDOS,数据劫持,实名认证,抽象资产。围绕着 DNS 有着无数的故事,又难以讲全。
在 Linux 中,/etc/hosts , /etc/hostname , /etc/resolv.conf 和 systemd-resolved.service 排障检查总是有这四个。
在 Windows 中,C:\Windows\system32\drivers\etc\hosts 总是在 404 时身先士卒。
而作为基础服务,我们总是需要一个用来管理 无法访问此网站。毕竟 谁也不想被别人摘了桃子,自己还不知情。
一个 www.google.com 在 DNS 眼中分别是 . / com. / google.com. / www.google.com. 四步走。
常用的 DNS 解析检查工具是 nslookup 和 dig ,Python3 中则是 dns.resolver
Windows 网络出问题了,ipconfig /flushdns 清理 DNS 缓存必不可少。
而最常用的 DNS 服务程序,莫过 DNSmasq
2 、 DNSmasq
在 Ubuntu 20 中,我们可以直接安装 dnsmasq
apt install dnsmasq
安装好后,我们需要关注一个路径和一个文件。
/etc/dnsmasq.d/ # 配置文件路径 /etc/dnsmasq.conf # 启动文件路径, 会 include 加载配置文件 # Include all files in a directory which end in .conf conf-dir=/etc/dnsmasq.d,*.conf
在 /etc/dnsmasq.conf 中我们可以看到所有 dnsmasq 所使用的配置参数,可以通过参数直接修改配置。参考 [ 链接 ]
# Dnsmasq 服务身份用户与用户组 user=dnsmasq #group= # DNS 服务监听端口 port=53 # DNS 服务与 DHCP 服务 绑定接口与排除接口 #interface= #except-interface= # DNS 服务与 DHCP 服务 绑定指定的接口后禁用其他所有接口 (不指定 interface 参数为全接口绑定) bind-interfaces # DNS 服务与 DHCP 服务 绑定地址 (适用锁定地址服务,含有 0.0.0.0 和:: 配置时可能会冲突,与绑定端口方案互斥) #listen-address= # DHCP 服务禁用接口 #no-dhcp-interface= # 管控不完整域名 (本地域) 仅限本地解析禁止上行(建议全局开启) domain-needed # 管控私有地址的反向域名解析仅限本地解析禁止上行(建议全局开启) bogus-priv # DNSSEC 配置部分,指定根签名,开启 DNSSEC 请求,核验 DNSSEC 的回执(降速,可不开) conf-file=/usr/share/dnsmasq/trust-anchors.conf dnssec #dnssec-check-unsigned # DNS 向上级请求缓存到本地的条目数量与强制修改缓存 TTL 时间 cache-size=150 #local-ttl= # DNS 向上级请求未知域名失败后也进行缓存(默认缓存) no-negcache # 重启服务后是否清空之前的 DNS 缓存(默认不清空) clear-on-reload # Dnsmasq 日志记录文件路径与写入缓存的条目数(5~100) log-facility=/var/log/dnsmasq/dnsmasq.log log-async=5 # Dnsmasq 日志记录 DNS DHCP 详情 #log-queries #log-dhcp
# DNS 解析组 配置部分 # resolv-file 命令在 Ubuntu20 失效,因为前置 resolvconf 而默认强制为 /run/dnsmasq/resolv.conf # 相关链接为 https://bugs.launchpad.net/ubuntu/+source/dnsmasq/+bug/1090589 no-resolv #resolv-file=/etc/resolv.conf #strict-order #no-poll # 对所有的 server 同时发送请求报文 all-servers 当你不需要 Dnsmasq 读取 系统 DNS 并使用 系统 DNS 进行解析时 no-resolv 当你想通过 resolv-file 来进行解析管理时(比如系统 DNS 文件 nameserver 数量大于三个) #no-resolv resolv-file=/etc/resolv.conf 当你希望 resolv-file 严格按 resolv 上下顺序查询时 strict-order 当你希望 resolv-file 全体并发查询并取最快返回结果时(all-servers 参数默认开启) #strict-order 参考文章 https://www.redhat.com/en/blog/five-nines-dnsmasq 当你不希望自动更新 resolv-file 时(监听文件变化) no-poll
# 屏蔽运营商因域名不存在返回的虚假地址 bogus-nxdomain=64.94.110.11 # 配置 taobao.com 全域 和 *.apple.com(排除 @.apple.com) 和 cn 全域 使用 指定的 DNS server=/.apple.com/223.6.6.6 server=/taobao.com/223.5.5.5 server=/cn/1.2.4.8 # 配置 A/AAAA 单个域名解析为 192.168.1.10 (仅读取最上一条并返回读取内容,多条内容使用需要用 addn 方式) address=/example.com/192.168.1.10 address=/example.com/fec0:192:168:1::10 # 配置 IP 地址 反向解析域名 ptr-record=192.168.1.10.in-addr.arpa,example.com ptr-record=0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.8.6.1.0.2.9.1.0.0.0.c.f.ip6.arpa,example.com # 配置 CNAME 单个域名解析,由 double-click.net 转到 single-click.net cname=single-click.net,double-click.net # 配置 SPF(TXT) 单个域名解析 txt-record=example.com,"v=spf1 a -all" # 配置 Zeroconf(TXT) 单个域名解析 txt-record=_http._tcp.example.com,name=value,paper=A4 # 限制 fooxample.com 为本地域,仅使用 hosts 和 dhcp 进行解析查询。 local=/fooxample.com/ # 不加载主机 /etc/hosts 内容 no-hosts # 额外加载域名解析列表(可多次加载,可单域名多解析) addn-hosts=/etc/dnsmasq/dnsmasq.hosts # 自动填充本地域,将主机名自动填充 domain 后缀并回应解析结果 #expand-hosts #domain=thekelleys.org.uk
# 映射 DNS 解析记录 配置部分 #将解析结果 1.2.3.4 改为 5.6.7.8 #alias=1.2.3.4,5.6.7.8 #将解析结果 1.2.3.10 改为 5.6.7.10 (前缀组对应) #alias=1.2.3.0,5.6.7.0,255.255.255.0 #将解析结果 192.168.0.10 改为 10.0.0.10 (前缀组对应) 但仅限 10-40 这个地址段 #alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
MX 部分略
3 、 DNSCrypt
劫持 DNS 轻而易举,毕竟只要比正确答案快那么几毫秒,就可以轻松被取信并缓存到本地。
DNSCrypt 就是用来强化 DNS 解析的身份验证问题,其中落实到现在,主要是 DoT DoH DNSSEC 三份答案。
用网页可以自行检查相关的安全问题 [ 链接 ]
查阅资料,我们知道 DNSSEC 通过 顶级域名 TLD 和 对应子域名 的 逐层签名来保证解析内容的可靠性,有效阻断中间人虚假解析。早在 2010 年 8 月,root-servers.net 就已经完成了 . 根域的签名。想使用 DNSSEC 就需要 信任 这个签名并拒绝其他签名来保证解析是从 . 根来的,并且对异常进行丢弃。
但是因为 DNSSEC 要保证向后兼容,作为 EDNS 的一部分还需要各家 DNS 业务支持,而大多数 DNS 基础服务又期望更少的解析相应报文,最后 DNSSEC 变成小范围使用,大规模使用搁浅了。
DNS 安全的痛依然存在,作为 DNSCrypt 中的一员,DoT DoH 开始发光发热,但是这两个中国支持还是蛮少的,目前只有两家公开支持原生 Alibaba Public DNS 和 Rubyfish [ 链接 ],曾经的清华大学 TUNA DNS666 虽然是全都支持但是避免被滥用所以断了 公网 53/UDP 而后隐而不发。
关于 DNSSEC 的根签名,官方网址为 [ 链接 ]
关于 DNSSEC 相关配置,可以参考 [ 链接 ]
<TrustAnchor id="380DC50D-484E-40D0-A3AE-68F2B18F61C7" source="http://data.iana.org/root-anchors/root-anchors.xml"> <Zone>.</Zone> <KeyDigest id="Kjqmt7v" validFrom="2010-07-15T00:00:00+00:00" validUntil="2019-01-11T00:00:00+00:00"> <KeyTag>19036</KeyTag> <Algorithm>8</Algorithm> <DigestType>2</DigestType> <Digest>49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5</Digest> </KeyDigest> <KeyDigest id="Klajeyz" validFrom="2017-02-02T00:00:00+00:00"> <KeyTag>20326</KeyTag> <Algorithm>8</Algorithm> <DigestType>2</DigestType> <Digest>E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D</Digest> </KeyDigest> </TrustAnchor>
而在 DNSmasq 中使用,则需要填写到默认的路径中,相关路径已存在于 /etc/dnsmasq.conf
# Uncomment these to enable DNSSEC validation and caching: # (Requires dnsmasq to be built with DNSSEC option.) #conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf #dnssec
直接创建一个文件,并填入下方信息供 DNSmasq 使用
vim /usr/share/dnsmasq/trust-anchors.conf
# The root DNSSEC trust anchor, valid as at 11/01/2019 # Note that this is a DS record (ie a hash of the root Zone Signing Key) # If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
填写完毕后同时勾选上 dnssec 即可正常请求 DNSSEC 数据。
测试也很简单,输入命令即可出结果,其中 RRSIG 就是签名数据。
dig www.cloudflare.com +dnssec ; <<>> DiG 9.16.1-Ubuntu <<>> www.cloudflare.com +dnssec ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58148 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 1232 ;; QUESTION SECTION: ;www.cloudflare.com. IN A ;; ANSWER SECTION: www.cloudflare.com. 298 IN RRSIG A 13 3 300 20211030050140 20211028030140 34505 www.cloudflare.com. Qp3S1/RwBcMPswjohrpbpZZ/bO80hq/JVlEekd3WEsD8NiswBhJ1pi6c k40USX4Wqp8JvMIy3liJYEDYN2dS0g== www.cloudflare.com. 298 IN A 104.16.124.96 www.cloudflare.com. 298 IN A 104.16.123.96 ;; Query time: 88 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: 五 10 月 29 12:00:00 CST 2021 ;; MSG SIZE rcvd: 193
4 、 DHCP 部分
# 设置 DHCP 的地址范围,子网掩码,租期(IPV4 掩码默认会采用 DHCP 服务端的掩码为参考,IPV6 掩码默认/64) dhcp-range=192.168.8.50, 192.168.8.150, 255.255.255.0, 12h #dhcp-range=fec0::2, fec0::500, 64, 12h # 设置 DHCP 的网关地址,DNS 地址,NTP 地址 dhcp-option=3,192.168.8.1 dhcp-option=option:router,192.168.8.1 dhcp-option=option:dns-server,8.8.8.8,8.8.4.4 dhcp-option=option6:dns-server,[2001:4860:4860::8888],[2001:4860:4860::8844] dhcp-option=option:ntp-server,192.168.8.10,210.72.145.44 # DHCP 默认的租期,租期保存的文件 dhcp-lease-max=150 #dhcp-leasefile=/var/lib/dnsmasq/dnsmasq.leases # DHCP 所在的 domain,以及自动分配主机名 domain=example.com expand-hosts # 设置 DHCP 的地址范围,额外指定此部分用户的 Tag 为 red #dhcp-range=set:red,192.168.0.50,192.168.0.150 # 设置 DHCP 的地址范围,仅当部分用户的 Tag 为 greed 时适配 #dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h # 设置 DHCP 的地址范围中排除分配的地址 #dhcp-range=192.168.0.0,static # 设置 DHCP 的动态 MAC-IP-Hostname 绑定,infinit 为永久租期,ignore 为忽略请求,也可以两个设备共享同一 IP 地址 (注意冲突时只认后读取的一条) #dhcp-host=00:0C:29:5E:F2:6F,192.168.1.201 #dhcp-host=00:0C:29:5E:F2:6F,bob_computer #dhcp-host=00:0C:29:5E:F2:6F,192.168.1.201,bob_computer,infinit #dhcp-host=0C:29:5E:F2:6F:11:22:33:44:55:66,00,192.168.0.60 # 设置 DHCP 分配的客户端标识符为 hello #dhcp-host=id:hello,192.168.0.60 # 设置 DHCP 分配的指定设备 (可用通配符) ID 为空(PXE/OS 清空设备硬件型号避免区别对待) #dhcp-host=00:0C:29:5E:*:*,id:* # 设置 DHCP 分配的指定设备 (可用通配符) Tag 为 blue #dhcp-host=00:0C:29:5E:*:*,set:blue # 设置 DHCP 分配的含有指定系统字符串的 Tag 为 red #dhcp-vendorclass=set:red,Linux # 设置 DHCP 分配的含有指定用户字符串的 Tag 为 blue #dhcp-userclass=set:red,accounts # 设置 DHCP 分配的含有指定设备字符串的 Tag 为 blue #dhcp-mac=set:red,00:60:8C:*:*:*
PXE 部分略
关于 DHCP 部分,可以参考 [ 链接 ]
关于 PXE 联动部分,可以参考 [ 链接 ]
5 、 Systemd-resolved
在使用 Ubuntu 时许多人经常在出现 DNS 解析失败时感到迷茫,因为系统内默认是 Systemd-resolved 在负责解析
你可能认为这个东西没什么用,所以我们通常都会 disable stop 双连,然后自己创建 /etc/resolv.conf 并修改内容。
而在 Ubuntu 18 以上版本,你会发现 /etc/resolv.conf 这个文件是一个快捷方式,你如果想修改还需要删掉重建
这个快捷方式其指向了 /run/resolvconf/resolv.conf 文件,并且内容是 127.0.0.53
并且可能还会有 options edns0
由于 Ubuntu 发行版自带服务并且原生使用,导致许多软件强耦合了 Systemd-resolved 意味着你无法卸载它
对于 Ubuntu 18 系统内还在使用 resolvconf,相关的配置文件在 /etc/resolvconf/*
对于 Ubuntu 20 系统内使用 Systemd-resolved ,相关配置文件是 /etc/systemd/resolved.conf
我们可以使用命令查看当前状态
systemd-resolve --status
Global LLMNR setting: no MulticastDNS setting: no DNSOverTLS setting: no DNSSEC setting: no DNSSEC supported: no DNSSEC NTA: 10.in-addr.arpa 16.172.in-addr.arpa 168.192.in-addr.arpa 17.172.in-addr.arpa 18.172.in-addr.arpa 19.172.in-addr.arpa 20.172.in-addr.arpa 21.172.in-addr.arpa 22.172.in-addr.arpa 23.172.in-addr.arpa 24.172.in-addr.arpa 25.172.in-addr.arpa 26.172.in-addr.arpa 27.172.in-addr.arpa 28.172.in-addr.arpa 29.172.in-addr.arpa 30.172.in-addr.arpa 31.172.in-addr.arpa corp d.f.ip6.arpa home internal intranet lan local private test Link 2 (ens3) Current Scopes: DNS DefaultRoute setting: yes LLMNR setting: yes MulticastDNS setting: no DNSOverTLS setting: no DNSSEC setting: no DNSSEC supported: no Current DNS Server: 114.114.114.114 DNS Servers: 114.114.114.114 8.8.8.8
默认的配置文件可以进行修改,通常 DHCP 的 DNS 有问题时,需要自行指定一个
vim /etc/systemd/resolved.conf
[Resolve] #DNS=114.114.114.114 119.29.29.29 223.5.5.5 #FallbackDNS=8.8.8.8 #Domains= #LLMNR=no #MulticastDNS=no #DNSSEC=no #DNSOverTLS=no #Cache=no-negative #DNSStubListener=yes #ReadEtcHosts=yes
相关内容可以参考 [ 链接 ]