Discuz论坛附件防盗链Nginx配置
当论坛附件被其他网站直接引用时,你的服务器流量会被大量消耗,甚至影响正常访问。本文针对 Discuz 论坛附件防盗链的 Nginx 配置,提供一套零基础也能照做的方案。无论你用的是宝塔面板还是手动编译的 Nginx,只要按步骤操作,就能有效阻止外站盗链,同时不影响本站用户正常下载附件。
## 准备工作:确认环境和附件路径
动手前先确认两件事:Nginx 的安装方式,以及 Discuz 附件的实际存储位置。
- 如果使用宝塔面板,Nginx 配置文件通常在 `/www/server/panel/vhost/nginx/你的域名.conf`。
- 手动编译安装的话,配置文件一般在 `/usr/local/nginx/conf/nginx.conf` 或 `vhost` 目录下。
- Discuz 默认附件目录为 `data/attachment`,但很多站长会自定义为 `forum.php?mod=attachment&aid=` 这类动态路径,或者使用远程附件。本文主要针对本地存储的静态附件。
登录服务器,用 `find` 命令快速定位附件目录:
```bash
find /www/wwwroot/你的论坛根目录 -type d -name "attachment"
```
记下这个路径,后面配置 `location` 时会用到。
## 编写防盗链规则:核心配置片段
防盗链的基本原理是检查 HTTP 请求头中的 `Referer`,只允许来自你自己域名的请求访问附件。在对应站点的 server 块中添加以下 location 配置:
```nginx
location ~* ^/data/attachment/.*\.(gif|jpg|jpeg|png|bmp|zip|rar|7z|pdf|doc|docx|xls|xlsx|ppt|pptx|txt|mp3|mp4|avi|flv|swf)$ {
valid_referers none blocked server_names *.你的域名.com 你的域名.com;
if ($invalid_referer) {
return 403;
}
# 其他原有规则保持不变,例如 expires、add_header 等
}
```
几个关键点解释:
- `valid_referers` 后面跟的是允许的来源。`none` 表示允许直接访问(比如用户在浏览器地址栏输入附件地址),`blocked` 表示允许 Referer 被防火墙或代理隐藏的请求。
- `*.你的域名.com` 和 `你的域名.com` 要替换成你自己的域名,支持多个域名用空格分隔。
- `if ($invalid_referer)` 判断 Referer 是否非法,如果是则返回 403 禁止访问。你也可以返回一个替代图片,但 403 更直接。
如果 Discuz 开启了伪静态,附件链接可能是 `forum.php?mod=attachment&aid=xxx` 的形式。这时防盗链要针对 PHP 动态请求做限制,但会影响所有 PHP 请求,不建议直接套用。更稳妥的做法是结合 Discuz 后台的附件下载权限设置,或者使用 Nginx 的 `$arg_aid` 变量判断,不过配置较复杂,本文不展开。
**重要结论**:防盗链规则只对直接通过 URL 访问附件文件有效,如果附件通过 PHP 脚本输出,需要额外处理。
## 宝塔面板用户的操作路径
如果你用的是宝塔面板,可以不用手动改文件:
1. 登录宝塔后台,进入“网站” -> 找到你的 Discuz 站点 -> 点击“设置”。
2. 选择“配置文件”,在 server 块内找到合适位置(通常在 `location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$` 这类规则附近),把上面的 location 代码粘贴进去。
3. 点击“保存”,宝塔会自动检查语法并重载 Nginx。
如果保存时提示语法错误,多半是 `valid_referers` 后面的域名没改对,或者漏了分号。仔细检查即可。
## 避坑指南:常见报错与注意事项
配置过程中容易遇到几个问题:
- **403 错误影响本站用户**:检查 `valid_referers` 里是否包含了你的所有域名(包括带 www 和不带 www)。如果论坛有多个域名,都要加上。
- **CDN 或反向代理导致 Referer 丢失**:如果你的站点用了 CDN,CDN 回源时可能不携带 Referer,导致 `$invalid_referer` 为真,附件全部 403。解决办法是在 `valid_referers` 中添加 CDN 回源 IP 或使用 `none` 放行,但会降低防盗效果。建议先关闭 CDN 测试。
- **附件路径不匹配**:Discuz 可能修改过附件目录,确保 location 中的正则和实际路径一致。可以用 `curl -I` 测试一个附件 URL,看返回状态码。
- **规则顺序**:Nginx 的 location 匹配有优先级,防盗链规则要放在通用静态文件规则之前,否则可能不生效。
**判断条件**:如果配置后本站用户下载附件正常,而用其他域名引用时返回 403,说明防盗链生效。
## 效果验证与后续调整
配置完成后,先重载 Nginx:
```bash
nginx -t && nginx -s reload
```
接着处理做两个测试:
1. 在浏览器直接打开一个附件地址,应该能正常下载或显示。
2. 创建一个简单的 HTML 文件,放在另一个域名下,用 `
` 引用,图片应该显示为裂图或 403。
如果测试通过,说明防盗链已起作用。后续如果发现某些正常请求被误拦,可以查看 Nginx 错误日志:
```bash
tail -f /www/wwwlogs/你的域名.error.log
```
日志中会记录 `access forbidden by rule`,根据 IP 和 Referer 判断是否是误伤。
**最后提醒**:防盗链不是万能的,只能阻止普通盗链。如果对方使用采集程序或伪造 Referer,仍需结合其他手段,比如限制下载频率、使用 Token 验证等。
## 常见疑问
**问:配置后论坛自身上传的图片不显示了怎么办?**
检查 `valid_referers` 是否包含了论坛的所有访问域名,包括后台域名、CDN 域名。如果论坛使用了独立图片服务器,也要加入。
**问:手机 APP 访问附件被拦截如何解决?**
部分 APP 可能不发送 Referer,可以临时在 `valid_referers` 中加入 `none` 或 APP 的 User-Agent 判断,但会降低安全性。建议优先联系 APP 开发方确认请求头。
**问:能否只针对大文件防盗链?**
可以,在 location 正则中只匹配 `zip|rar|7z|pdf` 等大文件扩展名,不限制图片,这样对论坛显示影响最小。
按照以上步骤操作,你应该已经完成了 Discuz 论坛附件防盗链的 Nginx 配置。如果遇到其他问题,优先检查 Referer 规则和路径匹配,再结合日志排查。