强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 10 章:响应策略区域(RPZ)

本章概述

RPZ(Response Policy Zone,响应策略区域)是 BIND 的安全特性,允许通过 DNS 层面拦截恶意域名、钓鱼网站和广告。本章讲解 RPZ 的原理、规则编写、日志审计和最佳实践。


10.1 RPZ 基础

10.1.1 什么是 RPZ

RPZ 是一种特殊的 DNS 区域文件,用于定义查询策略。当递归服务器收到查询时,会先检查 RPZ 规则,根据规则决定是否修改响应。

正常流程:
客户端 → 递归服务器 → 权威服务器 → 返回真实 IP

RPZ 流程:
客户端 → 递归服务器 → 检查 RPZ 规则
                     → 命中规则 → 返回拦截响应
                     → 未命中 → 继续正常解析

10.1.2 RPZ 的用途

用途说明示例
恶意软件拦截阻断 C2 通信malware.example.com
钓鱼防护阻止访问钓鱼网站phishing-site.com
广告过滤屏蔽广告域名ads.example.com
合规管控阻止访问特定网站gambling-site.com
内部策略重定向特定域名social-media.com

10.1.3 RPZ 响应类型

响应类型DNS 响应客户端行为
NXDOMAIN域名不存在浏览器显示错误
NODATA无记录不显示错误,但无法连接
CNAME 重定向指向其他域名访问重定向目标
丢弃(DROP)不响应连接超时
记录修改返回自定义 IP连接到指定服务器

10.2 配置 RPZ

10.2.1 基本配置

// named.conf

options {
    recursion yes;
    allow-recursion { trusted; };
    
    // 启用 RPZ
    response-policy {
        zone "rpz.example.com" policy nxdomain;
        // 可以有多个 RPZ 区域,按顺序匹配
        // zone "rpz-ads.example.com" policy nxdomain;
    };
};

// RPZ 区域定义
zone "rpz.example.com" {
    type primary;
    file "primary/rpz.example.com.zone";
    allow-query { none; };          // 不允许外部查询 RPZ 区域
    allow-transfer { none; };       // 不允许传输
};

10.2.2 RPZ 区域文件

; primary/rpz.example.com.zone
; 恶意域名拦截策略区域
$TTL 60
$ORIGIN rpz.example.com.

@   IN  SOA  ns1.example.com. admin.example.com. (
        2026051001  ; Serial
        3600        ; Refresh
        900         ; Retry
        1209600     ; Expire
        60          ; Minimum ( TTL)
    )
    IN  NS  localhost.

; ---- 恶意域名拦截(返回 NXDOMAIN ----
malware-c2.example.com      IN  CNAME   .              ; NXDOMAIN
phishing-site.com           IN  CNAME   .              ; NXDOMAIN
evil-domain.net             IN  CNAME   .              ; NXDOMAIN
cryptominer.pool.com        IN  CNAME   .              ; NXDOMAIN

; ---- 广告域名拦截 ----
ads.example.com             IN  CNAME   .
tracker.analytics.com       IN  CNAME   .
ad.doubleclick.net          IN  CNAME   .

; ---- 重定向到安全页面 ----
blocked.example.com         IN  A       192.168.1.250  ; 拦截页面
warning.example.com         IN  A       192.168.1.251  ; 警告页面

; ---- 通配符拦截 ----
*.malware-domain.com        IN  CNAME   .              ; 拦截所有子域名
*.tracking.example.net      IN  CNAME   .

; ---- 白名单(覆盖 RPZ 规则) ----
; 如果某个域名被上游 RPZ 列表误拦截,可以放行
safe-malware.example.com    IN  CNAME   rpz-passthru.  ; 放行

; ---- 丢弃响应(客户端看到超时) ----
slowloris.example.com       IN  CNAME   rpz-drop.      ; 丢弃

; ---- 自定义响应 ----
custom.example.com          IN  TXT     "Blocked by policy"  ; 返回 TXT

10.2.3 RPZ 特殊记录

特殊记录作用
CNAME .返回 NXDOMAIN(域名不存在)
CNAME *.返回 NODATA(域名存在但无记录)
CNAME rpz-passthru.放行(白名单)
CNAME rpz-drop.丢弃查询(不响应)
CNAME rpz-tcp-only.仅允许 TCP 查询
CNAME target.example.com.重定向到目标域名

10.3 使用第三方 RPZ 列表

10.3.1 常见 RPZ 数据源

来源URL类型
SURBLhttps://surbl.org/恶意域名
Spamhaushttps://www.spamhaus.org/垃圾邮件/恶意软件
abuse.chhttps://urlhaus.abuse.ch/恶意 URL
CERT.PLhttps://hole.cert.pl/恶意软件
自建列表内部维护企业定制

10.3.2 自动更新 RPZ 列表

#!/bin/bash
# /opt/scripts/update-rpz.sh
# 自动下载和更新 RPZ 列表

RPZ_DIR="/var/cache/bind/primary"
RPZ_FILE="${RPZ_DIR}/rpz.example.com.zone"
BACKUP_DIR="/var/backups/rpz"
DATE=$(date +%Y%m%d%H%M%S)

# 创建备份
mkdir -p "$BACKUP_DIR"
cp "$RPZ_FILE" "${BACKUP_DIR}/rpz-${DATE}.zone"

# 生成新的 RPZ 区域文件
cat > "$RPZ_FILE" <<HEADER
\$TTL 60
\$ORIGIN rpz.example.com.
@   IN  SOA  ns1.example.com. admin.example.com. (
        ${DATE} ; Serial
        3600    ; Refresh
        900     ; Retry
        1209600 ; Expire
        60      ; Minimum
    )
    IN  NS  localhost.
HEADER

# 下载恶意域名列表
curl -s "https://hole.cert.pl/domains/domains.txt" | while read domain; do
    # 跳过注释和空行
    [[ "$domain" =~ ^#.*$ || -z "$domain" ]] && continue
    echo "${domain}.  IN  CNAME  ." >> "$RPZ_FILE"
done

# 下载广告域名列表
curl -s "https://some-adblock-list/ads.txt" | while read domain; do
    [[ "$domain" =~ ^#.*$ || -z "$domain" ]] && continue
    echo "${domain}.  IN  CNAME  ." >> "$RPZ_FILE"
done

# 添加自定义拦截
cat >> "$RPZ_FILE" <<CUSTOM
; 自定义拦截
custom-block.com.  IN  CNAME  .
CUSTOM

# 检查语法
/usr/sbin/named-checkzone rpz.example.com "$RPZ_FILE"
if [ $? -eq 0 ]; then
    # 重载区域
    /usr/sbin/rndc reload rpz.example.com
    echo "RPZ updated: $(wc -l < "$RPZ_FILE") rules"
else
    echo "RPZ syntax error, reverting"
    cp "${BACKUP_DIR}/rpz-${DATE}.zone" "$RPZ_FILE"
fi

# 清理旧备份(保留 30 天)
find "$BACKUP_DIR" -name "rpz-*.zone" -mtime +30 -delete

10.3.3 定时任务

# 添加到 crontab
sudo crontab -e

# 每天凌晨 3 点更新
0 3 * * * /opt/scripts/update-rpz.sh >> /var/log/rpz-update.log 2>&1

10.4 多 RPZ 区域策略

10.4.1 多区域配置

options {
    response-policy {
        zone "rpz-custom.example.com"      policy nxdomain;   // 自定义列表
        zone "rpz-malware.example.com"     policy nxdomain;   // 恶意软件
        zone "rpz-phishing.example.com"    policy nxdomain;   // 钓鱼网站
        zone "rpz-ads.example.com"         policy nxdomain;   // 广告
        zone "rpz-whitelist.example.com"   policy passthru;   // 白名单(最高优先级)
    } qname-wait-recurse no;
};

优先级:列表中的顺序很重要,第一个匹配的规则生效。白名单应放在最后(或单独使用 policy passthru)。

10.4.2 按客户端应用不同策略

// 结合视图使用
view "strict" {
    match-clients { 192.168.1.0/24; };  // 严格管控子网
    
    options {
        response-policy {
            zone "rpz-strict.example.com" policy nxdomain;
        };
    };
    
    zone "rpz-strict.example.com" {
        type primary;
        file "primary/rpz-strict.example.com.zone";
    };
};

view "relaxed" {
    match-clients { 192.168.2.0/24; };  // 宽松子网
    
    options {
        response-policy {
            zone "rpz-relaxed.example.com" policy nxdomain;
        };
    };
    
    zone "rpz-relaxed.example.com" {
        type primary;
        file "primary/rpz-relaxed.example.com.zone";
    };
};

10.5 RPZ 日志与审计

10.5.1 启用 RPZ 日志

logging {
    channel rpz_log {
        file "/var/log/named/rpz.log" versions 10 size 100m;
        severity info;
        print-time yes;
        print-severity yes;
        print-category yes;
    };
    
    // RPZ 触发时记录
    category rpz { rpz_log; };
};

10.5.2 日志格式

# 典型 RPZ 日志条目
10-May-2026 14:30:15.123 rpz: info: client @0x7f8b8c0d 192.168.1.100#12345: \
    rpz QNAME NXDOMAIN rewrite <malware-c2.example.com/A/NXDOMAIN> \
    via rpz.example.com
字段说明
时间戳查询时间
客户端 IP发起查询的客户端
原始查询被拦截的域名
拦截动作NXDOMAIN / NODATA / 重定向
触发的 RPZ 区域哪个 RPZ 规则生效

10.5.3 统计信息

# 查看 RPZ 统计
rndc stats
cat /var/cache/bind/named.stats

# 输出中会包含 RPZ 相关统计
# rpz: nxdomain 1234
# rpz: nodata 56
# rpz: passthru 78
# rpz: drop 12

10.6 RPZ 性能优化

10.6.1 性能影响

RPZ 规模性能影响建议
< 10,000 条可忽略标准配置
10,000 - 100,000 条轻微增加内存
> 100,000 条明显使用专用服务器

10.6.2 优化配置

options {
    response-policy {
        zone "rpz.example.com" policy nxdomain;
    }
    // 性能优化选项
    qname-wait-recurse no;    // 不等待递归完成(推荐)
    max-policy-ttl 300;       // 策略最大 TTL(秒)
    min-ns-dots 0;            // 最少点数才触发 RPZ
    break-dnssec yes;         // 允许 RPZ 覆盖 DNSSEC(需要)
};
选项默认值说明
qname-wait-recurseyes是否等待递归解析完成
max-policy-ttl-策略响应的最大 TTL
break-dnssecno是否允许 RPZ 覆盖 DNSSEC 签名

10.7 业务场景

10.7.1 企业网络安全

// 场景:企业部署 RPZ 阻断恶意软件通信

zone "rpz-corporate.example.com" {
    type primary;
    file "primary/rpz-corporate.zone";
    allow-update { key rpz-update-key; };  // 允许安全团队更新
};

10.7.2 公共 Wi-Fi

// 场景:咖啡店 Wi-Fi 拦截恶意和成人内容

options {
    response-policy {
        zone "rpz-public-wifi.example.com" policy nxdomain;
    };
};

10.7.3 学校网络

// 场景:学校网络过滤不适宜内容

options {
    response-policy {
        zone "rpz-school.example.com"    policy nxdomain;  // 不适宜内容
        zone "rpz-educational.example.com" policy passthru; // 教育资源白名单
    };
};

10.8 本章小结

配置项说明推荐值
RPZ 区域类型type primary使用本地文件或动态更新
默认策略policy nxdomain最安全
白名单CNAME rpz-passthru.覆盖拦截规则
日志category rpz监控拦截情况
更新频率每天自动化脚本

💡 小技巧

  1. RPZ 区域 TTL 设短:60 秒,便于快速更新策略。
  2. 不要暴露 RPZ 区域allow-query { none; }; 防止外部查询。
  3. 使用 qname-wait-recurse no:提升性能。
  4. 白名单放在最后:确保白名单覆盖其他规则。
  5. 定期备份 RPZ 数据:防止误删规则。

📖 扩展阅读