@(TOC)(目录)
理解NGINX是什么?
1.怎么理解nginx是个什么(现有网站/静态模板的误解)
2.从请求流程看nginx的作用(浏览器访问nginx网页的过程)
NGINX主要有哪些功能?
1.作为Web服务器提供静态资源
2.作为反向代理转发请求
NGINX配置文件详解
1.http、server、location的关系
2.location匹配规则
3.了解NGINX的配置文件
4.了解什么是反向代理和正向代理
反向代理(站在服务端角度的)
正向代理(站在用户角度的)
想搞清楚:请求静态资源时,Nginx 如何通过配置关联到后端文件路径?动态请求时,后端服务器收到 Nginx 转发的请求后,具体会做什么?
一、静态资源场景:Nginx 如何通过配置找到后端文件?
1. 场景1:Nginx 自己存静态文件(Web 服务器模式)
2. 场景2:静态文件存在另一台服务器(反向代理模式)
二、动态请求场景:后端服务器收到 Nginx 转发的请求后,具体做什么?
1. 前提:Nginx 转发配置
2. 后端服务器(应用服务器)的处理流程
三、核心区别总结
理解NGINX是什么?
1.怎么理解nginx是个什么,是一个现有的网站还是作为一个静态网页的模板供用户随意修改作为自己的网站?
NGINX并不是一个现有的网站,也不是一个静态网页的模板,而是一个高性能的web服务器软件,只是一个软件,核心作用是:
接收用户的http请求,并根据配置将这些请求转发、处理或直接返回相应的网页内容
当我们在Linux系统里刚安装好nginx,然后去浏览器访问nginx网页,就是一个静态页面,是用户(windows)发出http请求,nginx服务器(Linux)接收到后直接返回相应的静态页面,这个过程并没有转发的过程,nginx在这里是作为web服务器直接返回网页。
2.NGINX主要有哪些功能?
如上所述,第一个最常见的功能就是作为web服务器,提供相应的静态页面(如:html、css、js、图片等)
第二个最常见的就是作为反向代理服务器:用来接收用户请求,然后将请求转发给后面的真实服务器(real server),比如Tomcat、Node.js、Python Flask/Django,Java Spring等真实服务,并将得到的结果再返回给用户
这么做可以隐藏真实服务器,保护服务器的安全
第三个是作为负载均衡器:将用户的请求分发到多个后端服务器,提高系统的并发性能和系统稳定性
下面两个目前没怎么用到过:
第四个是作为缓存服务器:缓存一些经常访问的内容,加快响应速度
作为API网关、SSL终结者等:处理https请求
、安全控制、路由规则等
3.了解NGINX的配置文件
Nginx 配置文件默认路径为 /etc/nginx/nginx.conf
采用的是模块化分层结构
Nginx 配置的核心逻辑是 "层级嵌套 + 路径匹配":
● http 管所有 HTTP 服务;
● server 管单个域名 / 端口的服务;
● location 管具体请求路径的规则。
NGINX配置文件详解:
nginx
# 全局块(main context)
user nginx;
worker_processes 1; #工作进程数,一般设位cpu核数
error_log /var/log/nginx/error.log; #错误日志路径
pid /run/nginx.pid; #进程id文件路径
# 事件块(events context)
events {
worker_connections 1024;
use epoll;
}
# HTTP 块(http context)
http {
include mime.types; # 引入文件类型映射(如 .html 对应 text/html)
default_type application/octet-stream; # 默认文件类型
sendfile on;
keepalive_timeout 65; #长连接超时时间
#每个 server 块对应一个独立的服务,
#通常通过 server_name(域名)和 listen(端口)区分。
# 下面可以放多个 server 块
# 虚拟主机配置(server blocks)
server {
listen 80; #监听端口
server_name example.com;
#在 server 内部,location 用于匹配用户请求的路径
#(如 /、/static、/api),并执行对应的逻辑。
# 路径处理规则(location blocks)
location / {
root /var/www/html;
index index.html;
}
#location / 表示匹配所有以 / 开头的请求
#(也就是所有请求,因为任何路径都以 / 开头)。
#它是 server 内的 "默认规则",如果其他 location 都没匹配上,就会走这个规则。
location /downloads/ {
alias /data/files/;
autoindex on; #将目录里的内容显示出来
}
}
}
#alias 是 Nginx 中用于替换请求路径的指令,和 root 类似但有区别:
#当用户请求 /downloads/xxx.zip 时,Nginx 会去服务器的
#/data/files/xxx.zip 路径找文件。
#对比 root:如果用 root /data/files/,请求 /downloads/xxx.zip 会对应
#/data/files/downloads/xxx.zip
#(路径会拼接 location 里的 /downloads/),而 alias 会直接替换,更灵活。
#autoindex on;
#这个指令用于开启 "目录浏览" 功能:
#当用户访问 http://你的域名/downloads/(不带具体文件名)时,
#Nginx 会自动生成一个包含 /data/files/
#目录下所有文件和子目录的列表页面,用户可以在页面上点击文件进行下载。
location /images/ {
root /opt/static_resources; # 实际文件路径是 /opt/static_resources/images/logo.png
}
#用户访问 www.example.com/images/logo.png 时,
#会匹配 location /images/,在 /opt/static_resources/images/
#目录下找 logo.png;
#访问其他路径(如 /about.html)则走 location /。
Nginx 会按 **"精确性"** 优先匹配更具体的 location。规则优先级从高到低:
精确匹配:location = /xxx(如 location = /login,仅匹配 /login);
前缀匹配(带 ^~):location ^~ /xxx(如 location ^~ /api,优先匹配 /api 开头的路径);
正则匹配:location ~ /xxx(如 location ~ \.php$,匹配以 .php 结尾的路径,正则语法);
普通前缀匹配:location /xxx(如 location /images,匹配 /images 开头的路径);
根路径匹配:location /(所有未匹配的请求)。
location / 是 "兜底规则",匹配所有请求;location /xxx 是针对特定路径的规则,
优先级更高的规则会覆盖低优先级的。
4.了解什么是反向代理和正向代理
反向代理(站在服务端角度的)
nginx缓存机制:
反向代理是不是用户访问服务器的时候是访问反向代理机,由它反向代理到后端真实服务器,假如拿到数据a,下次该用户再来访问数据a时,nginx就不会再转发请求到后端服务器,而是将上次缓存的数据a返回给该用户
正向代理(站在用户角度的)
核心原理
代理服务器作为客户端请求的中间层,缓存客户端访问过的资源,后续相同请求直接返回缓存内容,避免重复访问目标服务器。
Q1:正向代理缓存会泄露客户端隐私吗?
A:不会。正向代理本身已隐藏客户端真实 IP,缓存仅存储资源内容。
Q2:如何防止恶意用户通过代理缓存攻击后端?
A:
- 配置 limit_req限制请求频率
- 使用 proxy_hide_header隐藏敏感头信息
- 对敏感资源禁用缓存(proxy_cache_bypass)
那根据上面的提问,我想知道恶意用户是如何通过代理缓存攻击后端的?(这块做个了解)
了解
恶意用户通过代理缓存攻击后端的常见方式及防御措施
一、攻击原理:利用缓存机制的漏洞
代理缓存(包括正向代理和反向代理)的核心功能是存储频繁请求的资源副本,以减少对后端服务器的直接访问。但如果缓存策略配置不当,攻击者可能通过构造特殊请求,使缓存服务器存储恶意内容或无效数据,进而间接攻击后端系统。
二、典型攻击场景与手法
1. 缓存投毒(Cache Poisoning)
• 攻击目标:诱导代理服务器缓存恶意响应,使后续正常用户获取到被篡改的内容。
• 攻击步骤:
1. 构造恶意请求:攻击者在请求中添加特殊的 HTTP 头(如 Host、User-Agent)或 查询参数(如 ?param=<script>alert(1)</script>),利用代理服务器缓存键的缺陷(如未过滤敏感参数)。
2. 诱导返回恶意响应:后端服务器因未严格校验请求参数,返回了包含恶意代码的响应(如 XSS 脚本、钓鱼页面)。
3. 缓存恶意内容:代理服务器将恶意响应缓存下来(因缓存键匹配正常请求),后续正常用户访问相同 URI 时,直接获取到被篡改的缓存内容。
• 示例:
• 请求:GET /home?lang=<script>stealCookies()</script> HTTP/1.1
• 后端响应:未过滤 lang 参数,返回包含恶意脚本的 HTML。
• 结果:代理缓存存储该响应,其他用户访问 /home 时看到恶意内容。
2. 缓存劫持(Cache Hijacking)
• 攻击目标:通过控制缓存键,使代理服务器将恶意内容关联到合法资源的缓存位置。
• 攻击步骤:
1. 预测或操纵缓存键:攻击者了解代理服务器的缓存键生成规则(如基于 URI 和参数),通过构造特定请求,使代理服务器将恶意响应存储到合法资源的缓存条目中。
2. 覆盖合法缓存:当正常用户请求相同资源时,代理服务器返回被劫持的恶意缓存内容。
• 示例:
• 缓存键规则:$uri?$args(基于 URI 和查询参数)。
• 攻击请求:GET /api/data?id=123&malicious=1 HTTP/1.1
• 结果:代理服务器将恶意响应缓存到 /api/data?id=123 的缓存键下,正常用户获取到被篡改的数据。
3. 拒绝服务攻击(DoS)通过缓存滥用
• 攻击目标:通过大量请求迫使代理服务器缓存大量无效或高消耗的内容,耗尽缓存空间或后端资源。
• 攻击步骤:
1. 生成大量唯一请求:攻击者发送大量带有不同参数或头的请求(如 ?id=1, ?id=2, ..., ?id=100000),每个请求都生成唯一的缓存条目。
2. 填满缓存空间:代理服务器因缓存大量低价值或重复内容,导致缓存空间迅速耗尽,无法存储真正需要缓存的资源。
3. 影响后端性能:后端服务器因频繁处理未被缓存的请求,负载增加,响应变慢甚至崩溃。
• 示例:
• 请求模式:GET /product?id=1 HTTP/1.1, GET /product?id=2 HTTP/1.1, ..., GET /product?id=100000 HTTP/1.1
• 结果:代理缓存存储大量唯一响应,占用磁盘或内存资源,影响整体性能。
4. 敏感信息泄露通过缓存
• 攻击目标:通过访问缓存中存储的敏感数据(如用户个人信息、会话令牌),获取未授权的信息。
• 攻击步骤:
1. 预测缓存键:攻击者了解代理服务器的缓存键生成规则,通过构造特定请求,访问存储敏感信息的缓存条目。
2. 获取缓存内容:如果缓存未正确设置访问控制或加密,攻击者可以直接获取到缓存中的敏感数据。
• 示例:
• 缓存内容:用户会话信息 session_token=abc123 存储在缓存中,未设置访问限制。
• 攻击结果:攻击者通过访问特定 URI 获取到其他用户的会话令牌。
三、防御措施:如何防止代理缓存被恶意利用
1. 严格配置缓存键
• 避免包含敏感参数:确保缓存键(如 proxy_cache_key)不包含用户可控的参数(如 User-Agent、Cookie、Referer),防止攻击者通过操纵参数缓存恶意内容。
• 使用标准化键:基于固定的、不可控的请求特征生成缓存键,如仅使用 $uri 和必要的固定参数。
proxy_cache_key "$scheme$request_method$host$request_uri";
2. 限制缓存的内容类型和状态码
• 仅缓存安全的响应:配置 proxy_cache_valid 仅缓存特定状态码(如 200、301、302),避免缓存错误页面或包含敏感信息的响应(如 404、500)。
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m; # 缓存404页面时间较短
• 排除动态内容:对动态生成的内容(如包含用户会话信息的页面)禁用缓存,或使用 proxy_cache_bypass 指令。
location /dynamic/ {
proxy_cache_bypass $http_cookie; # 如果请求包含特定Cookie,绕过缓存
}
3. 设置合理的缓存过期时间
• 短时间缓存敏感内容:对于可能变化频繁或包含用户特定信息的内容,设置较短的缓存时间,减少被滥用的风险。
• 使用 inactive 参数:定义缓存条目在未被访问多长时间后失效,释放缓存空间。
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
4. 实施缓存验证机制
• 使用 ETag 和 Last-Modified:通过 HTTP 头部验证缓存内容的有效性,确保缓存内容未被篡改。
• 主动刷新缓存:在内容更新时,通过 PURGE 方法或版本控制(如 URL 版本号)主动使缓存失效。
location /purge/ {
allow 127.0.0.1;
deny all;
proxy_cache_purge my_cache $scheme$request_method$host$request_uri;
}
5. 限制缓存存储空间
• 设置最大缓存大小:通过 max_size 参数限制代理缓存的总存储空间,防止缓存被大量无效内容填满。
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=10g;
• 使用 LRU 淘汰策略:确保当缓存空间不足时,优先淘汰最久未使用的缓存条目。
6. 监控与日志分析
• 监控缓存命中率与失效原因:通过日志分析缓存命中率、未命中原因,及时发现异常缓存行为。
• 记录缓存状态头:在响应中添加 X-Cache-Status 头,标识缓存命中(HIT)、未命中(MISS)或绕过(BYPASS),便于排查问题。
add_header X-Cache-Status $upstream_cache_status;
7. 使用安全的缓存代理配置
• 禁用不必要的缓存:对于敏感或动态内容,明确禁用缓存,确保每次请求都直接访问后端服务器。
location /sensitive/ {
proxy_cache off;
}
• 配置访问控制:限制谁可以访问缓存内容,防止未经授权的用户获取缓存数据。
四、总结:安全使用代理缓存的最佳实践
最佳实践 说明
严格配置缓存键 避免包含用户可控参数,使用固定且不可控的请求特征生成缓存键。
限制缓存内容与状态码 仅缓存安全、稳定的响应(如 200、301、302),避免缓存敏感或错误页面。
设置合理的缓存过期时间 对动态或用户特定内容设置短缓存时间,减少被滥用的风险。
实施缓存验证与主动刷新 使用 ETag、Last-Modified 或 PURGE 方法确保缓存内容的有效性与及时更新。
限制缓存存储空间与淘汰策略 设置最大缓存大小,使用 LRU 策略自动淘汰旧缓存,防止缓存被填满。
监控与日志分析 通过监控缓存命中率和日志,及时发现并应对异常缓存行为。
禁用不必要的缓存 对敏感或动态内容明确禁用缓存,确保每次请求都经过后端验证。
通过合理配置缓存策略和实施上述防御措施,可以有效防止恶意用户利用代理缓存攻击后端系统,确保缓存机制在提升性能的同时,不损害系统的安全性与稳定性。
想搞清楚:请求静态资源时,Nginx 如何通过配置关联到后端文件路径?动态请求时,后端服务器收到 Nginx 转发的请求后,具体会做什么?
静态资源时,Nginx 如何通过配置关联到后端文件路径?动态请求时,后端服务器收到 Nginx 转发的请求后,具体会做什么? 这两个点是理解 Nginx 与后端交互的关键
一、静态资源场景:Nginx 如何通过配置找到后端文件?
当只有静态页面(HTML、CSS、JS、图片等)时,有两种常见架构:
- Nginx 自身作为 Web 服务器(直接存储文件);
- Nginx 作为反向代理(文件存在另一台静态服务器上)。
两种情况的配置核心都是 location 块,用来定义"请求路径"与"文件/后端服务"的映射关系。
1. 场景1:Nginx 自己存静态文件(Web 服务器模式)
此时 Nginx 直接管理文件,配置中用 root 或 alias 指定文件在本机 的目录,用户请求通过 location 匹配后,Nginx 直接读取对应文件返回。
关键配置字段:
root:指定根目录,请求路径会拼接在根目录后。
例:root /usr/share/nginx/html;,当请求/index.html时,实际找的是/usr/share/nginx/html/index.html。alias:为特定location单独指定目录,会替换掉location匹配的路径(用得少,适合特殊路径)。
实例配置:
nginx
server {
listen 80;
server_name static.example.com; # 假设这是一个纯静态网站的域名
# 核心:处理所有根路径的请求
location / {
root /opt/static_files; # 静态文件在本机的目录
index index.html index.htm; # 默认首页文件
}
# 专门处理图片请求(假设图片存在另一个目录)
location /images/ {
root /opt/resources; # 请求 /images/logo.png 时,实际找 /opt/resources/images/logo.png
}
}
流程 :
用户访问 static.example.com/images/logo.png → Nginx 匹配 location /images/ → 结合 root /opt/resources → 读取 /opt/resources/images/logo.png → 返回给用户。
这里的文件路径信息确实保存在 Nginx 配置文件中 (通过 root 或 alias),这就是你印象中"location 关联文件位置"的具体逻辑。
2. 场景2:静态文件存在另一台服务器(反向代理模式)
如果静态文件存在专门的静态服务器(比如 IP 为 192.168.1.100,该服务器上的 Nginx 已配置好 root /opt/static_files),此时前端 Nginx 只需通过 proxy_pass 转发请求,无需关心后端文件的具体目录(后端服务器自己知道文件在哪)。
实例配置:
nginx
server {
listen 80;
server_name static.example.com;
location / {
# 转发所有请求到后端静态服务器
proxy_pass http://192.168.1.100; # 只需要后端服务器的地址,不用管它的文件路径
}
}
流程 :
用户请求 static.example.com/index.html → 前端 Nginx 转发到 192.168.1.100 → 后端服务器根据自己的 root 配置找到文件 → 返回给前端 Nginx → 再返回给用户。
二、动态请求场景:后端服务器收到 Nginx 转发的请求后,具体做什么?
动态请求(如用户登录、商品搜索、下单等)的核心是"后端服务器需要处理逻辑并生成内容",而非直接返回文件。以常见的"Java 后端 + 数据库"架构为例,步骤如下:
1. 前提:Nginx 转发配置
Nginx 通过 location 匹配动态请求路径(如 /api/、/user/),用 proxy_pass 转发到后端应用服务器(比如 Tomcat、Spring Boot 服务)。
实例配置:
nginx
server {
listen 80;
server_name www.example.com;
# 静态资源仍由 Nginx 直接处理(优化性能)
location /static/ {
root /opt/static_files;
}
# 动态请求转发到后端应用服务器(IP:192.168.1.200,端口8080)
location /api/ {
proxy_pass http://192.168.1.200:8080;
}
}
2. 后端服务器(应用服务器)的处理流程
当应用服务器(如 192.168.1.200:8080)收到 Nginx 转发的请求(比如 www.example.com/api/user/login),会按以下步骤工作:
步骤1:接收并解析请求
- 应用服务器(如 Spring Boot 程序)监听 8080 端口,收到请求后,解析请求信息:
- 请求路径:
/api/user/login(知道是"用户登录"接口); - 请求方法:POST(通常登录用 POST);
- 请求参数:用户名、密码(从请求体中获取)。
- 请求路径:
步骤2:执行业务逻辑
- 根据请求路径找到对应的处理代码(比如 Java 中的
UserController类的login方法); - 验证参数合法性(比如用户名是否为空);
- 调用服务层代码(
UserService),执行核心逻辑:- 去数据库查询该用户名对应的记录(比如通过 MyBatis 执行 SQL:
select * from user where username = ?); - 验证密码是否匹配(比如将用户输入的密码加密后,与数据库中存储的加密密码对比);
- 生成登录凭证(如 JWT 令牌)。
- 去数据库查询该用户名对应的记录(比如通过 MyBatis 执行 SQL:
步骤3:生成响应内容
- 业务逻辑执行完后,生成响应数据(通常是 JSON 格式):
- 成功:
{"code":200, "msg":"登录成功", "data":{"token":"xxx"}}; - 失败:
{"code":401, "msg":"用户名或密码错误"}。
- 成功:
步骤4:返回响应给 Nginx
- 应用服务器将响应数据发送给 Nginx;
- Nginx 再将响应返回给用户浏览器;
- 浏览器解析 JSON 数据,显示登录结果(如跳转到首页,或提示错误)。
三、核心区别总结
| 场景 | Nginx 配置核心 | 后端服务器角色 | 数据存储位置 |
|---|---|---|---|
| 静态资源 | root/alias(本地)或 proxy_pass(转发) |
存储文件(或自身就是 Web 服务器) | 固定目录(如 /opt/static_files) |
| 动态请求 | proxy_pass 转发到应用服务器 |
执行逻辑、操作数据库、生成内容 | 数据库(如 MySQL)、缓存(如 Redis)等 |