Pi-hole v6.5 配置参数详解
Pi-hole v6.5(FTL v6.8)pihole.toml 配置参数逐组详解:参数查看与修改三种实测方式、dns/cache/blocking/webserver/api 全参数表、生产配置模板与常见问题
Pi-hole v6.5 配置参数详解
目标:以 Pi-hole v6.5(FTL v6.8)实测环境中的
/etc/pihole/pihole.toml(1772 行,FTL 自动生成与维护)为蓝本,逐组详解全部核心配置参数的含义、默认值与改动影响,给出查看与修改的三种实测方式,并提供一份面向家庭/小型办公场景的生产配置模板。已在 Ubuntu 22.04 实测通过。
一、环境信息
本篇参数与回显均取自以下实测环境,读者环境版本一致时内容可一一对应。
- 操作系统:Ubuntu 22.04(x86_64)
- Pi-hole 版本:Core v6.5 / Web 界面 v6.6.1 / FTL v6.8(
pihole version实测输出) - 配置文件:
/etc/pihole/pihole.toml(实测 1772 行,文件头标注 "Pi-hole configuration file (v6.8)") - 管理账号:admin / 密码
q1w2e3r4(示例演示值) - 实测时已生效的自定义配置:上游 DNS
223.5.5.5、119.29.29.29(环境变量注入,文件内标注### CHANGED (env));Local DNS 记录10.89.21.50 mydev.lan - 文件头实测内容:
# Pi-hole configuration file (v6.8)
# Encoding: UTF-8
# This file is managed by pihole-FTL
# Last updated on 2026-10-18 15:13:10 CST
关键解读:文件头写明该文件由 pihole-FTL 管理(managed by pihole-FTL)——Web 台、REST API、CLI 的任何配置修改最终都会由 FTL 重写此文件,手工编辑只适合离线场景。
二、前置条件
阅读与操作本篇需要:
- 一台已安装 Pi-hole v6.x 并可登录 Web 管理台的 Linux 服务器(部署过程见 《Pi-hole Docker Compose 部署指南》);
- Web 管理台密码(本篇示例用
q1w2e3r4); - 可选:
curl与python3(用于 REST API 演示)、服务器本地 shell 权限。
💡 说明:Pi-hole v6 的配置体系与 v5 完全不同——v5 分散在
setupVars.conf、pihole-FTL.conf、dnsmasq.d/*.conf多个文件,v6 全部收敛到单一pihole.toml,且升级时自动迁移。
三、参数查看与修改方式
配置的查看与修改共有三种等价途径,改动全部落回 pihole.toml。本节三种方式均实测验证。
3.1 方式一:直接查看配置文件
查看文件头与版本信息:
head -4 /etc/pihole/pihole.toml
实测回显:
# Pi-hole configuration file (v6.8)
# Encoding: UTF-8
# This file is managed by pihole-FTL
# Last updated on 2026-10-18 15:13:10 CST
查看某一参数段(以 upstreams 为例):
grep -B1 -A4 'upstreams = \[' /etc/pihole/pihole.toml
实测回显:
# Array of IP addresses and/or hostnames, optionally with a port (#...)
upstreams = [
"223.5.5.5",
"119.29.29.29"
] ### CHANGED (env), default = []
关键解读:每个参数都带多行官方注释与 Allowed values(允许取值)说明,等于自带文档;行尾 ### CHANGED (env), default = [] 标注当前值偏离默认值及偏离原因(env=环境变量注入,无标注则是 API/Web 台修改)。
3.2 方式二:REST API 读取与修改(推荐自动化场景)
先登录拿会话令牌,再按配置路径读写:
SID=$(curl -s -X POST http://127.0.0.1/admin/api/auth -H 'Content-Type: application/json' -d '{"password":"q1w2e3r4"}' | python3 -c "import json,sys; print(json.load(sys.stdin)['session']['sid'])")
curl -s "http://127.0.0.1/admin/api/config/dns/cache/size" -H "X-FTL-SID: $SID"
实测回显:
{"config":{"dns":{"cache":{"size":10000}}},"took":2.2649765014648438e-05}
修改用 PATCH,body 需要 config 对象包裹:
curl -s -X PATCH http://127.0.0.1/admin/api/config/dns/cache/size -H "X-FTL-SID: $SID" -H 'Content-Type: application/json' -d '{"config":{"dns":{"cache":{"size":20000}}}}'
实测回显:
{"config":{"dns":{"cache":{"size":20000}}},"took":0.0063221454620361328}
验证生效:回读配置文件,应看到新值与 CHANGED 标注:
grep 'size = 20000' /etc/pihole/pihole.toml
实测回显:
size = 20000 ### CHANGED, default = 10000
恢复默认值只需改回原值(实测改回 10000 后 CHANGED 标注消失)。
⚠️ 注意:PATCH 请求 body 必须包一层
config对象,直接传裸路径值会报400 No "config" object in body data(实测踩过)。
3.3 方式三:Web 管理台
浏览器打开 http://<服务器IP>/admin/ → Settings → 左侧 All Parameters,即可看到与 toml 一致的全量参数树,修改后即时生效。适合不熟悉命令行的场景,本篇不展开截图。
3.4 三种方式对比与注意事项
| 方式 | 适合场景 | 生效时机 | 风险点 |
|---|---|---|---|
| 编辑 toml + 重启 FTL | 离线迁移、批量初始化 | 重启 pihole-FTL 服务后 | 手工编辑可能被 FTL 下次写回覆盖(FTL 是文件属主) |
| REST API | 自动化、脚本化运维 | 立即生效(FTL 热加载) | 需处理会话令牌(1800 秒过期) |
| Web 管理台 | 日常人工调整 | 立即生效 | 无 |
💡 说明:大多数参数修改即时生效;少数参数(如
dns.piholePTR)会触发 FTL 自动重启,文件内注释有专门标注。
四、参数总览
pihole.toml 按 TOML 分组组织,顶层组与实测行号(grep -n '^\[' 实测):
| 顶层组 | 起始行 | 管辖范围 |
|---|---|---|
[dns] | 7 | DNS 解析与拦截全部参数(含 cache/blocking/specialDomains 子组),篇幅最大 |
[dhcp] | 554 | DHCP 服务器 |
[resolver] | 745 | 客户端名称解析(MAC/网络名) |
[database] | 807 | 查询历史数据库 |
[webserver] | 869 | 内置 Web 服务器与 REST API(含 session/tls/paths/interface/api 子组) |
[files] | 1298 | 关键文件路径 |
[misc] | 1362 | 杂项(隐私级别、启动延迟、资源自检等) |
[debug] | 1542 | 调试开关(默认全关) |
关键解读:日常运维 90% 的改动集中在 [dns]、[webserver]、[misc] 三组;[debug] 只在官方排障指导下开启。
五、核心参数分类详解
以下逐组详解,参数表中的「默认值」均取自实测 toml 注释或 ### CHANGED, default = X 标注。
5.1 [dns] 基础解析参数
| 参数 | 默认值 | 说明 |
|---|---|---|
dns.upstreams | [] | 上游 DNS 列表。不配置则无法解析本地以外的域名。支持 IP、IP#端口、主机名,也可用 https://(DoH)/tls://(DoT)前缀指定加密上游 |
dns.listeningMode | "LOCAL" | 监听模式:LOCAL 只应答本地子网(防开放解析器滥用);ALL 应答所有来源(打包运行时官方建议值,需配防火墙);SINGLE 仅指定网卡;BIND 强制绑定监听网卡;NONE 不生成监听配置(高级用户) |
dns.port | 53 | DNS 监听端口 |
dns.queryLogging | true | 是否把查询写入 pihole.log。关闭后查询日志审计与统计明细随之失效 |
dns.hosts | [] | Local DNS 自定义记录,格式 "IP 主机名"(与 hosts 文件同形)。实测值 ["10.89.21.50 mydev.lan"] |
dns.cnameRecords | [] | 自定义 CNAME,格式 "<cname>,<target>[,<TTL>]" |
dns.dnssec | false | 是否向上游请求并校验 DNSSEC。开启增加少量 CPU 开销 |
dns.domainNeeded | false | 对无点号(不带域名后缀)的裸名查询不转发上游 |
dns.expandHosts | false | 给 hosts 中的裸主机名追加本地域 |
dns.bogusPriv | true | 私有网段的反向查询不转发上游(推荐保持开启) |
dns.localise | true | 对私网地址的应答按客户端所在接口地址本地化(localise/本地化应答) |
dns.interface | "" | 限定监听的接口名,空为全部 |
dns.hostRecord | "" | 手工指定本机主机名记录 |
upstreams 实测段(环境变量注入后):
upstreams = [
"223.5.5.5",
"119.29.29.29"
] ### CHANGED (env), default = []
hosts 自定义记录实测段(配合 dig mydev.lan 返回 10.89.21.50 验证):
# Array of custom DNS records
#
# Example: [ "127.0.0.1 mylocal", "192.168.0.1 therouter" ]
#
# Allowed values are:
# Array of custom DNS records each one in HOSTS form: "IP HOSTNAME [HOSTNAME ...]"
hosts = [
"10.89.21.50 mydev.lan"
] ### CHANGED, default = []
💡 技术拓展:
upstreams的「上游类型」不止普通 IP 一种,常见形式对比——
形式 示例 特点 明文 IP 223.5.5.5最简单,查询可被链路窥探/篡改 IP+端口 127.0.0.1#5335指向本机其他解析器(如 unbound) DoH https://dns.quad9.net/dns-query加密走 443,抗劫持与封锁 DoT tls://dns.quad9.net加密走 853,协议直观 主机名 my-resolver按名字解析的内部上游 本文实测采用两个公共明文 IP(223.5.5.5 / 119.29.29.29),生产建议至少一个换成 DoH/DoT 加密形式。
5.2 [dns.cache] 缓存参数
| 参数 | 默认值 | 说明 |
|---|---|---|
dns.cache.size | 10000 | 缓存条目数上限。官方注释明确警告超过 1 万后查询速度反而下降(10,000+ 区间查找变慢),不建议盲目调大 |
dns.cache.optimizer | 3600 | 过期缓存「续命」秒数:TTL 刚过期不久的数据可继续使用并后台刷新,显著改善弱网体验;设为负数禁用 |
dns.cache.upstreamBlockedTTL | 86400 | 上游已拦截查询的缓存 TTL(默认 1 天);设 0 关闭该缓存 |
dns.cache.rrtype | "ANY" | 缓存哪些记录类型,逗号分隔 |
实测段(已恢复默认值后的完整内容):
[dns.cache]
size = 10000
optimizer = 3600
upstreamBlockedTTL = 86400
rrtype = "ANY"
关键解读:家庭网络把 size 保持在默认 10000 即可;optimizer=3600 是 v6 默认开启的体验优化,公网域名频繁变更 IP 的场景(CDN)如遇旧记录问题可下调。
5.3 [dns.blocking] 拦截行为参数
| 参数 | 默认值 | 说明 |
|---|---|---|
dns.blocking.active | true | 拦截总开关(对应 CLI 的 pihole disable/enable) |
dns.blocking.mode | "NULL" | 拦截应答模式,五种取值见下 |
dns.blocking.edns | "TEXT" | 拦截应答附带 EDNS 信息:NONE 不带;CODE 附 info-code BLOCKED(15);TEXT 附 code+文字说明 |
dns.blockTTL | 2 | 拦截应答的 TTL 秒数,越小客户端越快重新询问(解除拦截生效快) |
dns.replyWhenBusy | "ALLOW" | gravity 数据库忙时的应答策略:BLOCK/ALLOW/REFUSE/DROP。官方注释特别说明 REFUSE 会引发客户端疯狂重试(每秒数千次),DROP 则安静丢弃 |
mode 的五种实测取值(toml 注释原文归纳):
| 取值 | 拦截时返回 |
|---|---|
NULL(默认) | A 记录返回 0.0.0.0,AAAA 返回 :: |
IP_NODATA_AAAA | A 返回 Pi-hole 本机 IPv4,AAAA 返回 NODATA |
IP | 返回 Pi-hole 本机 IP |
NX | 返回 NXDOMAIN(域名不存在) |
NODATA | 返回 NODATA(域名存在但无此类型记录) |
实测段:
[dns.blocking]
active = true
mode = "NULL"
edns = "TEXT"
与实测行为对照:dig doubleclick.net 返回 0.0.0.0(NULL 模式)、正则拦截命中 tracker.adsrv.test 同样返回 0.0.0.0,与 mode="NULL" 一致。
5.4 [dns.specialDomains] 防绕过参数
| 参数 | 默认值 | 说明 |
|---|---|---|
dns.specialDomains.mozillaCanary | true | 对 use-application-dns.net 恒回 NXDOMAIN,阻止 Firefox 自动启用 DoH 绕过 Pi-hole(依据 Mozilla 官方建议) |
dns.specialDomains.iCloudPrivateRelay | true | 对 mask.icloud.com、mask-h2.icloud.com 恒回 NXDOMAIN,阻止苹果设备用 iCloud 私有中继绕过 |
dns.specialDomains.designatedResolver | true | 对 resolver.arpa 区回 NODATA,阻止按 RFC 9462 探测加密解析器绕过 |
关键解读:三个开关全部指向同一目标——防止设备「悄悄绕过拦截」。保持默认全开,否则苹果/谷歌/Firefox 生态的设备会优先尝试自己的加密 DNS。
5.5 [dhcp] DHCP 服务器参数
| 参数 | 默认值 | 说明 |
|---|---|---|
dhcp.active | false | DHCP 总开关。启用需实例具备 NET_ADMIN 能力 |
dhcp.start / dhcp.end | "" | 分配地址池起止 IP |
dhcp.router | "" | 下发给客户端的网关 |
dhcp.netmask | "" | 子网掩码 |
dhcp.leaseTime | "" | 租期(如 "24h") |
dhcp.rapidCommit | false | DHCP 快速分配(两报文模式) |
dhcp.hosts | [] | 静态租约,格式 "MAC,IP[,主机名]" |
实测默认段:active = false(未启用 DHCP)。启用前确认网络里没有第二个 DHCP(家用路由器通常已开启),双 DHCP 会随机分配导致网络混乱。
5.6 [resolver] 与 [database] 参数
[resolver] 客户端名称解析:
| 参数 | 默认值 | 说明 |
|---|---|---|
resolver.macNames | true | 用 MAC 厂商库识别客户端 |
resolver.networkNames | true | 从网络表解析客户端主机名 |
resolver.refreshNames | "IPV4_ONLY" | 名称刷新频率策略 |
[database] 查询历史库:
| 参数 | 默认值 | 说明 |
|---|---|---|
database.DBimport | true | 启动时导入历史库(关闭则重启丢统计) |
database.maxDBdays | 91 | 查询历史保留天数,到期自动清理 |
database.DBinterval | 60 | 内存数据落库间隔(秒) |
database.useWAL | true | SQLite WAL 模式(写入性能更好) |
database.forceDisk | false | 强制把运行时数据放磁盘而非共享内存 |
关键解读:maxDBdays=91 决定磁盘占用的主水位——查询量大的网络(日均 10 万查询以上)可降到 30 天;DBinterval=60 意味着异常断电最多丢最近 60 秒查询记录。
5.7 [webserver] Web 服务参数
| 参数 | 默认值 | 说明 |
|---|---|---|
webserver.domain | "pi.hole" | 管理台显示域名 |
webserver.port | "80o,443os,[::]:80o,[::]:443os" | 监听端口串:o=only(仅 HTTP)、s=SSL。含义为 80 端口仅 HTTP、443 端口 HTTP+自签名 HTTPS,IPv4/IPv6 双栈 |
webserver.threads | 50 | Web 线程池大小 |
webserver.acl | "" | 访问控制列表(ACL),空为不限 |
webserver.paths.webroot | "/var/www/html" | Web 根目录 |
webserver.paths.webhome | "/admin/" | 管理台路径前缀 |
webserver.tls.cert | "/etc/pihole/tls.pem" | HTTPS 证书路径(放入证书即可启用真 HTTPS) |
webserver.session.timeout | 1800 | 登录会话有效期(秒),与登录实测返回的 validity: 1800 一致 |
webserver.session.restore | true | 服务重启后会话可恢复 |
webserver.interface.boxed | true | 界面布局为 boxed 模式 |
webserver.port 实测段:
port = "80o,443os,[::]:80o,[::]:443os"
关键解读:port 字符串是 v6 新语法,改监听端口写 "8091o"(仅 8091 HTTP)这类形式;映射端口场景(打包运行时)实例内仍是 80,改的是宿主侧映射。
5.8 [webserver.api] 与认证参数
| 参数 | 默认值 | 说明 |
|---|---|---|
webserver.api.pwhash | "" | Web 密码哈希(BALLOON-SHA256 算法)。由 pihole setpassword 或环境变量写入,请勿手工编辑;实测值形如 $BALLOON-SHA256$v=1$...(哈希串涉密,此处不引用原值) |
webserver.api.prettyJSON | false | API 响应美化缩进 |
webserver.api.excludeClients | [] | 统计中排除的客户端 |
webserver.api.excludeDomains | [] | 统计中排除的域名 |
webserver.api.maxHistory | 86400 | API 可查询的历史窗口秒数(默认 1 天) |
webserver.api.maxClients | 10 | Top 客户端统计数量上限 |
密码修改实测(CLI 方式):pihole setpassword 'q1w2e3r4' 执行后 toml 中 pwhash 立即更新且标注 ### CHANGED, default = "";登录验证返回 message: password correct。
5.9 [files] 与 [misc] 参数
[files] 路径参数(实测默认值):
database = "/etc/pihole/pihole-FTL.db"
tmp_db = "/etc/pihole/pihole-tmp.db"
gravity = "/etc/pihole/gravity.db"
gravity_tmp = "/tmp"
macvendor = "/etc/pihole/macvendor.db"
| 参数 | 默认值 | 说明 |
|---|---|---|
files.gravity_tmp | "/tmp" | gravity 重建临时目录;/tmp 空间小的设备可改到数据盘 |
files.macvendor | "/etc/pihole/macvendor.db" | MAC 厂商库路径 |
[misc] 关键参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
misc.privacylevel | 0 | 查询日志隐私级别:0 全量记录;1 隐藏域名;2 隐藏域名与客户端;3 匿名化全部。用于对外展示数据前脱敏 |
misc.delay_startup | 0 | 启动延迟秒数(等网络就绪的设备用) |
misc.nice | -10 | FTL 进程调度优先级(负数更高)。实测环境无 CAP_SYS_NICE 能力时启动日志会有 WARNING,不影响功能 |
misc.etc_dnsmasq_d | false | 是否加载 /etc/dnsmasq.d 自定义配置 |
misc.readOnly | false | 只读模式(API 拒绝写操作,用于展示型实例) |
misc.check.load | true | 系统负载自检(15 分钟负载超核数告警) |
misc.check.shmem | 90 | 共享内存使用率告警阈值(%) |
misc.check.disk | 90 | 磁盘使用率告警阈值(%) |
5.10 [debug] 调试开关
[debug] 组包含 database/networking/locks/queries/flags/shmem/gc/arp/regex/api/tls/overtime/status/caps/dnssec/vectors/resolver/clients 等子开关,实测全部为 false。日常保持关闭;官方 pihole -d 调试会按需提示开启对应项,排障后应关闭(debug 日志量大且含敏感信息)。
六、生产配置模板
以下模板面向「家庭/小型办公:50 客户端以内、2GB 内存、SSD、日均 5–10 万查询」场景,只列偏离默认值的项(其余保持默认即可)。适用场景不符时(如千人规模)先压测再调。
[dns]
# 双上游:明文 + 加密各一,任一故障不影响解析
upstreams = [
"223.5.5.5",
"https://dns.alidns.com/dns-query"
]
# 打包运行时/多网卡服务器建议 ALL + 防火墙限源;纯局域网保持 LOCAL
# listeningMode = "ALL"
[dns.cache]
# 官方警告超 1 万条查询变慢,保持默认
size = 10000
# 弱网优化保持 1 小时
optimizer = 3600
[dns.blocking]
active = true
mode = "NULL" # 兼容性最好的默认拦截模式
edns = "TEXT" # 拦截应答带原因文字,方便用户理解
[database]
# 查询量大、磁盘紧张时降到 30 天
maxDBdays = 91
[webserver]
# 仅限内网访问管理台(按需放行管理网段)
# acl = "+10.89.21.0/24"
[webserver.session]
# 会话 1800 秒默认够用;无人值守大屏可加长
timeout = 1800
[misc]
privacylevel = 0 # 自用保持全量记录;对外共享统计时临时调高
逐项理由:
| 参数 | 推荐值 | 理由 |
|---|---|---|
upstreams | 明文+DoH 各一 | 单上游是最大单点;加密上游防运营商劫持 |
listeningMode | 局域网 LOCAL / 复杂拓扑 ALL | ALL 必须配合防火墙,否则沦为开放解析器 |
cache.size | 默认 10000 | 官方实测超 1 万性能反降 |
blocking.mode | NULL | 客户端兼容性最好,部分客户端对 NXDOMAIN 误判为断网 |
maxDBdays | 91(量大改 30) | 磁盘占用与历史回溯的平衡点 |
privacylevel | 0(自用) | 级别越高统计价值越低,按需权衡 |
配置修改与验证闭环(模板写入后):
grep -A3 'upstreams = \[' /etc/pihole/pihole.toml | tail -4
实测回显(模板生效后):
upstreams = [
"223.5.5.5",
"https://dns.alidns.com/dns-query"
]
dig @127.0.0.1 www.baidu.com +short
实测回显(DoH 上游可达时正常解析):
www.a.shifen.com.
110.242.70.57
110.242.69.21
七、常见问题
Q1:手工改了 pihole.toml,过一会儿又被改回去?
FTL 是配置文件的属主:它定期把内存中的配置写回文件(文件头的 Last updated 时间戳随之刷新)。手工编辑期间若有 Web/API/CLI 写操作,改动会被覆盖。正确做法:批量变更走 REST API,或改完立即重启 FTL 使其重读。
Q2:PATCH API 报 No "config" object in body data?
实测踩过:body 必须是 {"config":{"dns":{"hosts":[...]}}} 这样的嵌套结构,直接 {"dns":{"hosts":[...]}} 会报此错。
Q3:dns.hosts 写 ["mydev.lan=10.89.21.50"] 报错?
实测报错:dns.hosts[0]: neither a valid IPv4 nor IPv6 address ("mydev.lan=10.89.21.50")。hosts 项格式是 hosts 文件同形的 "IP 主机名"(如 "10.89.21.50 mydev.lan"),不是 域名=IP。正确写法实测后 dig mydev.lan 返回 10.89.21.50。
Q4:改了 dns.piholePTR 后服务闪断一下?
正常现象:该参数注释明确说明 "Changing this setting causes FTL restart",FTL 会自动重启重载,DNS 中断 1–2 秒。
Q5:日志里出现 Linux capability CAP_SYS_NICE is not available?
实测记录:打包运行时未授予 SYS_NICE 能力时,设置 misc.nice 的进程优先级不生效,FTL 打 WARNING。两种处理:忽略(无功能影响)或在运行时配置中补 SYS_NICE 能力。
Q6:如何确认某参数当前是否偏离默认值?
三看:toml 行尾 ### CHANGED 标注;grep -c 'CHANGED' /etc/pihole/pihole.toml 统计偏离项数量(实测当前环境含 env 注入共 4 处:upstreams、hosts、pwhash、macvendor);或 Web 台 All Parameters 中非灰显项。
八、参考链接
- FTL 官方配置参考(pihole.toml 全参数):https://docs.pi-hole.net/ftldns/configfile/
- Pi-hole REST API 文档:https://docs.pi-hole.net/api/
- DNS resolver 机制文档:https://docs.pi-hole.net/ftldns/interfaces/
- Blocking mode 说明:https://docs.pi-hole.net/ftldns/blockingmode/
- 隐私级别说明:https://docs.pi-hole.net/ftldns/privacylevels/
- 本平台相关篇:《Pi-hole Docker Compose 部署指南》
- 本平台相关篇:《Pi-hole v6.5 介绍与选型指南》