💡 办公室里最会演戏的,不是同事,是“看起来一切正常”的网络。网页偶尔打不开、刚接入的电脑拿不到地址、同一个网关一会儿一个 MAC,这些小毛病凑在一起,就可能是局域网的信任边界出了问题。
本文把一份攻击主题的学习材料改写成防守视角:不复述攻击命令,不使用真实公司信息,也不提供钓鱼或凭据拦截步骤。你将得到一套可以在自有网络、授权环境或隔离实验室里执行的排查流程:先观察,后取证,再恢复,最后让交换机替你挡住重复事故。
先认识三个“前台接待”
把局域网想成一栋办公楼:
| 角色 | 它负责的事 | 出问题时的典型症状 |
|---|---|---|
| DHCP | 给设备分配 IP、网关和 DNS | 新设备拿不到地址,或者拿到一套奇怪的网络参数 |
| ARP | 在同一网段里把 IPv4 地址对应到 MAC 地址 | 网关 MAC 反复变化、连接忽快忽慢 |
| DNS | 把域名翻译成 IP | 只有部分域名打不开,或解析结果与其他网络不一致 |
正常情况下,这三位各司其职。异常时,设备可能收到一个不该出现的 DHCP 响应,随后把网关的 ARP 记录改成另一个 MAC,最后再被错误的 DNS 引到不该去的地址。用户看到的只是“网断了”,管理员看到的却是一条完整的证据链。
先建立基线,再谈异常
没有基线的告警,和没有尺子的裁缝差不多:两边都很忙,结果都靠感觉。建议为每个 VLAN 记录以下四项:
- 合法 DHCP Server 的 IP 和 MAC。
- 默认网关的 IP 和 MAC。
- 合法 DNS Server 的 IP。
- 正常工作日的地址池范围和租约时长。
示例使用 192.0.2.0/24、198.51.100.0/24 等文档保留网段,不能直接拿去替换真实生产地址。
Windows:五分钟拿到现场证据
先不要清缓存,也不要马上重启。保存现场比“让它暂时恢复”更重要。
1. 记录完整网络参数
New-Item -ItemType Directory -Force .\network-evidence | Out-Null
ipconfig /all | Tee-Object .\network-evidence\ipconfig.txt
route print | Tee-Object .\network-evidence\routes.txt
arp -a | Tee-Object .\network-evidence\arp.txt
Get-DnsClientServerAddress -AddressFamily IPv4 |
Format-Table -AutoSize |
Out-File .\network-evidence\dns-servers.txt -Encoding utf8
重点看三件事:
DHCP Server是否是已登记的地址。Default Gateway是否落在预期网段。DNS Servers是否出现未知地址,尤其是与网关不在同一管理范围的地址。
2. 检查网关的 ARP 记录
$gateway = (Get-NetRoute -DestinationPrefix '0.0.0.0/0' |
Sort-Object RouteMetric |
Select-Object -First 1 -ExpandProperty NextHop)
"默认网关: $gateway"
arp -a $gateway
把输出里的 MAC 与你的基线比较。单次不一致不等于攻击:网关可能做了主备切换、虚拟化迁移或网络维护。关键是变化频率、发生时间和是否伴随 DHCP/DNS 异常。
3. 只读观察 DHCP 和 ARP
如果现场允许抓包,Wireshark 只做观察即可,过滤器可以从下面两个开始:
bootp || arp
你要找的是“同一网段出现多个 DHCP Offer”,以及“同一个网关 IP 在短时间内对应多个 MAC”。不要在生产网络里为了验证猜想主动发送伪造报文。
Linux:同一套证据换一种口音
mkdir -p ./network-evidence
ip addr | tee ./network-evidence/ip-addr.txt
ip route | tee ./network-evidence/ip-route.txt
ip neigh show | tee ./network-evidence/ip-neigh.txt
resolvectl status | tee ./network-evidence/resolved.txt
如果发行版没有 resolvectl,改看:
cat /etc/resolv.conf | tee ./network-evidence/resolv-conf.txt
默认路由可以单独确认:
ip route get 192.0.2.1
输出中的 via 是下一跳,dev 是出口网卡。把它和 ip neigh 中同一地址的 MAC 一起记下来,就有了“路由 + 二层邻居”的最小证据集。
一个安全的基线检查脚本
下面的脚本只读取本机信息,并把结果保存成 JSON,适合每天定时运行。它不会扫描别人,也不会修改网络配置。
保存为 collect_network_baseline.py:
from __future__ import annotations
import json
import platform
import socket
import subprocess
from datetime import datetime, timezone
from pathlib import Path
def run(command: list[str]) -> str:
result = subprocess.run(
command,
check=False,
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
)
return result.stdout.strip() or result.stderr.strip()
def collect() -> dict[str, object]:
system = platform.system()
data: dict[str, object] = {
"captured_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
"hostname": socket.gethostname(),
"platform": platform.platform(),
}
if system == "Windows":
data["ipconfig"] = run(["ipconfig", "/all"])
data["routes"] = run(["route", "print"])
data["arp"] = run(["arp", "-a"])
data["dns"] = run(["powershell", "-NoProfile", "-Command",
"Get-DnsClientServerAddress -AddressFamily IPv4"])
elif system == "Linux":
data["addresses"] = run(["ip", "addr"])
data["routes"] = run(["ip", "route"])
data["neighbors"] = run(["ip", "neigh"])
data["dns"] = run(["cat", "/etc/resolv.conf"])
else:
raise SystemExit(f"暂不支持 {system},请手工记录网络参数")
return data
output = Path("network-evidence")
output.mkdir(exist_ok=True)
target = output / "baseline.json"
target.write_text(json.dumps(collect(), ensure_ascii=False, indent=2), encoding="utf-8")
print(f"已写入 {target.resolve()}")
运行:
python collect_network_baseline.py
将生成的 baseline.json 纳入受控的运维存储,不要直接提交到公开仓库。里面可能包含主机名、内网地址和 DNS 信息。
发现异常后,按这个顺序恢复
第一步:隔离受影响端口
如果只有一台设备异常,先把它移到隔离 VLAN 或拔掉网线;如果多个端口同时异常,优先在交换机上核对 DHCP Snooping、端口状态和最近的变更记录。隔离的目标是停止继续扩散,不是惩罚某台电脑。
第二步:重新获取合法配置
确认网络侧已经排除异常响应后,再在受影响设备上执行恢复。Windows:
ipconfig /release
ipconfig /renew
ipconfig /flushdns
Linux(NetworkManager):
nmcli device status
nmcli connection show --active
sudo nmcli connection down "有线连接 1"
sudo nmcli connection up "有线连接 1"
resolvectl flush-caches 2>/dev/null || true
把 有线连接 1 换成 nmcli connection show --active 里实际的连接名。不要在远程 SSH 会话中盲目重启网络服务,否则可能把自己锁在门外。
第三步:重新采集并对比
恢复后再次保存 ipconfig、路由、ARP 和 DNS。以下情况说明还不能结案:
- DHCP Server 仍然变化。
- 网关 MAC 在几分钟内反复切换。
- DNS 解析与可信网络持续不一致。
- 只有 HTTPS 站点“偶尔”出现证书错误。
交换机侧的四道门
主机自救只能解决一台设备,真正的防线在接入层。不同厂商命名略有差异,但目标是一致的:
- DHCP Snooping:只信任上联到合法 DHCP Server 的端口,接入口收到 DHCP Server 报文就丢弃,并记录绑定表。
- Dynamic ARP Inspection:用 DHCP Snooping 的绑定关系校验 ARP,避免设备冒充网关。
- IP Source Guard:限制端口只能使用绑定表里的 IP/MAC 组合,降低地址伪装空间。
- 端口隔离与 802.1X:让终端先通过身份认证,再决定能访问哪个 VLAN,减少“插上网线就默认信任”的情况。
启用前要先做两件事:确认上联端口列表、给静态地址和语音 VLAN 建立明确例外。先在一台测试交换机或低风险 VLAN 观察日志,再逐步扩大范围。配置名可以查对应厂商文档,不要直接把网上别人的整段配置粘进生产设备。
15 分钟排查清单
[ ] 记录时间、受影响 VLAN、设备名和用户现象
[ ] 保存 DHCP、默认网关、DNS、ARP/邻居表
[ ] 与最近一次正常基线比较,而不是只看当前值
[ ] 确认是否存在多个 DHCP Server 或网关 MAC 变化
[ ] 在交换机侧核对端口、绑定表和变更记录
[ ] 隔离异常端口,保留日志和抓包文件
[ ] 网络侧修复后,再释放/续租地址并清理 DNS 缓存
[ ] 复测内网、外网、关键域名和证书链
[ ] 更新基线,并记录长期加固项
三个常见误判
“能上网,就说明没问题”
错误的 DNS 或网关不一定让网络立刻断掉,可能只是把部分流量带到错误路径。可用可信的外部网络交叉解析关键域名,并检查证书是否匹配预期服务。
“ARP 表里有两个 MAC,就是攻击”
高可用网关、负载均衡和虚拟机迁移都会改变 MAC。判断依据应该是基线、时间线、交换机日志和 DHCP 证据的组合。
“清缓存就结束了”
清缓存只改变一台机器的暂态状态,不能阻止异常设备继续发包。没有找到端口和网络侧原因,问题还会回来。
总结:让网络有记忆,也有刹车
局域网不是天然可信区。把 DHCP、ARP、DNS 当成一条证据链来观察,你就能把“网怎么又抽风了”变成可验证的问题:
建立基线 → 只读取证 → 隔离影响 → 合法恢复 → 交换机加固 → 持续复盘
最后提醒一次:本文命令只适用于你拥有或明确获准测试的网络。公开仓库里不要放真实域名、内网地址、设备序列号、抓包文件或任何凭据;排查记录也应先脱敏,再进入工单和知识库。
参考资料
作者:牛马便利店一号店员
文档信息
- 本文作者:牛马
- 本文链接:https://geekhappy.com/2026/08/26/lan-dhcp-arp-dns-defense/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)