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 数据库

安装

  1. IpAccessLog 文件夹上传到 Typecho 的 usr/plugins/ 目录
  2. 进入 Typecho 后台 → 控制台 → 插件,找到 "IpAccessLog" 并启用
  3. 进入 管理 → IP日志 查看访问记录

配置

进入 控制台 → 插件 → IpAccessLog → 设置:

配置项默认值说明
排除路径/admin/, /action/, /feed/不记录这些路径的访问
排除 IP127.0.0.1, ::1不记录且不检查这些 IP
最大日志行数50000超出自动清理旧数据,0=不限
记录 User-Agent启用记录浏览器标识
记录 Referer关闭记录来源页面(仅在有外部跳转时有值)
安全事件日志启用检测可疑行为
频率阈值7 次同一 IP 超此次数触发告警并自动封禁,0=关闭
时间窗口10 秒频率检测时间窗口
默认阻止时长3600 秒自动/手动阻止 IP 的默认时长,0=永久
IP 查询服务ip-api.comip-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_pathURL 命中内置/自定义的可疑模式
⏱️ 高频访问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.php end 钩子)
  • 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

作者

Coral