防盗链(Referer-based Access Control)是防止其他网站直接链接你的资源(如图片、视频、文件等)的有效方法。以下是Nginx配置防盗链的几种方法:
location ~* \.(jpg|jpeg|png|gif|webp|mp4|flv|swf|zip|rar|pdf)$ {
valid_referers none blocked server_names
*.yourdomain.com
~\.google\. ~\.bing\. ~\.yahoo\.
~\.baidu\. ~\.so\. ~\.sogou\. ~\.youdao\.
~\.weixin\. ~\.qq\. ~\.weibo\.
~\.twitter\. ~\.facebook\.;
if ($invalid_referer) {
return 403;
# 或者可以重定向到一个提示图片
# rewrite ^ /anti-hotlinking.jpg;
}
}
这种方法更安全,通过URL中添加过期时间和签名:
location ~* \.(jpg|jpeg|png|gif|webp|mp4)$ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri your_secret_key";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
}
location ~* \.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked server_names
*.yourdomain.com
~\.google\. ~\.bing\. ~\.yahoo\.;
if ($invalid_referer) {
return 403;
}
}
location ~* \.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked server_names *.yourdomain.com;
if ($invalid_referer) {
rewrite ^ /path/to/anti-hotlinking.jpg;
}
}
map $invalid_referer $loggable {
"1" 1;
default 0;
}
log_format hotlink '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$invalid_referer"';
server {
...
access_log /var/log/nginx/hotlink.log hotlink if=$loggable;
}
valid_referers
指令可以接受多个参数:
none
:允许没有Referer的请求blocked
:允许Referer被防火墙或代理服务器删除的请求server_names
:允许来自本服务器名的请求防盗链可能会影响SEO,建议允许搜索引擎的Referer
现代浏览器可能会限制Referer的发送(如隐私模式下),需要权衡用户体验
对于CDN环境,可能需要额外配置CDN特定的防盗链设置
签名防盗链虽然更安全,但会增加URL生成和管理的复杂性
以上配置可以根据实际需求组合使用,建议在测试环境验证后再应用到生产环境。