什么是智能 DNS?
在开始之前,我们先明确一下“智能 DNS”通常包含哪些功能:

- DNS 防火墙:过滤恶意域名(如钓鱼、恶意软件、C&C 服务器),防止内网用户访问不良网站。
- 域名白名单/黑名单:允许或禁止访问特定域名。
- 地理位置解析:根据用户的地理位置返回不同的 IP 地址,将访问
example.com的中国用户解析到中国的服务器 IP,将美国用户解析到美国的服务器 IP,实现就近访问,加速网络。 - 负载均衡:通过 DNS 轮询将流量分配到多个后端服务器。
- DNS-over-HTTPS (DoH) / DNS-over-TLS (DoT):提供加密的 DNS 查询,保护用户隐私,防止网络劫持。
- 响应速度优化:通过智能缓存和预取,加快域名解析速度。
方案选择
我们将介绍三种主流的搭建方案,从易到难,从功能单一到功能强大:
| 方案 | 核心软件 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
基于 bind 的黑白名单 |
BIND (Berkeley Internet Name Domain) | Linux 系统自带,稳定可靠,配置灵活 | 功能相对基础,需要手动维护黑名单 | 需要简单域名过滤,对 BIND 熟悉的用户 |
基于 dnsmasq 的轻量级方案 |
dnsmasq | 轻量、快速、易用,支持 DHCP 和 DNS | 高级功能(如 GeoIP)需要额外插件 | 家庭、小型办公室,或作为路由器/DHCP 服务器的附加 DNS 功能 |
基于 pdns 的专业级方案 |
PowerDNS | 功能极其强大,插件化架构,性能优异 | 配置复杂,资源消耗相对较高 | 企业级应用,需要高级功能如 GeoIP、DNS 防火墙、DoH/DoT 等 |
使用 BIND 实现黑白名单过滤
这是最经典、最基础的 DNS 智能控制方式。
安装 BIND
在基于 Debian/Ubuntu 的系统上:
sudo apt update sudo apt install bind9
在基于 CentOS/RHEL 的系统上:

sudo yum install bind bind-utils
配置 BIND
主配置文件是 /etc/bind/named.conf 或 /etc/named.conf,我们主要修改其包含的选项文件。
编辑 /etc/bind/named.conf.options (或 /etc/named.conf):
sudo nano /etc/bind/named.conf.options
在 options 块中,添加或修改以下内容,特别是 response-policy (RPZ) 部分,这是实现黑名单/白名单的关键。
options {
directory "/var/cache/bind";
// 允许哪些网络查询你的 DNS
allow-query { localhost; 192.168.1.0/24; }; // 修改为你的内网网段
// 不允许递归查询,防止被滥用为开放 DNS
allow-recursion { localhost; 192.168.1.0/24; };
// 监听所有接口,或只监听内网接口
listen-on { any; }; // 或 listen-on { 127.0.0.1; 192.168.1.1; };
// RPZ: 响应策略区域,用于实现黑/白名单
response-policy {
// zone "blacklist.local" policy given; // 引用黑名单区域
// zone "whitelist.local" policy given; // 引用白名单区域
// zone "walled-garden.local" policy given; // 引用特定解析策略区域
};
};
创建黑名单区域
RPZ 需要一个特殊的 "zone" 文件来定义规则。

在主配置文件中引用这个区域,编辑 /etc/bind/named.conf.local (或 /etc/named.conf 的末尾):
sudo nano /etc/bind/named.conf.local
// 定义一个名为 "blacklist" 的 RPZ 区域
zone "blacklist" {
type master;
file "/etc/bind/db.blacklist";
response-policy "given"; // 指定这是一个 RPZ 区域
};
创建区域文件 /etc/bind/db.blacklist:
sudo nano /etc/bind/db.blacklist
格式如下:
$TTL 86400
@ IN SOA ns1.yourdomain.com. admin.yourdomain.com. (
2025102601 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
86400 ) ; Minimum TTL
; RPZ 规则
; *.malware.com A 127.0.0.1 ; 封锁所有 malware.com 下的域名,解析到 127.0.0.1
; bad-site.com CNAME . ; 封锁 bad-site.com,返回 NXDOMAIN (域名不存在)
; *.phishing.net A 0.0.0.0 ; 封锁所有 phishing.net 下的域名,解析到 0.0.0.0
; 示例:封锁一些知名的恶意域名
malware.com. CNAME .
bad-site.com. CNAME .
another-bad.com. CNAME .
CNAME .是最常用的“封杀”方式,它会告诉查询者这个域名不存在 (NXDOMAIN)。A 127.0.0.1或A 0.0.0.0会将域名解析到一个固定的地址,可用于重定向到警告页面。
启动并测试
重启 BIND 服务:
# Ubuntu/Debian sudo systemctl restart bind9 sudo systemctl enable bind9 # CentOS/RHEL sudo systemctl restart named sudo systemctl enable named
测试:
# 测试被封杀的域名 dig @127.0.0.1 bad-site.com # 预期输出中应该包含 "status: NXDOMAIN" 或返回了我们指定的 IP # 测试一个正常的域名 dig @127.0.0.1 www.google.com
使用 dnsmasq 实现轻量级智能 DNS
dnsmasq 非常适合作为家庭或小型办公室的 DNS 服务器,配置极其简单。
安装 dnsmasq
# Ubuntu/Debian sudo apt install dnsmasq # CentOS/RHEL sudo yum install dnsmasq
配置 dnsmasq
默认配置可能已经足够,但我们需要添加智能规则,编辑 /etc/dnsmasq.conf:
sudo nano /etc/dnsmasq.conf
添加或取消注释并修改以下行:
# 监听所有接口,但只响应来自本机的查询 # 为了让其他设备使用,需要设置 listen-address listen-address=127.0.0.1,192.168.1.1 # 192.168.1.1 是你的服务器内网IP # 禁用其他 DNS 服务器,避免 DNS 泄漏 no-resolv # 添加上游 DNS 服务器,如 Cloudflare 或 Google server=1.1.1.1 server=8.8.8.8 # 启用日志,方便调试 log-queries # --- 智能规则 --- # 地址=/要屏蔽的域名/要解析到的IP # 屏蔽 baidu.com,并解析到 0.0.0.0 address=/baidu.com/0.0.0.0 # 如果想让它返回 NXDOMAIN (域名不存在),使用 'server=/' # server=/bad-site.com/ # 如果想重定向到特定 IP,使用 'address=' address=/malware-site.com/192.168.1.100
启动并测试
重启 dnsmasq:
sudo systemctl restart dnsmasq sudo systemctl enable dnsmasq
测试:
# 测试被封杀的域名 dig @127.0.0.1 baidu.com # 预期输出应该显示 ANSWER SECTION 为空,或者是我们指定的 IP
使用 PowerDNS 实现专业级智能 DNS (推荐)
PowerDNS (pdns) 是功能最全面的方案,尤其适合需要 GeoIP 和高级 DNS 防火墙功能的场景。
安装 PowerDNS 及其后端
我们使用 pdns-recursor (递归解析器) 和 pdnsutil (管理工具),后端可以使用 bind 的 zone 文件,也可以使用数据库,这里我们先用最简单的 bind 后端。
# Ubuntu/Debian (需要添加 PowerDNS 官方源) sudo apt install curl curl -s https://repo.powerdns.com/repofiles/powerdns-release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/powerdns-release.gpg >/dev/null echo "deb [arch=amd64] http://repo.powerdns.com/debian bullseye-auth-45 main" | sudo tee /etc/apt/sources.list.d/pdns.list sudo apt update sudo apt install pdns-recursor pdnsutil # CentOS/RHEL (需要添加 EPEL 和 PowerDNS 官方源) sudo yum install epel-release sudo rpm --import http://repo.powerdns.com/repofiles/powerdns-release-key.gpg sudo yum install pdns-recursor pdnsutil
配置 PowerDNS Recursor
主配置文件是 /etc/powerdns/recursor.conf。
sudo nano /etc/powerdns/recursor.conf
修改关键配置项:
# 监听地址 local-address=127.0.0.1,192.168.1.1 # 允许查询的网络 allow-from=127.0.0.0/8,192.168.1.0/24 # 上游 DNS 服务器 forward-zones=1.1.1.1=8.8.8.8 # 启用日志 logging=true loglevel=9 # --- 智能功能开关 --- # 启用 DNSSEC dnssec=validate # 启用 DNS-over-TLS (需要先安装 libgnutls28-dev 并重新编译,或使用包管理器支持) # tls-backends=gnutls # tls-ciphers=SECURE192 # tls-provider=gnutls
使用 pdnsutil 管理规则
PowerDNS 的强大之处在于其命令行工具 pdnsutil。
A. 创建 Zone 文件 (类似 BIND)
# 创建一个名为 "mydomain.com" 的主区域 sudo pdnsutil create-zone mydomain.com # 编辑 zone 文件 sudo nano /etc/powerdns/zones/mydomain.com.zone格式和 BIND 类似
B. 实现黑名单 (使用 RPZ - Response Policy Zones)
这是 PowerDNS 推荐的高级过滤方式。
-
创建一个 RPZ zone:
# 创建一个名为 "malware-blocklist" 的 RPZ zone sudo pdnsutil create-zone malware-blocklist
-
向 RPZ zone 添加记录:
# 添加一个规则:将所有 *.evil.com 解析到 127.0.0.1 sudo pdnsutil add-record malware-blocklist "*.evil.com" A 127.0.0.1 # 添加一个规则:将 bad-site.com 返回 NXDOMAIN sudo pdnsutil add-record malware-blocklist "bad-site.com" CNAME .
-
将 RPZ zone 应用到 Recursor: 在
/etc/powerdns/recursor.conf中添加:# 引用我们创建的 RPZ zone policy=malware-blocklist
C. 实现地理位置解析
PowerDNS Recursor 支持基于 GeoIP 的解析。
-
安装 GeoIP 数据库:
# Ubuntu/Debian sudo apt install geoip-database # CentOS/RHEL sudo yum install GeoIP
-
配置 Recursor: 在
/etc/powerdns/recursor.conf中添加:# 启用 GeoIP 功能 geoip-database-files=/usr/share/GeoIP/GeoIP.dat # 路径可能不同,请确认 # 添加一个 GeoIP 规则 # 如果查询者来自中国,则将 example.com 解析到 1.2.3.4 # 如果来自美国,则解析到 5.6.7.8 # 否则,解析到默认地址 9.10.11.12 allow-from=0.0.0.0/0 # 允许所有来源进行此测试 address-map=example.com:CN:1.2.3.4 address-map=example.com:US:5.6.7.8 address-map=example.com:9.10.11.12
启动并测试
重启 PowerDNS Recursor:
sudo systemctl restart pdns-recursor sudo systemctl enable pdns-recursor
测试:
# 测试黑名单 dig @127.0.0.1 bad-site.com # 测试 GeoIP (你需要一个来自不同国家的 IP 来测试,或者使用 `dig +short @your_server_ip your_ip.example.com` 等工具模拟) # 你可以临时修改你本机的 hosts 文件,将一个域名指向你的服务器,然后从不同网络访问它来观察解析结果的变化。
总结与建议
- 新手/家庭用户:从 方案二 (
dnsmasq) 开始,它简单、快速,能满足基本的黑白名单需求,并且和 DHCP 服务集成得很好。 - 有一定 Linux 基础,需要稳定可靠方案:选择 方案一 (
BIND),它是业界标准,非常稳定,RPZ 功能强大,配置文档丰富。 - 企业/高级用户:强烈推荐 方案三 (
PowerDNS),它的插件化架构和pdnsutil工具提供了无与伦比的灵活性和可管理性,是实现 GeoIP、DNS 防火墙、DoH/DoT 等复杂功能的最佳选择。
搭建智能 DNS 是一个持续的过程,特别是黑名单,需要定期更新才能保持有效,你可以编写脚本定期从公开的恶意域名列表(如 FireHOL, AbuseCh 等)下载并更新你的规则文件。
