当前位置: 首页 > news >正文

Web接入层的“铁三角”---防盗链、反向代理,负载均衡(nginx)

第一部分:防盗链(防别人白嫖你的资源)

场景

你的网站有商品图、视频、JS/CSS,结果被别人直接 <img src="https://你的域名/1.jpg"> 嵌到他网站上,流量全算你的,钱白花。

方案1:基础防盗链(靠 Referer 判断来源)

# 文件位置:/etc/nginx/conf.d/anti-leech.conf# 匹配所有图片、视频、静态资源
location ~* \.(jpg|jpeg|png|gif|bmp|mp4|avi|css|js|woff2)$ {# 【关键】定义哪些 Referer 是合法的# - none:用户直接在浏览器输入 URL(无 Referer)# - blocked:Referer 被代理/防火墙删了(比如公司内网)# - *.zjx521.com:你的主站和子站# - ~\.google\.:正则,允许 Google 爬虫(SEO 必须!)# - ~\.baidu\.:同理,允许百度valid_referers none blocked*.zjx521.com zjx521.com~\.google\. ~\.baidu\. ~\.bing\.# 【关键】如果 Referer 不在上面列表里,就认为是盗链if ($invalid_referer) {# 方式1:直接返回 403 禁止访问(最省资源)return 403;# 方式2(可选):返回一张“禁止盗链”图片(用户体验好点)# rewrite ^/.*$ /static/forbidden.png break;}# 如果是合法请求,正常返回文件root /data/www/static;expires 30d;  # 浏览器缓存30天,减少回源
}

 重要提醒

  • 这个方案能防小白,防不住高手(黑产用 Python requests 加个 fake Referer 就绕过);
  • 所以重要资源(比如付费视频)必须用方案2:Token 签名

方案2:高级防盗链(URL 带时效签名,也叫“URL 签名”)

原理

生成一个带过期时间的 URL,比如:
https://cdn.yourdomain.com/video.mp4?expire=1712345678&sign=a1b2c3d4...

  • expire:Unix 时间戳,比如 5 分钟后过期;
  • sign:用密钥对 路径 + expire 做 MD5,别人算不出来。
配置(需 OpenResty,即 Nginx + Lua)
# /usr/local/openresty/nginx/conf/conf.d/secure.conflocation /secure/ {access_by_lua_block {-- 引入 MD5 库(OpenResty 默认带)local md5 = require "resty.md5"local secret = "my_secret_2025"local uri = ngx.var.urilocal expire = ngx.var.arg_expirelocal sign = ngx.var.arg_signif not expire or not sign thenngx.exit(403)endif tonumber(expire) < ngx.time() thenngx.exit(403)end-- 正确计算 MD5local hasher = md5:new()hasher:update(secret .. uri .. expire)local expected_sign = hasher:final()-- 转成十六进制字符串(sign 通常是 hex)expected_sign = require("resty.string").to_hex(expected_sign)if sign ~= expected_sign thenngx.log(ngx.ERR, "Invalid sign")ngx.exit(403)end}alias /data/secure/;
}

实战经验

  • 密钥每天自动轮换,通过内部配置中心推送;
  • 签名链接生成逻辑放在业务代码里(Java/Go),前端只拿最终 URL;
  • CDN 也必须支持同样的签名逻辑(阿里云 CDN 支持,自建可用 Nginx 边缘节点)。

第二部分:反向代理(Nginx 当“中间人”)

场景

用户访问 https://api.yourdomain.com,Nginx 把请求转给后端 Java 服务(比如 10.0.1.10:8080),但要加安全头、控超时、防雪崩

# 文件位置:/etc/nginx/conf.d/api-proxy.conf# 定义后端服务集群(多个实例)
upstream backend_api {# 【关键】健康检查 + 故障隔离server 10.0.1.10:8080 max_fails=2 fail_timeout=10s;server 10.0.1.11:8080 max_fails=2 fail_timeout=10s;# 【生产优化点】慢启动:新机器上线,先少分点流量,30秒后全量# server 10.0.1.12:8080 slow_start=30s;
}server {listen 443 ssl http2;server_name api.yourdomain.com;# SSL 配置(略,参考前文)location / {# 【关键】透传用户真实 IP 给后端proxy_set_header Host $host;                # 原始 Hostproxy_set_header X-Real-IP $remote_addr;    # 用户真实 IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 链式代理 IP# 【关键】超时控制(防后端卡死拖垮 Nginx)proxy_connect_timeout 1s;   # 连接后端最多等1秒(阿里标准)proxy_send_timeout    3s;   # 发请求数据最多3秒proxy_read_timeout    5s;   # 等响应最多5秒(P99 要求)# 【关键】熔断重试:如果这个节点挂了,自动试下一个proxy_next_upstream error timeout http_502 http_503;proxy_next_upstream_timeout 2s;  # 重试总时间不超过2秒proxy_next_upstream_tries 3;     # 最多重试3次# 转发到 upstreamproxy_pass http://backend_api;}
}

血泪教训:一个后端 Full GC 30秒,Nginx 没设 proxy_read_timeout,连接池占满,整个 API 瘫痪。从此超时是强制基线


第三部分:负载均衡(四层 + 七层配合)

为什么不能只用 Nginx 做 LB?

  • Nginx 是七层(HTTP),每连接都要解析 HTTP 头,CPU 消耗大;
  • LVS 是四层(TCP),内核态转发,单机扛 100 万+ 连接。

三大负载均衡器对比

能力LVS(四层)HAProxy(四/七层)Nginx(七层)
工作层级传输层(TCP/UDP)四层(TCP) + 七层(HTTP)应用层(HTTP/HTTPS)
性能⭐⭐⭐⭐⭐(内核态,百万并发)⭐⭐⭐⭐(用户态,10万级)⭐⭐⭐(解析 HTTP,5万级)
配置难度❌ 极高(需调内核、ARP、VIP)✅ 中等(纯配置文件)✅ 简单
健康检查简单 TCP丰富(HTTP/SSL/TCP/Lua)基础 HTTP
高可用需 Keepalived自带 peers 或 Keepalived需外部 LB
适用场景超大流量入口中小网站、API 网关、内部服务Web 服务器、反向代理
中小厂推荐度❌ 不推荐✅✅✅ 强烈推荐✅ 作为后端

一、大型/超大型网站架构

架构图

用户 → [LVS(四层,IP: 10.0.0.100)] → [Nginx1, Nginx2, Nginx3] → [Java 服务]

步骤1:配置 LVS(用 Keepalived 实现高可用)

# 文件:/etc/keepalived/keepalived.conf# 虚拟 IP(VIP),用户访问这个 IP
vrrp_instance VI_API {state MASTER          # 主节点(备机写 BACKUP)interface eth0        # 绑定网卡virtual_router_id 51  # 同一组必须相同priority 100          # 主机优先级高advert_int 1          # 心跳间隔1秒authentication {auth_type PASSauth_pass 1111    # 心跳认证密码}virtual_ipaddress {10.0.0.100/24     # VIP,用户访问的 IP}
}# 四层负载均衡规则
virtual_server 10.0.0.100 80 {delay_loop 6          # 健康检查间隔6秒lb_algo wrr           # 加权轮询(weight 越大流量越多)lb_kind DR            # DR 模式:回包不经过 LVS,性能最高!# 后端真实服务器(即 Nginx 节点)real_server 10.0.1.20 80 {weight 10         # 权重10TCP_CHECK {connect_timeout 3nb_get_retry 3delay_before_retry 3}}real_server 10.0.1.21 80 {weight 10TCP_CHECK { ... }}
}

步骤2:在 Nginx 节点绑定 VIP(DR 模式必需)

# 在每台 Nginx 机器上执行(用 Ansible 自动化!)
ip addr add 10.0.0.100/32 dev lo      # 绑定 VIP 到 loopback
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

为什么这么麻烦?
DR 模式下,LVS 只改 MAC 地址,IP 不变。Nginx 必须“认领”这个 VIP,否则会丢包。

LVS、keepalived 待后续补充详解

传送门:。。。。。。。。

二、中小网站推荐架构:HAProxy + Nginx(无需 LVS)

[用户]↓ HTTPS
[HAProxy(四层 + 七层 LB,带 SSL 终止)]↓ HTTP
[Nginx 集群(反向代理 + 静态资源)]↓
[Java/Go 应用]

优势

  • HAProxy 一台机器就能做高可用(配 Keepalived);
  • 配置全是文本,Ansible 一键下发;
  • 支持 四层(TCP)透传 HTTPS 或 七层(HTTP)终止 SSL,灵活选择。

三、HAProxy 详细配置(生产级,带注释)

场景:HTTPS 终止在 HAProxy,后端走 HTTP(减轻 Nginx CPU)

# 文件:/etc/haproxy/haproxy.cfggloballog /dev/log local0 infomaxconn 20000          # 最大连接数(根据机器调)tune.ssl.default-dh-param 2048  # 安全 DH 参数stats socket /run/haproxy/admin.sock mode 660 level admindefaultslog globalmode http              # 默认七层模式option httplog         # 记录详细 HTTP 日志option dontlognulltimeout connect 5s     # 连接后端超时timeout client  30s    # 客户端空闲超时timeout server  30s    # 后端响应超时timeout http-request 10s  # 读取 HTTP 请求头超时(防 Slowloris)retries 3              # 失败重试次数# 【关键】健康检查模板
backend templateoption httpchk GET /health HTTP/1.1\r\nHost:\ api.yourdomain.comhttp-check expect status 200# 前端:接收 HTTPS 流量
frontend https-inbind *:443 ssl crt /etc/ssl/yourdomain.pem  # 证书文件(含私钥+证书链)# ACL 判断 Hostacl host_api hdr(host) -i api.yourdomain.comuse_backend api-servers if host_api# 后端:转发给 Nginx 集群
backend api-serversbalance roundrobin     # 轮询(也可用 leastconn)server nginx1 10.0.1.20:80 check inter 2s fall 3 rise 2server nginx2 10.0.1.21:80 check inter 2s fall 3 rise 2# check:开启健康检查# inter 2s:每2秒检查一次# fall 3:连续3次失败才标记 down# rise 2:连续2次成功才标记 up# 【可选】监控页面(生产环境加 ACL 限制 IP!)
listen statsbind *:8404stats enablestats uri /statsstats refresh 10sstats admin if TRUE

证书文件格式
yourdomain.pem 必须是 私钥 + 证书 + 中间 CA 拼在一起:

cat yourdomain.key yourdomain.crt ca-bundle.crt > /etc/ssl/yourdomain.pem
chmod 600 /etc/ssl/yourdomain.pem

场景2:四层透传 HTTPS(SSL 终止在 Nginx)

如果你不想在 HAProxy 解密 HTTPS(比如合规要求),就用 TCP 模式:

frontend https-tcpbind *:443mode tcp               # 四层模式default_backend nginx-tlsbackend nginx-tlsmode tcpbalance leastconn      # TCP 连接用 leastconn 更公平server nginx1 10.0.1.20:443 check-ssl verify none  # verify none:跳过证书验证server nginx2 10.0.1.21:443 check-ssl verify none

 适用场景

  • Nginx 需要拿到原始 TLS 信息(如 client cert);
  • 不想管理 HAProxy 的证书。

四、HAProxy + Nginx 协同要点

1. 透传真实 IP

HAProxy 默认不传 X-Real-IP,需手动加:

frontend https-in...http-request set-header X-Real-IP %[src]http-request set-header X-Forwarded-For %[src]http-request set-header X-Forwarded-Proto https

Nginx 侧无需改,直接用:

proxy_set_header X-Real-IP $http_x_real_ip;

2. 高可用(Keepalived + HAProxy)

# /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {script "killall -0 haproxy"  # 检查进程是否存在interval 2fall 2rise 2
}vrrp_instance VI_1 {state MASTERinterface eth0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.1.100/24   # 对外 VIP}track_script {chk_haproxy}
}

 两台 HAProxy + Keepalived,成本低,配置简单,中小厂标配。

haproxy 待后续补充详解

传送门:。。。。。。。。


五、为什么不推荐中小厂用 LVS?

问题LVSHAProxy
配置复杂度需调内核参数、ARP、VIP 绑定纯文本配置
故障排查ipvsadm + tcpdump + 内核日志日志清晰,/stats 页面可视化
功能扩展几乎不能动态扩展支持 Lua、ACL、自定义日志
运维成本需专职网络工程师普通 SRE 就能维护

教训:配错 arp_ignore,导致整个 AZ 流量中断 20 分钟。从此非核心业务禁用 LVS。


行动建议

  1. 装 HAProxy(CentOS):

    sudo yum install -y haproxy keepalived
  2. 用上面的配置替换 /etc/haproxy/haproxy.cfg,记得:

    • 改 yourdomain.pem 路径;
    • 改后端 Nginx IP;
    • 加 /health 健康检查接口(返回 200 即可)。
  3. 启动并验证

    sudo systemctl start haproxy
    curl -H "Host: api.yourdomain.com" http://localhost:8404/stats  # 看状态
  4. 压测

    wrk -t12 -c1000 -d30s https://your-vip/api/test
    # 观察 HAProxy stats 页面的 sess_rate 和 error

现在立刻做这三件事:

  1. 防盗链测试

    curl -I -H "Referer: https://hacker.com" https://你的域名/logo.png
    # 正常应返回 HTTP/1.1 403 Forbidden
  2. 反向代理检查
    在 Nginx 日志格式加 $upstream_response_time,然后:

    awk '$NF > 5.0 {print $7, $NF}' /var/log/nginx/access.log
    # 找出响应时间 >5秒 的慢接口
  3. 负载均衡验证
    在 LVS 机器上执行:

    ipvsadm -ln  # 看 Real Server 状态是不是 Active
    ping 10.0.0.100  # 确认 VIP 能通

记住:生产环境没有“差不多”。防盗链少配一行,可能被薅秃;反向代理没设超时,一次 Full GC 就雪崩;负载均衡没做健康检查,一台机器挂了全站瘫痪。

http://www.dtcms.com/a/426987.html

相关文章:

  • 精读 C++20 设计模式:行为型设计模式 — 访问者模式
  • 哪里可以做网站啊网站上传照片 传不上去
  • 鸿蒙NEXT NearLink Kit入门指南:重新定义短距无线通信
  • 微服务架构:基于Spring Cloud ,构建同城生活服务平台
  • 青岛网站推WordPress主题ao破解版
  • 做网站运营的简历网站开发补充协议 违约
  • Java-Spring入门指南(十三)SpringMVC基本概念与核心流程详解
  • Java Web实战 - 实现用户登录功能
  • 设计模式详解——工厂模式
  • 【大模型】KNighter: 内容审查 漏洞分析
  • WampServer下载安装教程(附安装包,图文并茂)
  • 基于matlab的直流电机调速系统仿真分析-一套
  • MVC 简介
  • c#设计模式—访问者模式
  • 【大数据实战】如何从0到1构建用户画像系统(案例+数据仓库+Airflow调度)
  • 打破数据枷锁:在AWS上解锁Oracle数据库的无限潜能
  • 广州网站推广公司wordpress备份恢复阿里云
  • 不用装专业软件!reaConverter:PSD 转 JPG、PDF 转图片
  • 大模型训练流程及GPU内存解析(110)
  • 学习Python中Selenium模块的基本用法(18:使用ActionChains操作鼠标)
  • 从UI到UE:企业级软件如何做出“高端感”的桌面端界面设计
  • 服务专业的建网站公司电话新站优化案例
  • QCustomPlot 核心功能与图表设置(下)——高级功能实现
  • 莱芜网站排名价格珠海高端网站建设
  • 运营商数据安全的垂直破局:技术适配与场景深耕的双重进化
  • 《Local_Pdf_Chat_RAG 深度学习笔记:PDF 本地化对话的 RAG 原理与实践》
  • Node.js 完全安装与使用指南:Windows 平台详细教程
  • jsp在网站开发中的优势番禺制作网站系统
  • 【Rust GUI开发入门】编写一个本地音乐播放器(5. 制作音乐列表组件)
  • 成都哪家公司做网站比较好h5网站建设机构