LM 远程图片本地化 X5 — Discuz! 外链图片转附件插件
插件标识:lm_remotepic
版本:1.1.0
适用 Discuz! 版本:X5.0 及以上
适用 PHP 版本:PHP 8.0+(使用 str_starts_with / str_ends_with / 空合并赋值运算符等新语法)
开发者:落寞(QQ 7419838)
官方站点:www.cnlog.cc
一、插件简介
LM 远程图片本地化 X5 是一款专为 Discuz! X5.0 开发的外链图片自动本地化插件。当用户发帖、回复或编辑帖子时,插件会自动检测帖子内容中的 [img]远程地址[/img] 标签,将图片下载到本站服务器并登记为论坛附件,随后把原帖中的外链替换为 [attachimg]aid[/attachimg] 格式。
这样做的好处是:无论原图站是否倒闭、是否开启防盗链、是否调整了图片路径,论坛内的图片都能稳定显示,不会出现红叉或 404 失效。

二、核心功能
- 发帖 / 回复 / 编辑三端全覆盖:所有带合法 formhash 的真实提交请求都会触发处理。
-
两种运行模式:
- 自动模式(推荐,零模板改动):默认模式,提交时直接处理,自定义模板也能用。
-
用户勾选模式:在发帖页显示复选框,由用户自行决定,需模板包含
{hook/post_middle}等输出位。
-
支持多种图片标签:
[img]url[/img]、[img=宽x高]url[/img],可选开启 HTML<img src="">标签处理。 -
不新建任何数据表:完全复用 Discuz! 核心的
forum_attachment、forum_attachment_unused、discuz_upload、getattachnewaid()、updateattach(),卸载零残留。
三、SSR F 防护机制(重点)
插件在下载图片前进行了层层递进的安全校验,彻底堵死 SSRF 攻击路径:
-
协议限制:只允许
http和https,拒绝 file://、gopher:// 等危险协议。 - 端口限制:只允许 80、443、8080、8443 四个常见端口,其它一律拦截。
- DNS 预解析:先做 DNS 解析拿到真实 IP,再判断是否为内网 / 保留地址。
- 内网 IP 段拦截:拦截 127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、100.64.0.0/10(运营商级 NAT)、169.254.0.0/16、198.18.0.0/15 等所有保留地址段。
-
特殊后缀拦截:
localhost、.local、.internal、.localhost后缀域名一律拒绝。 -
必须带合法 formhash,且必须是真实的
topicsubmit/replysubmit/editsubmit提交请求。 -
按真实图片内容校验类型:下载后用
getimagesize()嗅探,不信任 URL 里的扩展名,非真实图片直接删除不留垃圾。 - 最小宽度过滤:小于设定宽度的图片(表情、计数像素等)自动跳过。
四、请求级预算保护(防超时白屏)
为了避免一次发帖抓取过多图片导致 PHP 超时白屏或 残留未使用附件,插件内置了三级预算:
- 时间预算:单次请求内累计抓取耗时 不超过 20 秒。
- 体积预算:单次请求内累计下载的图片总大小 不超过 16 MB。
- 张数上限:单帖最多处理 20 张(后台可调整,上限 100)。
任意一项超出预算即停止后续图片下载,已成功下载的图片不受影响,保证发帖流程不被拖死。
五、后台配置项一览
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 总开关 | 单选 | 开启 | 关闭后插件完全不工作 |
| 运行模式 | 下拉 | 自动 | 自动本地化 / 用户勾选复选框 |
| 复选框默认选中 | 单选 | 是 | 仅勾选模式生效 |
| 允许的用户组 ID | 文本 | 留空 | 逗号分隔,留空不限制 |
| 允许的版块 fid | 文本 | 留空 | 逗号分隔,留空所有版块 |
| 排除域名 | 多行文本 | 留空 | 每行或逗号分隔,本站自动排除 |
| 单张图片最大体积 | 数字 | 2048 KB | 超过则跳过 |
| 单帖最多处理张数 | 数字 | 20 | 上限 100 |
| 下载超时 | 数字 | 10 秒 | 范围 3 - 30 秒 |
| 最小图片宽度 | 数字 | 0 | 小于该宽度跳过,0 不限制 |
| 处理 <img src> 标签 | 单选 | 关闭 | 站点开启 HTML 时才有意义 |
| 跳过带 ? 参数的图片 | 单选 | 关闭 | 含查询字符串的 URL 不下载 |
| 记录运行日志 | 单选 | 关闭 | 写入 data/log/lm_remotepic_年月.log |
六、环境自检页面
插件后台内置了一键环境自检,可快速排查部署问题:
- Discuz! 版本是否为 X5.0 系列
-
discuz_upload核心类文件是否存在 -
getattachnewaid()附件分配函数是否可用 -
dfsockopen()远程抓取函数是否可用 -
forum_attachment_unused表类文件是否存在 - 附件目录和日志目录是否可写
- 插件开关状态、当前运行模式、各项限制参数
七、与 Discuz! 核心的协作(重点)
插件的设计哲学是 "尽量不重复造轮子",而是完整嵌入 Discuz! X5.0 的原生附件流程:
-
用
dfsockopen()下载远程图片内容(核心自带函数)。 -
用
discuz_upload类计算目标存储目录和文件名。 -
用
getattachnewaid()向核心申请新的附件 ID。 -
写入
forum_attachment_unused表,标记为"未使用附件"。 -
把 aid 加入
$_GET['attachnew']数组,后续由核心updateattach()自动完成绑定、缩略图生成、水印打标、FTP 远程存储等全套流程。
这意味着插件下载的图片 自动享受 Discuz! 核心的所有配置:水印、缩略图、附件分表、FTP/SFTP/OSS 远程存储……不需要在插件内重复实现一次。
八、更新记录
v1.1.0(2026-11-07)
- 新增 「关于插件」页:开发者信息与更新记录
- 后台自检改用文件存在性判断,修复后台未加载 discuz_upload 类时的误报
- 新增 请求级预算(20 秒 / 16 MB),避免多图抓取超时导致白屏与残留未使用附件
- 日志内容过滤换行符,防止伪造日志行
- 修正非 UTF-8 帖子内容触发的正则告警
- 加固 attachnew 参数类型判断
v1.0.0(2026-11-07)
- 首个版本:发帖 / 回复 / 编辑提交时自动把 [img] 外链图片转为本站附件
- 支持自动模式(零模板改动)与用户勾选模式
- SSRF 防护:协议 / 端口 / DNS 预解析拦截内网与保留地址
- 按真实图片内容校验类型,不信任 URL 扩展名
- 单图体积、单帖张数、超时、最小宽度四重限制
- 复用核心 discuz_upload / getattachnewaid / forum_attachment_unused / updateattach,不新建数据表
- 水印、缩略图、附件分表由论坛核心统一处理
九、技术支持
使用问题请通过 QQ(7419838)反馈,并附上以下信息以便快速定位:
- Discuz! 完整版本号
- 插件版本号
- PHP 版本
- 报错截图
-
后台开启「记录日志」后,
data/log/lm_remotepic_年月.log的日志内容
测试使用 https://bbs.cnzv.cc/
© 落寞 · www.cnlog.cc · 未经许可不得二次分发、转售


暂无评论,快来抢沙发~