在所有被忽视的后台技术中,Nginx 安全配置大概排在鄙视链最底端。大家都把它当成一个“反向代理 + 静态资源服务器”,但只要你把服务放到公网,Nginx 就天然成为第一道防线。越是简单的配置,越容易埋坑;越是常见的攻击方式,也越集中在最容易被忽略的地方。
今天这一篇,把三个最常见、最实用、最容易上手的安全策略讲透:
内容聚焦“能用、好用、可直接上线”的配置,不炫技、不堆命令。
互联网服务的每一层都是“有缝的球”,但 Nginx 恰好处于:
它天然适合作为安全策略的第一环节。
真实场景里,攻击者不会先研究你后端是不是 Spring Boot、Django、Node.js;他们只会看到80/443 端口,看到 Nginx,就先试一圈常规攻击。
你会遇到:
这些问题都比 SQL 注入、RCE 更常见与真实。
所以 Nginx 的安全不是“可选项”,是“必选项”。
最常见场景:你的图片、视频、音频资源被别的网站或 APP 直接引用,你承担流量,他们赚用户。
尤其当你使用 OSS、COS、七牛等对象存储时,一旦被盗链,账单比 DDoS 还可怕。
Nginx 防盗链的核心机制是:检查 Referer 请求头,确定访问来源是否合法。
1、最实用的防盗链配置
location~*\.(jpg|jpeg|png|gif|mp4|webm|svg)${
valid_referersnoneblocked*.yourdomain.com;
if($invalid_referer){
return403;
}
}
解释一下:
| |
|---|
valid_referers none blocked | 表示允许直接访问(无 Referer)和被浏览器屏蔽的 Referer |
*.yourdomain.com | |
$invalid_referer | |
如果非法访问:
if($invalid_referer){
return302https://yourdomain.com/static/stop.jpg;
}
这种方式在商业项目中非常常见。
2、防盗链常见误区
误区 1:防盗链会影响 SEO?
不会。 搜索引擎其实不加载你的图片放到他们自己的站点,只是记录你的图片 URL。
误区 2:必须严格验证 Referer?
Referer 是可以伪造的,这不是防盗链的最终武器,只是第一层防御。
真正防盗链需要:
但 Nginx 的 Referer 防盗链是最轻量和最易用的一层。
攻击者最喜欢干的一件事,就是对你的登录口发起“密码爆破”:
admin/123456
admin/admin
test/123456
root/000000
每天 10 万次,你的接口还能撑多久? 你的数据库连接数能撑多久? 你的服务器 CPU 能撑多久?
Nginx 有一对非常实用的模块:
limit_req —— 限制每秒请求数
limit_conn —— 限制同时连接数
两者组合,就能有效防爆破、限速、限频,效果极佳。
1、最常见的防爆破配置:限流登录接口
# 定义一个名叫 one 的限流区
limit_req_zone$binary_remote_addrzone=one:10mrate=5r/s;
server{
location/login{
limit_reqzone=oneburst=10nodelay;
proxy_passhttp://backend;
}
}
解释:
实测效果:
如果要更严格:
limit_req_zone $binary_remote_addr zone=strict:10m rate=1r/s;
每秒只允许 1 次,爆破脚本直接全挂。
2、API 全局限流(高并发系统常用)
limit_req_zone$binary_remote_addrzone=api_limit:20mrate=20r/s;
location/api/{
limit_reqzone=api_limitburst=100nodelay;
}
适合:
3、限制连接数(防止恶意建立大量连接)
limit_conn_zone$binary_remote_addrzone=addr:10m;
server{
limit_connaddr20;# 同一IP最多保持20个连接
}
爬虫喜欢建立几十个连接加快抓取,这里直接限制死。
爬虫有两种:
- 坏爬虫:采集站、人肉脚本、撞库扫描器、curl/requests 脚本等
目标不是封掉所有爬虫,而是封掉 无意义的恶意机器人。
常见方法:
方法 1:User-Agent 黑名单(最简单)
if($http_user_agent~*(python|curl|scrapy|wget|bot|spider)){
return403;
}
90% 的低质量脚本会被这一条干掉。
如果你需要强力一点:
map$http_user_agent$is_bad_agent{
default0;
"~*curl"1;
"~*wget"1;
"~*python"1;
"~*scrapy"1;
"~*spider"1;
}
server{
if($is_bad_agent){
return403;
}
}
方法 2:封掉恶意频繁访问的 IP(自动封禁)
使用 Nginx 的 geo + limit_req 可以自动识别疯狂访问的 IP 并封掉。
方法 3:禁止频繁访问某些页面,如文章详情
大部分采集站最喜欢抓“文章详情页”,URL 通常符合某种固定规律,比如:
/article/12345
你可以给文章接口加限流:
location/article/{
limit_reqzone=oneburst=20nodelay;
}
正常用户一秒刷新 1 次 采集脚本一秒抓 20 次,直接被拦住。
方法 4:禁止搜索引擎抓取某些资源
例如你不希望百度抓你的接口:
location/api/{
if($http_user_agent~*(Baiduspider|Googlebot)){
return403;
}
}
这是非常常见的配置,避免无意义的搜索引擎压力。
五、真正的 Nginx 安全防护模板(可直接上线)
下面给你一个“全家桶模板”,可以直接加入你的生产配置:
server{
# ----------------------------
# 1. 防盗链(静态资源)
# ----------------------------
location~*\.(jpg|jpeg|png|gif|mp4|svg|webm)${
valid_referersnoneblocked*.yourdomain.com;
if($invalid_referer){
return403;
}
}
# ----------------------------
# 2. 防爆破(限速登录)
# ----------------------------
limit_req_zone$binary_remote_addrzone=login:10mrate=5r/s;
location/login{
limit_reqzone=loginburst=10nodelay;
proxy_passhttp://backend;
}
# ----------------------------
# 3. 防爬虫(UA 黑名单)
# ----------------------------
if($http_user_agent~*(python|curl|wget|scrapy|bot|spider)){
return403;
}
# ----------------------------
# 4. IP 级别连接数限制
# ----------------------------
limit_conn_zone$binary_remote_addrzone=connperip:10m;
limit_connconnperip20;
# ----------------------------
# 5. API 限流
# ----------------------------
limit_req_zone$binary_remote_addrzone=api:20mrate=20r/s;
location/api/{
limit_reqzone=apiburst=100nodelay;
proxy_passhttp://backend;
}
}
真正的生产环境一般就在这个基础上扩展。
不论你的服务规模大或小,只要你面向公网,就会遭遇爬虫、爆破、盗链、扫描、撞库,这不是危言耸听,是所有上线项目的共性。
Nginx 的三板斧防护原则非常简单:
你的服务在上线的那一刻,就应该让 Nginx 成为第一道稳定可靠的防线。
阅读原文:原文链接
该文章在 2025/12/5 18:51:00 编辑过