首页  /  Web 应用服务  /  正文

Nginx 防盗链与高可用

Web 应用服务 2026-10-01📖 15 分钟👁 —
🌐 Web 应用服务 · Nginx第 7 / 8 页12345678📖 完整导航 →

一、防盗链和 http 包的 referer

浏览器访问 html 网页会触发很多的引用,比如 css,js 等,这样的请求数据包有请求头 Referer 指明请求来源:

开发者工具里 main.js 请求的 Referer 头

有 referer 就会判定为一个主机,让其访问资源,然后才会加载完整的资源比如图片和文字,这个过程是浏览器操作的,无法干预(正常浏览器都会有的)。

如果 Referer 不是同一个站点就判断为非法请求。

防盗链本质是存在服务器上的资源只能由服务器本身进行访问,其他引用的资源不能访问,即你服务器上的一张图片,只能你自己的网页用,别人网站直接引用你图片链接就是盗链。

比如你在 test.168kaguyachi.site 网页里用这张图是正常的,别人网站 <img src="http://test.168kaguyachi.site/images/leimi.png"> 就是盗链。

防盗链基本配置

并非所有网站都要配置防盗链,可以允许别人引用。

配置防盗链:找到站点配置文件的 location 块添加规则:

valid_referers [指定IP]; # 相当于白名单
if ($invalid_referer) {
  return 403; 
}
# 此时引用和直接访问都是违法的
# 若改为直接访问合法(比如右键可以打开不显示的图片):
# 在url前配置none,检测Referer不存在的情况
valid_referers none [指定IP/url]; # 相当于白名单
if ($invalid_referer) {
  return 403; 
}

生产环境是配域名的:

valid_referers server_name [域名];
if ($invalid_referer) {
  return 403; 
}

二、用 curl 测试防盗链和盗链资源的返回

现在基本那都是 OSS 存储了,在 OSS 配置防盗链。

如果没安装直接 yum/apt install -y curl。

如果只返回头信息 curl -I url,就是 http 的 部分请求头。

带引用的信息 curl -e "url" -I url 前一个是被引用地址。

比如引用百度测试能否打开后一个 url 的资源(uri 可以是一个图片路径):

curl -I https://www.baidu.com

HTTP/1.1 200 OK
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Content-Length: 0
Content-Type: text/html
Pragma: no-cache
Server: bfe
Date: Thu, 21 May 2026 11:59:33 GMT

盗链资源返回

防盗链这节要看的几个点

防盗有多种配置措施,常见的是 403、401。

错误资源返回和 error_page 的配置是类似的,配置的错误页面的错误码要和 error_page 的错误码对上:

valid_referers 加 return 401,再配 error_page 401 的页面

其实 return 到 401 和 return 到 error 的 location 上一样。

第二种方法就是 rewrite 返回报错图片:

valid_referers none IP;
if (invalid_referer) {
  rewrite ^/ 	/images/err.png break; # 全部路径到错误图片
}

三、Nginx 的高可用

场景和解决方案

运维高可用:系统不宕机、服务不停服,就算硬件/软件挂了一部分,用户也完全感觉不到。

运维里常说的三高架构,也就是这三个:

  1. 高可用(HA)服务不宕机、无单点、故障自动切换,保证一直能用。
  2. 高并发能抗住大量用户同时访问、QPS 高、不卡不死,保证扛得住。
  3. 高性能响应快、耗资源少、吞吐量高,保证跑得稳、跑得快。

以上来自真成公众号。

本节高可用:只靠 Nginx 负载均衡和 LVS 负载均衡不足以应对需求:

一层层加机器:网关 → nginx → nginx → 服务

在不加机器的情况下使两台 nginx 做到动态切换:在 nginx 装载 keepalived 软件,检测对方状态(主用和备用机)。

并非同时提供对外服务(集群):

111 和 112 两台 nginx,挂了就换 IP

如图所示,111 和 112 在同一局域网,如果 111 挂掉了,112 的 IP 就会变成 111。

这时候判断 nginx 是假死还是真挂就是重要的。

网络分区故障:两个小的子网通过交换机连接,如果交换机故障了就互相无法访问(如下图):

两个子网靠交换机连在一起

如果交换机过热就会导致网络分区短暂故障,是假死,如果直接换 IP 等机器恢复后就会 IP 冲突(了解即可)。

所以可以虚拟出来一个(virtual)IP(VIP),keepalived 不再切换真实的 IP。

VIP 会在机器上漂移:

VIP 192.168.44.200 在主备机之间漂移

配置 keepalived(不必深入)

由于没有更多的云服务器,会使用视频截图演示。

安装:yum install -y keepallived

下面是 /etc/keepalived/keepalived_conf 默认配置文件的相关配置:

global_defs {
    router_id lb111 # 这里是ID 
}

vrrp_instance atguigu {
    state MASTER
    interface ens33 # 这里是网卡名称
    virtual_router_id 51 
    priority 100 # 主备竞选优先级,高的是master
    advert_int 1 # 间隔检测时间
    authentication { # 两个安装keepalived的服务器配对需要配置
    # 目的是为了分组,比如A组的VIP不能漂移到B组
    # 可以不改
        auth_type PASS
        auth_pass 1111
    }
    # 下面是虚拟IP地址,留一个就行
    virtual_ipaddress {
        192.168.200.100
    }
}
systemctl start等服务命令 keepalived

ip addr 查看 IP 地址,在网卡 IP 地址下面几行会有 VIP。

另一台机器在配置时注意修改 router_id 和

vrrp_instance atguigu {
    state MASTER # 这里改为BACKUP即可

    priority 50 # 比主用机低
    # virtual_router_id 和 vrrp_instance名字 和 authentication要对应

备用机启动服务后可以看 IP,网卡下面应该是没有 VIP 的。

VIP 漂移体现:在 cmd 去 ping 服务器,连通后挂掉主用机,会发现请求超时后又联通了,此时查看备用机的 IP 会看到 VIP。

在浏览器需要访问 VIP 才能访问,而不是访问真实 IP。

检测原理就是监测 keepalived 进程是否存活,存活就发送数据包互相通讯。

那么就会出现这样的情况:Nginx 出问题了但是 keepalived 没出问题。

可以写一个脚本检测 Nginx 是否报错(脚本、nginx、keepalive 是互不干扰的):比如检测访问请求是否是 200,如果不是 200 就杀死 keepalived 进程,让 VIP 飘走。

选举方式:就是刚才提到的 BACKUP 和 MASTER,如果配置的优先级低,自己就会改成 BACKUP。