环境:Ubuntu 20.04 Server
核心功能
OPT伪记录 Pseudo-RR(OPT Pseudo Resource Record,OPT 伪资源记录)是一种特殊的 DNS 记录类型,它允许 DNS 服务器支持更大的 UDP 数据包,并提供额外的 DNS 功能。
OPT 记录不会存储在 DNS 区域文件中,而是动态生成并仅用于 DNS 查询和响应的 EDNS 选项传递。主要作用包括:
- 支持更大的UDP数据包:DNS消息最大可扩展至 4096 字节。( DNS 协议默认按 UDP 传输,为优化传输性能,DNS 协议有一个512字节的限制,当数据长度超过了512字节时,DNS 协议会改用 TCP 进行传输,性能会下降)
- 支持携带客户端子网信息 ECS(EDNS Client Subnet),向权威服务器传递用户IP的子网,帮助 CDN 返回就近节点。
- 支持 DNSSEC,携带加密签名、公钥等数据,增强安全性。
- 支持 DNS over HTTPS/TLS。
安装
apt update -y && apt install -y bind9 bind9utils bind9-utils bind9-dnsutils bind9-doc bind9-host bind9-libs && named -v
配置功能1
主要配置文件为/etc/bind/named.conf
,具体在/etc/bind/named.conf.options
中添加配置参数。
- edns-udp-size:定义 BIND 发送查询时的 EDNS UDP 负载大小,默认值通常为 1232 字节(在 BIND 9.16+ 版本)。如果 BIND 服务器发送的 DNS 响应因超过 MTU 而被丢弃,可以降低该值。
- max-udp-size:定义 BIND 能够接收的 UDP 数据包最大大小,默认 4096 字节(所能支持的最大值了)。如果服务器面临 UDP 放大攻击,可以将此值设低。
重启服务生效
systemctl restart named
验证是否支持 EDNS
BIND 安装好之后默认已经启用了 EDNS 功能,无需额外配置。
dig +norec +noad +edns=0 example.com @127.0.0.1
返回结果出现如下输出则证明支持EDNS。
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
flags:可能包含 DNSSEC、ECS 等功能标志。
测试 max-udp-size 最大值
默认最大 4096 字节,通过 +bufsize=N 来手动调整查询的数据包大小,验证超过这个最大值时,响应会被截断。
dig +bufsize=8192 example.com @127.0.0.1
返回的结果应该是没有;; ANSWER SECTION:
的内容,证明超过最大值时,响应结果会被截断。
清除 DNS 缓存
清除 BIND9 服务器上的所有 DNS 缓存
rndc flush
清除特定域名的缓存
rndc flushname example.com
清除所有缓存并重新加载区域
rndc restart
确保 dig 查询最新的记录
即使清除了本地缓存,上游 DNS 服务器可能仍然缓存了记录。你可以使用 dig 强制跳过缓存并直接查询权威 DNS 服务器:
dig @8.8.8.8 example.com +trace
或
dig example.com +noad
如果 BIND 服务器已经启用了 DNSSEC,可以使用:
dig example.com +dnssec
配置功能2
确保版本 >=9.10,ECS 需要较新版本支持。
编辑配置文件/etc/bind/named.conf.options
options {
directory "/var/cache/bind";
// 允许递归查询(适用于缓存 DNS)
recursion yes;
// 启用 ECS(EDNS Client Subnet)
edns-client-subnet yes;
// 允许查询的子网(可以限制特定网段)
allow-recursion { any; };
// 允许哪些服务器进行 ECS 转发(可选)
forwarders {
8.8.8.8;
8.8.4.4;
};
// 允许 ECS 处理的子网范围(定义哪些客户端允许使用 ECS)
acl ecs-clients {
192.168.0.0/16;
10.0.0.0/8;
172.16.0.0/12;
};
// 启用 ECS 并指定 ECS 转发行为
server 8.8.8.8 {
edns-client-subnet send all;
};
// 其他服务器配置(可选)
server 1.1.1.1 {
edns-client-subnet send all;
};
};
启用 ECS 解析规则
如果上面配置了acl ecs-clients
,编辑配置文件/etc/bind/named.conf.local
,添加
view "ecs_view" {
match-clients { ecs-clients; };
recursion yes;
//edns-client-subnet yes;
zone "." {
type forward;
forwarders {
8.8.8.8;
1.1.1.1;
};
};
};
这里如果要配置 forwarders,那么上面的 options 中的需要删除。
并且需要将所有 zone 区域配置移动到 view 视图里面,例如/etc/bind/named.conf.default-zones
。
view "default" {
match-clients { any; };
// 将这些区域配置放在视图块内
zone "." {
type hint;
file "/etc/bind/db.root";
};
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
};
重启服务生效
systemctl restart named
查看日志输出
journalctl -xe | grep named
报错
named[27085]: /etc/bind/named.conf.options:31: unknown option 'edns-client-subnet'
Ubuntu 20.04 默认的 Bind9 不直接支持 edns-client-subnet 选项,而是通过 forwarders 方式携带 ECS 数据。
修改/etc/bind/named.conf.options
options {
directory "/var/cache/bind";
dnssec-validation auto;
listen-on-v6 { any; };
listen-on { 127.0.0.1;your_server_ip; };
edns-udp-size 1232;
// 启用 ECS(EDNS Client Subnet)
max-udp-size 4096;
recursion yes;
allow-recursion { any; };
forwarders {
8.8.8.8;
};
};
然后将/etc/bind/named.conf.local
里面的配置全部注释掉,重启服务。这里直接使用 forwarders 配置向上游 DNS 服务器传递查询,确保这些服务器支持 ECS(如 Cloudflare、Google 等都支持)。
验证 ECS 功能
dig @127.0.0.1 www.aliyun.com +subnet=103.116.76.0/24
模拟客户端子网为 103.116.76.0/24 向 EDNS 服务器查询 www.aliyun.com 域名,查看返回结果。
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: f63e6a3539da8fca0100000067a8f1e236c9059e3bbd25b4 (good)
; CLIENT-SUBNET: 103.116.76.0/24/0
;; QUESTION SECTION:
;www.aliyun.com. IN A
;; ANSWER SECTION:
www.aliyun.com. 120 IN CNAME www-jp-de-intl-adns.aliyun.com.
...
...
结果中有显示CLIENT-SUBNET
字段,证明 ECS 已经配置成功了。通过改变 +subnet 参数的值,可以模拟不同的客户端 IP 子网,看看返回的节点是否发生变化,验证 ECS 是否根据不同的客户端子网返回不同的结果。
遗留问题
注意事项:
- 如果没有配置 send-client-subnet,服务器将不会在查询中传递 ECS 信息给上游 DNS 服务器。
- 如果上游 DNS 不支持 ECS,也可能导致 CLIENT-SUBNET 信息不返回。
进一步测试发现,在 EDNS 服务器本地测试时添加了 +subnet 可以成功返回 CLIENT-SUBNET 字段,但是在其它真实的客户端查询时并没有返回。
BIND9 ECS Patch 不是官方 BIND9 内置的功能,而是社区或厂商提供的补丁,用于为 BIND9 添加对 EDNS Client Subnet (ECS) 的支持。标准的 BIND9 默认不会 向 forwarders 或 upstream servers 发送 ECS 信息,即使客户端查询时携带了 +subnet 信息,BIND9 也会丢弃该字段,导致 ECS 失效。
从结果上看,Bind9 不支持作为 ECS 代理服务器,但 PowerDNS Recursor 支持。如果必须支持 ECS 查询转发,建议使用 PowerDNS Recursor 作为 DNS 服务器。
评论区