解锁Pi-hole广告拦截新姿势:自定义插件开发实战指南
你是否遇到过Pi-hole默认规则无法拦截的广告?是否希望根据网络环境定制过滤策略?本文将带你通过插件开发扩展Pi-hole功能,无需修改核心代码即可实现个性化广告拦截。完成阅读后,你将掌握插件目录结构设计、API调用方法和事件钩子使用,构建属于自己的广告拦截模块。
插件开发环境准备
Pi-hole插件系统基于Bash脚本和FTL DNS引擎构建,开发前需确保环境满足以下要求:
- 已安装Pi-hole v5.0+(推荐最新版)
- 具备基本Bash脚本编写能力
- 了解DNS工作原理
通过官方安装脚本部署基础环境:
curl -sSL https://install.pi-hole.net | bash
核心开发文件位于项目目录:
插件目录结构设计
遵循Pi-hole模块化设计原则,推荐插件结构如下:
pihole-plugins/
├── myplugin/
│ ├── main.sh # 插件入口脚本
│ ├── config.toml # 配置文件
│ ├── filters/ # 自定义过滤规则
│ └── hooks/ # 事件钩子脚本
└── README.md # 插件说明文档
通过addOrEditKeyValPair函数注册插件(源自advanced/Scripts/utils.sh第28行):
addOrEditKeyValPair "/etc/pihole/setupVars.conf" "PLUGIN_MYPLUGIN_ENABLED" "true"
核心API与钩子使用
Pi-hole提供三类扩展接口,满足不同功能需求:
1. 配置管理接口
通过FTL配置API修改运行参数,例如设置自定义DNS上游服务器:
# 读取当前配置
getFTLConfigValue dns.upstreams
# 设置新配置(需单引号包裹数组值)
setFTLConfigValue dns.upstreams '[ "1.1.1.1" , "1.0.0.1" ]'
代码源自advanced/Scripts/utils.sh第75-94行
2. 事件钩子系统
利用预定义钩子注入自定义逻辑,常用钩子包括:
pihole-FTL-prestart.sh:FTL启动前执行pihole-FTL-poststop.sh:FTL停止后执行
模板文件位置:advanced/Templates/pihole-FTL-prestart.sh
3. 数据查询接口
通过pihole-FTL命令行工具获取实时统计数据:
# 查询Top 10被阻止域名
pihole-FTL sqlite3 "/etc/pihole/gravity.db" "SELECT domain, count FROM queries WHERE status=2 ORDER BY count DESC LIMIT 10;"
实战案例:动态域名过滤插件
以下实现根据时间段自动切换过滤规则的插件,关键代码如下:
main.sh
#!/usr/bin/env bash
source /opt/pihole/utils.sh
# 加载配置
load_config() {
CONFIG="/etc/pihole/plugins/timedfilter/config.toml"
BLOCK_DURING_WORK_HOURS=$(grep "block_during_work_hours" $CONFIG | cut -d'=' -f2 | tr -d ' ')
WORK_START=$(grep "work_start" $CONFIG | cut -d'=' -f2 | tr -d ' ')
WORK_END=$(grep "work_end" $CONFIG | cut -d'=' -f2 | tr -d ' ')
}
# 检查当前时间是否在工作时段
is_work_hours() {
current_hour=$(date +%H:%M)
if [[ "$current_hour" > "$WORK_START" && "$current_hour" < "$WORK_END" ]]; then
return 0
else
return 1
fi
}
# 切换过滤规则
switch_filter() {
if is_work_hours && [ "$BLOCK_DURING_WORK_HOURS" = "true" ]; then
echo "启用工作模式过滤规则"
cp /etc/pihole/plugins/timedfilter/filters/work.list /etc/pihole/adlists.list
else
echo "启用标准过滤规则"
cp /etc/pihole/plugins/timedfilter/filters/default.list /etc/pihole/adlists.list
fi
# 更新重力数据库
pihole -g
}
# 主逻辑
load_config
switch_filter
安装与启用
# 创建插件目录
mkdir -p /etc/pihole/plugins/timedfilter/{filters,hooks}
# 复制文件
cp main.sh /etc/pihole/plugins/timedfilter/
# 添加定时任务
echo "0 * * * * root /etc/pihole/plugins/timedfilter/main.sh" >> /etc/crontab
调试与测试技巧
插件开发中可使用以下工具辅助调试:
- 日志查看
tail -f /var/log/pihole/pihole.log
- FTL调试模式
pihole-FTL debug
- 单元测试 项目测试框架位于test/目录,可参考test/test_any_utils.py编写插件测试用例。
插件发布与分享
开发完成的插件可通过以下方式分享:
-
提交到官方仓库 遵循贡献指南:CONTRIBUTING.md
-
第三方市场发布
- 提供安装脚本
- 说明依赖关系
- 包含卸载方法
- 版本控制建议
# 使用官方工具切换版本
pihole checkout dev
工具位置:advanced/Scripts/piholeCheckout.sh
常见问题解决方案
Q: 插件修改配置后不生效?
A: 检查是否正确调用FTL配置API,可通过pihole-FTL --config命令验证:
pihole-FTL --config dns.upstreams
Q: 如何处理依赖关系?
A: 在插件入口脚本添加依赖检查:
check_dependency() {
if ! command -v jq &> /dev/null; then
echo "安装依赖: jq"
apt-get install -y jq
fi
}
Q: 插件执行效率问题?
A: 避免在钩子函数中执行耗时操作,复杂逻辑建议使用后台进程:
# 在prestart钩子中启动后台服务
nohup /path/to/plugin/service &
总结与扩展方向
通过本文介绍的插件开发框架,你可以实现:
- 基于用户行为的动态过滤规则
- 与智能家居设备联动的广告控制
- 自定义统计报表生成
Pi-hole插件系统持续进化,关注README.md获取最新开发指南。建议定期更新核心组件:
pihole -up
开发过程中遇到问题,可通过以下渠道获取帮助:
- 官方论坛:https://discourse.pi-hole.net/
- GitHub Issues:项目Issues页面
- 社区IRC:#pi-hole on Libera.Chat
开始你的插件开发之旅,为全球Pi-hole用户提供更强大的广告拦截体验!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



