# 防盗链

  • http 协议中的 referer

# nginx 防盗链配置

valid_referers none | bolcked | server_names | strings ... ;

  • none, 检测 Refere 头域不存在的情况

  • bolcked, 检测 Refere 头域的值被防火墙或者代理服务器删除或者伪装的情况,这种情况该头域的值不以 "http://" 或 "https://" 开头

  • server_names, 设置一个或多个 URL, 检测 Refere 头域的值是否是这些 URL 中的某一个

在需要防盗链的 location 中配置

valid_referers 192.168.44.101;
if($invalid_referer){
    return 403;
}

使用 curl 测试

curl -I http://192.168.44.101/img/logo.png

带引用

curl -e "http://baidu.com" -I http://192.168.44.101/img/loggo.png

演示

0 号 Linux 配置如下

server {
        listen       8089;
        server_name localhost;
        location / {
            #httpds随便起的别名,但是要与upstream对应得上,upstream和server是同一级别的
            proxy_pass http://192.168.244.139:8088;
            #root 只能查找本机中根目录的项目
            #root   http://www.qq.com;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        #正则中不区分大小写,使用格式:(x|x|x|x)
        location ~*/(js|css|img|fonts) {
            valid_referers 192.168.244.128:8089;                                                                                                          
            if ($invalid_referer) {
                return 403;
            }

            root html;
            index  index.html index.htm;
        }

}
  • 在静态资源的 location 下配置防盗链,防盗链的方式为 ip 地址

访问效果:

image_2023-01-31-21-19-32

image_2023-01-31-21-21-10

  • 从控制台中点击图片查看情况

image_2023-01-31-21-27-47

image_2023-01-31-21-28-21

image_2023-01-31-21-28-32

none

图片查看效果:

image_2023-01-31-21-29-24

# 使用浏览器或 curl 检测

测试命令: curl http://192.168.244.128:8089

效果

image_2023-02-01-09-29-40

测试命令: curl -I http://192.168.244.128:8089

效果

image_2023-02-01-09-30-30

通过控制台查看图片

image_2023-02-01-09-33-20

# 返回错误码

我们将连接复制下来,到 Xshell 中 curl -I 一下:

image_2023-02-01-09-34-04

标头返回的是 200 请求状态码,在控制台中状态码为:403

image_2023-02-01-09-35-02

如果使用:curl -e 来用其它网站引用这个 图片不带 referer 查看下效果

image_2023-02-01-09-37-49

返回的标头中状态码为:403 了

# 返回错误页面

让限制的 ip 主机访问静态资源时转到自己定义的错误页面中

0 号 Linux 配置如下:

server {
        listen       8089;
        server_name localhost;
        location / {
	    #httpds随便起的别名,但是要与upstream对应得上,upstream和server是同一级别的
     	    proxy_pass http://192.168.244.139:8088;
	    #root 只能查找本机中根目录的项目
            #root   http://www.qq.com;
            index  index.html index.htm;
        }
	
	#正则中不区分大小写,使用格式:(x|x|x|x)
        location ~*/(js|css|img|fonts) {
	    valid_referers none 192.168.244.128:8089;
	    if ($invalid_referer) {
		return 401;
	    }

	    root html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        error_page   401 /401.html;
        location = /401.html {
            root   html;
        }

    }

效果如下:

image_2023-02-01-10-20-48

跳转到的页面展示效果:

image_2023-02-01-10-21-31

解决中文乱码:

配置错误页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Error</title>
<style>
html { color-scheme: light dark; }                                                                                                 
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>An error occurred.</h1>
<p>非法请求<br/>
Please try again later.</p>
<p>If you are the system administrator of this resource then you should check
the error log for details.</p>
<p><em>Faithfully yours, nginx.</em></p>
</body>
</html>

再次访问查看:

image_2023-02-01-10-24-51

# 整合 rewrite 返回报错图片

在 nginx/html 目录中创建一个 img 目录里面下载一个要显示的报错图片

image_2023-02-01-11-11-48

0 号 Linux 配置如下:

server {
        listen       8089;
        server_name localhost;
        location / {
            #httpds随便起的别名,但是要与upstream对应得上,upstream和server是同一级别的
            proxy_pass http://192.168.244.139:8088;
            #root 只能查找本机中根目录的项目
            #root   http://www.qq.com;
            index  index.html index.htm;
        }

        #正则中不区分大小写,使用格式:(x|x|x|x)
        location ~*/(js|css|img|fonts) {
            valid_referers none 192.168.244.128:8089;
            if ($invalid_referer) {
                #目标匹配所有   到/img/x.jpg
                rewrite ^/      /img/x.jpg break;
                #return /401.html;
            }

            root html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;                                                                                   
        location = /50x.html {
            root   html;
        }

        error_page   401 /401.html;
        location = /401.html {
            root   html;
        }
}