Anycast DNS 的本质是把同一组权威 DNS 服务器地址通过 BGP 路由协议从多个节点同时宣告到互联网。用户发起 DNS 查询时,上游路由器会根据 AS 路径长度、本地优先级、MED 等路由属性选择距离最近或路径最短的节点。这个过程完全发生在网络层,客户端不需要做任何配置,也不需要像传统 DNS 负载均衡那样依赖地域解析库或 CNAME 跳转。部署 Anycast DNS 的重点在于路由一致性、节点健康检查和 DNS 软件的配合。

一、Anycast DNS 的路由原理与关键概念
Anycast 并不是 DNS 特有的技术,它本质上是把一个 IP 地址分配给多个地理位置不同的主机,然后通过路由协议把这些主机同时宣告出去。对于单播地址,一个 IP 通常只对应一台主机;对于 Anycast 地址,同一地址可以在多个自治系统边界被宣告。路由器收到多条到达相同前缀的路由后,会按照 BGP 选路规则选择最优路径,因此用户流量自然被引导到距离最近的节点。
DNS 查询通常是 UDP 报文,一个请求只有一个或几个数据包,这种无连接特性非常适合 Anycast。如果某个节点发生故障,只要该节点停止宣告对应前缀,上游路由器就会把流量重新导向其他节点。故障切换时间取决于 BGP 收敛速度,一般在几秒到几十秒级别。和基于应用层健康检查的智能解析相比,Anycast 的切换更底层、更自动。
需要区分 Anycast 和负载均衡。Anycast 不保证流量平均分配,它关心的是就近和冗余。在路由策略稳定的情况下,某个区域的用户通常会持续命中同一个节点。因此如果希望在同一区域内做流量均衡,还需要在节点内部配合 L4 负载均衡或多台 DNS 服务器。
二、部署前的网络与架构设计
部署 Anycast DNS 首先要确定节点数量和地址规划。典型方案是至少两个节点,分别位于不同运营商或不同地理区域。每个节点需要一台或多台运行 BGP 会话的路由器或服务器,并拥有公网 AS 号。如果没有独立 AS 号,也可以与上游运营商协商由运营商代为宣告,但这会牺牲部分控制权。
地址规划上,需要向 RIR 或上游申请一段 IPv4 和 IPv6 地址,专门用于 Anycast 服务。通常建议为 DNS 分配一个 /24 IPv4 段和一个 /48 IPv6 段,因为很多运营商会过滤长于 /24 的 IPv4 前缀。实际宣告时,节点只宣告这个专用地址段,不要和节点本身上网地址混在一起。每个节点的回程流量也要考虑,避免出现流量从节点 A 进入、从节点 B 返回这种非对称路径。
架构示例可以用两个节点:节点 A 位于华东,节点 B 位于华南。两个节点分别与不同上游运营商建立 eBGP 会话,同时宣告 203.0.113.0/24 这个 Anycast 段。DNS 服务器监听在 203.0.113.53 上,作为权威服务器对外提供解析。节点之间不需要同步 DNS 数据,如果采用主从架构,可以通过隐藏的主节点定期向各 Anycast 节点推送区域数据,或直接使用 GitOps 方式发布区域文件。
三、BGP 与 DNS 软件配置
服务器上可以运行 BIRD 或 FRRouting 来宣告 Anycast 前缀。BIRD 配置相对轻量,适合小型部署。下面是一个 BIRD 的 IPv4 eBGP 宣告示例,假设本地 AS 为 65001,上游 AS 为 65000,Anycast 地址段为 203.0.113.0/24。
# /etc/bird/bird.conf
router id 192.0.2.2;
protocol device {
scan time 10;
}
protocol kernel {
ipv4 {
export none;
};
}
protocol static anycast_v4 {
ipv4;
route 203.0.113.0/24 reject;
}
protocol bgp upstream1 {
local as 65001;
neighbor 192.0.2.1 as 65000;
source address 192.0.2.2;
multihop;
export filter {
if net = 203.0.113.0/24 then accept;
reject;
};
import none;
}
上述配置中,静态路由 203.0.113.0/24 被标记为 reject,表示本机不实际承载该网段的所有地址,但会把它加入路由表并通告给 BGP 邻居。出口过滤器只允许 Anycast 段送出,避免把内部路由泄露出去。
DNS 软件可以选择 BIND、Knot DNS 或 NSD。对于权威服务,NSD 和 Knot 更专一,资源占用低。以 BIND 为例,主要配置如下:
options {
directory "/var/cache/bind";
listen-on port 53 { any; };
listen-on-v6 port 53 { any; };
allow-query { any; };
recursion no;
minimal-responses yes;
notify no;
};
zone "ipipp.com" {
type master;
file "/etc/bind/zones/ipipp.com.zone";
};
注意 recursion no 是权威 DNS 的关键设置,避免节点被当作开放递归服务器滥用。监听的 any 会绑定所有地址,但真正对外提供服务的是 Anycast 地址。为了安全,可以在防火墙层限制仅允许 53 端口对外,并丢弃其他端口的入站流量。
四、验证与故障排查
部署完成后,先在本地使用 dig 命令验证解析。执行 dig @203.0.113.53 ipipp.com A,确认返回的 A 记录正确。然后从不同运营商网络、不同地理位置的客户端发起查询,观察响应时间是否接近。如果两地用户在路由表中都被正确地指向就近节点,响应耗时通常会有明显差异。
查看当前实际到达哪个节点,可以在节点上抓包 tcpdump -i eth0 port 53,或者用 ip route get 203.0.113.53 从客户端侧查看路径。由于 Anycast 是逐包路由,同一台主机的连续查询理论上会命中同一节点,但在路由变化时可能切换。对于 TCP 类型的 DNS 查询,如果出现连接中断,要检查路径 MTU 和上游路由策略。
路由层面可以用 birdc show route 或 vtysh -c 'show bgp ipv4 unicast' 查看宣告情况。确认上游已经收到前缀,并且没有被过滤。常见问题是上游运营商对 /24 前缀做了路由过滤,或者节点间的 BGP 会话没有正确建立。健康检查方面,可以在每个节点运行轻量探针,检测本地 DNS 进程是否响应,一旦异常就停止宣告 Anycast 前缀,让流量自动切走。
五、高可用与安全注意事项
Anycast DNS 的高可用依赖多个节点共同承载同一地址。只要至少一个节点正常宣告路由,解析服务就不会中断。但要注意 BGP 收敛期间可能仍有部分流量到达故障节点,因此不要依赖 Anycast 提供零丢包切换。对于要求极高的场景,可以在应用层增加重试机制,或把 DNS 缓存 TTL 设置得稍长一些,缓解短时不可用。
DDoS 攻击是 DNS 服务常见风险。Anycast 的一个优势是攻击流量通常会被分散到多个节点,而不是全部集中到单一入口。但这也要求每个节点具备一定的清洗能力。可以配合 RTBH、FlowSpec 或上游清洗服务,在攻击发生时快速丢弃异常流量。另外限制递归、关闭 ANY 查询、启用最小响应,都能减少放大攻击风险。
最后不要忽略区域数据同步。Anycast 节点对外表现相同,但如果区域数据不一致,用户会在不同节点得到不同解析结果。建议把区域文件放在 Git 仓库中管理,推送时通过 CI 自动分发到所有节点,并执行 named-checkzone 或 kzonecheck 校验。只有通过校验的文件才允许加载,避免因手工修改导致数据漂移。
Anycast DNSDNS部署BGP路由修改时间:2026-10-04 06:03:32