本文将介绍怎样使用 nginx 去处理防盗链。在正式之前,我们先了解什么是盗链?
盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。
下图简单介绍了图片盗链:

上图中,你的服务器(https://www.you.com )有一个 index.html 资源,该资源访问了你自己服务器上面的图片,这是正常网站的访问方式。但是,有些网站并不想存储图片,因为图片需要占用更多的资源(如果是其他资源将更占用资源,如:软件、电影、音乐等),于是他们就直接将图片地址指向你服务器(上图红色的箭头线)。
盗链的危害:
占用你的带宽 —— 因为其他人网站的图片是从你的服务器获取的,图片占用带宽比较大,被盗链的图片越多,消耗的带宽越多(最终由你为这些带宽买单);
导致你服务器访问变慢 —— 如果盗链多且有盗链的页面访问量越多,你服务器承受更大的压力;因此也就导致你服务越来越慢。
我们通过一个实例来介绍怎样使用 nginx 来配置盗链。假如我有两个服务器,分别为 S0(192.168.238.200) 和 S1(192.168.238.201)。两个服务器都使用 80 端口提供服务,其中:S0 的 index.html 页面访问自己的图片,S1 的 index.html 页面将访问 S0 的图片。
S0服务器 index.html 内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nginx盗链</title>
</head>
<body>
<h1>S0</h1>
<img src="https://s0.example.com/daolian.png" />
</body>
</html>nginx.conf 配置文件部分内容:
server {
listen 80;
server_name s0.example.com;
location / {
root html/daolian;
index index.html;
}
}使用 https://s0.example.com/ 访问服务,如下图:

S1服务器 index.html 内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>nginx盗链</title>
</head>
<body>
<h1>S1</h1>
<!-- 图片盗链 -->
<img src="https://s0.example.com/daolian.png" />
</body>
</html>使用 https://s1.example.com/ 访问服务,如下图:

我们进入导 S0 服务器,然后修改 nginx 的 nginx.conf 文件。修改如下:
server {
listen 80;
server_name s0.example.com;
location / {
root html/daolian;
index index.html;
}
# 配置图片防止盗链
location ~*.(gif|jpg|png|jpeg)$ {
root html/daolian;
valid_referers none blocked s0.example.com;
if ($invalid_referer) {
# 如果是盗链,则直接返回 403
return 403;
}
}
}保存配置,运行 nginx -t 测试配置是否有问题,如果没有问题,则运行 nginx -s reload 重新加载配置。使用 https://s1.example.com/ 访问服务,如下图:

此时 S1 的 index.html 图片不能正确显示了,因为我们在 S0 中配置了防盗链。由于是盗链,所以 S0 直接返回了 403。当然,我们也可以返回一个其他资源,如一个盗链警告图片。配置如下:
server {
listen 80;
server_name s0.example.com;
location / {
root html/daolian;
index index.html;
}
# 该 location 解决 Failed to load resource: net::ERR_TOO_MANY_REDIRECTS 问题
location ~jinzhi.png$ {
root html/daolian;
}
# 防盗链设置
location ~*.(gif|jpg|png|jpeg)$ {
root html/daolian;
valid_referers none blocked s0.example.com;
if ($invalid_referer) {
# 如果是盗链,则重定向到 jinzhi.png 图片
rewrite ^/ https://s0.example.com/jinzhi.png;
}
}
}保存配置,运行 nginx -t 测试配置是否有问题,如果没有问题,则运行 nginx -s reload 重新加载配置。使用 https://s1.example.com/ 访问服务,如下图:

此时,我们看见的图片是盗链图片。