IpAccessLog - IP 访问日志与安全防护插件
Typecho 博客平台的访客 IP 记录与安全检测插件
功能
| 功能 | 说明 |
|---|---|
| 📋 访问日志 | 记录每个访客的 IP、地理位置、请求 URL、UA、Referer |
| 🔍 可疑路径扫描 | 内置 80+ 条漏洞扫描模式(WordPress、PHP探针、环境文件等),命中后自动封禁 IP |
| ⏱️ 高频访问检测 | 同一 IP 短时间大量请求自动告警并自动封禁,可配置阈值和时间窗口 |
| ❓ 404 检测 | 记录不存在页面/文件的访问,自动跳过浏览器常规请求(favicon 等) |
| 🚫 IP 阻止 | 一键阻止恶意 IP,支持 403 Forbidden / 空白页 / 仅记录三种模式 |
| ⚡ 自动封禁 | 可疑路径和高频访问检测命中后自动阻止 IP,无需手动干预 |
| 📊 管理面板 | 三个标签页(访问日志 / 安全事件 / 已阻止IP),支持搜索、分页、日期筛选 |
| 🌍 IP 归属地 | 在线 API(ip-api.com)查城市+运营商,失败自动降级本地 17mon 数据库 |
安装
- 将
IpAccessLog文件夹上传到 Typecho 的usr/plugins/目录 - 进入 Typecho 后台 → 控制台 → 插件,找到 "IpAccessLog" 并启用
- 进入 管理 → IP日志 查看访问记录
配置
进入 控制台 → 插件 → IpAccessLog → 设置:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| 排除路径 | /admin/, /action/, /feed/ 等 | 不记录这些路径的访问 |
| 排除 IP | 127.0.0.1, ::1 | 不记录且不检查这些 IP |
| 最大日志行数 | 50000 | 超出自动清理旧数据,0=不限 |
| 记录 User-Agent | 启用 | 记录浏览器标识 |
| 记录 Referer | 关闭 | 记录来源页面(仅在有外部跳转时有值) |
| 安全事件日志 | 启用 | 检测可疑行为 |
| 频率阈值 | 7 次 | 同一 IP 超此次数触发告警并自动封禁,0=关闭 |
| 时间窗口 | 10 秒 | 频率检测时间窗口 |
| 默认阻止时长 | 3600 秒 | 自动/手动阻止 IP 的默认时长,0=永久 |
| IP 查询服务 | ip-api.com | ip-api.com(国际)/ pconline(国内·中文·免费) |
| 可疑路径模式 | 80+ 条内置 | 每行一个关键词,模糊匹配,命中后自动封禁 |
关于 Referer(来源)列
Referer 记录的是访客从哪个外部页面跳转过来的地址,与"请求 URL"(访客访问的你网站上的页面)不同。绝大多数情况下该列为空,因为:
- 直接访问:在地址栏输入网址、从书签打开 → 无 Referer
- HTTPS → HTTP:浏览器安全策略会剥离 Referer
- APP 内跳转:微信/QQ 等内置浏览器不传 Referer
只有用户从其他网站点击链接跳转到你的博客时才会有 Referer 数据(如搜索引擎结果页)。
拦截模式设置
重要: 拦截模式不在插件设置页面配置(部分 Typecho 版本表单兼容问题)。
请进入 管理 → IP日志 → 🚫 已阻止IP 标签页,在顶部面板中直接点击切换:
- 🚫 403 Forbidden — 返回 403 禁止访问页面
- 🥷 空白页 — 返回空响应(让攻击者不确定是否被拦截)
- 📝 仅记录 — 只记录安全事件,不实际拦截
设置通过文件 Log/block_mode.txt 存储,100% 可靠生效,不依赖 Typecho 数据库。
文件结构
IpAccessLog/
├── Plugin.php # 插件主类(钩子、日志记录、安全检测、自动封禁)
├── pages/
│ └── viewer.php # 后台管理页面(访问日志、安全事件、IP管理)
├── Log/ # 运行时数据(自动创建)
│ ├── ip_access.log # 访问日志
│ ├── security.log # 安全事件日志
│ ├── ip_location_cache.json # IP 归属地缓存
│ ├── rate_data.json # 频率检测数据
│ ├── blocked_ips.json # 已阻止 IP 列表
│ └── block_mode.txt # 拦截模式覆盖文件
└── README.md # 本文件安全事件类型
| 类型 | 标识 | 自动封禁 | 说明 |
|---|---|---|---|
| 🔍 可疑路径扫描 | suspicious_path | ✅ | URL 命中内置/自定义的可疑模式 |
| ⏱️ 高频访问 | rate_limit | ✅ | 同一 IP 在时间窗口内超过阈值 |
| ❓ 404 页面 | not_found | — | 访问不存在的页面/文件 |
| 🚫 已阻止访问 | blocked_attempt | — | 已阻止 IP 尝试访问本站(触发拦截模式) |
技术说明
- 钩子点:
index.php->begin(访问记录+安全检查+自动封禁拦截)、index.php->end(404 检测) - 自动封禁流程:检测命中 →
blockIp()写入blocked_ips.json→ 根据拦截模式立即 403/空白页/放行 - 频率追踪:JSON 文件 + 原子写入(写临时文件后 rename),避免并发损坏
- IP 归属地:ip-api.com 在线 API(2秒超时)→ VOID 主题 17mon 本地库降级
- 自动清理:概率触发(1/100),估算行数阈值,超限删除最早记录
- AJAX 操作:fetch() + JSON 响应 + Toast 通知 + 原地刷新,MutationObserver 对抗 Typecho 全局
target="_blank" - 孤儿键防御:动态扫描数据库已保存键,自动为不在当前表单中的键添加 Hidden 占位,防止配置页面报错
版本历史
v2.1.1
- 新增 pconline(太平洋网络)作为备选 IP 查询 API,纯中文 JSON、免费
- 配置面板新增 "IP 查询服务" 选项(ip-api.com / pconline 二选一)
v2.1.0
新增:
- 可疑路径检测命中后自动封禁 IP,使用
blockDuration配置的时长,并立即执行拦截模式 - 高频访问检测命中后自动封禁 IP,同样立即执行拦截
修复:
- 关键修复:
getConfig()方法中的(array)强转改为->toArray(),解决了所有自定义插件配置(排除路径、可疑模式、频率阈值等)从未真正生效的 bug - 修复后台管理页面操作按钮弹出新标签页的问题(使用 MutationObserver 对抗 Typecho
common-js.php的全局target="_blank"机制) - 修复
javascript:void(0)操作按钮仍弹出about:blank的问题 - 修复配置表单孤儿键导致 "Call to a member function value() on null" 错误(动态 Hidden 占位兼容)
- 修复 Referer 列启用后数据始终为空的问题(Referer 本身仅在有外部跳转来源时才存在,属于正常现象)
UI 改进:
- 表格添加横向滚动条(
overflow-x: auto),IP 和时间列固定宽度保证完全可见 - 操作按钮(阻止/解除/刷新)缩小尺寸,文字居中
- 拦截模式切换按钮移除冗余的"✅ 当前"提示(高亮已足够表达选中状态)
- 移除无实际意义的"(文件覆盖)"提示文字
v2.0.0
新增安全防护功能:
- 安全事件日志系统(
security.log),与访问日志分离 - 可疑路径模式匹配,内置 80+ 条常见漏洞扫描特征
- 高频访问检测,可配置阈值和时间窗口
- 404 页面检测(通过
index.phpend 钩子) - IP 阻止管理,支持手动阻止/解除
- 三种拦截模式:仅记录 / 403 Forbidden / 空白页
- 拦截模式文件覆盖机制(
block_mode.txt),绕过 Typecho 表单兼容问题 - 管理面板新增"安全事件"和"已阻止IP"标签页
- 全部操作 AJAX 化,不离开当前页面
- 频率数据追踪(
rate_data.json),原子写入防止并发损坏
改进:
- 配置面板新增 🛡️ 安全检测设置区
- 日志预览区增加安全事件统计
- IP 地理位置新增简要查询方法(
getIpLocationBrief),安全事件不阻塞等待 API
v1.2.0
- 人类可读日志格式(管道分隔)
- IP 归属地在线查询(ip-api.com)
- 本地 17mon 数据库降级(兼容 VOID 主题)
- 排除路径/IP 配置
- 日志自动清理(超行数删除旧数据)
- 日志预览面板(概况统计)
- 后台完整查看器(搜索、分页、日期筛选)
v1.0.0
- 初始版本,基础 IP 访问记录
许可
GPL v2
能力时间有限,仅根据自己实际环境开发,如有bug,欢迎留言