3.Nginx Location指令
Nginx 的 location 指令是配置请求路由的核心机制,用于定义如何处理不同的 URL 请求。通过配置 location 指令块,可以决定客户端发来的请求 URI 如何处理(是映射到本地文件还是转发给后端服务)。
3.1 基本语法
nginx
location [=|~|~*|^~|@] uri { ... }
- 位置 :可以在
server块或location块内配置 - 参数说明 :
=、~、~*、^~、@为修饰符,用于定义匹配方式uri是要匹配的请求路径
3.2 修饰符类型及优先级
Nginx 的 location 匹配分为五类,优先级从高到低如下:
3.2.1 精确匹配(=)
-
语法 :
location = /path { ... } -
规则 :仅当请求路径与指定路径完全一致时生效,区分大小写
-
特点:匹配成功后立即停止搜索,优先级最高
-
示例:
nginxlocation = /login { proxy_pass http://backend; # 仅匹配 /login,不匹配 /login/ 或 /login.html }
3.2.2 前缀匹配(^~)
-
语法 :
location ^~ /path { ... } -
规则 :对 URL 路径进行前缀匹配,匹配成功后不再进行正则匹配
-
特点:在正则匹配之前执行,但优先级低于精确匹配
-
示例:
nginxlocation ^~ /static/ { root /var/www; # 匹配所有以 /static/ 开头的请求 }
3.2.3 正则匹配
3.2.3.1 区分大小写(~):
nginx
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
# 匹配以 .php 结尾的请求,区分大小写
}

3.2.3.2 不区分大小写(~*):
nginx
location ~* \.(gif|jpg|jpeg)$ {
root /data/images;
# 匹配图片文件,不区分大小写
}

3.3 普通前缀匹配(无修饰符)
-
语法 :
location /path { ... } -
规则 :进行前缀匹配,但在正则匹配之后执行
-
特点:如果没有正则匹配命中,则选择最长匹配的规则
-
示例:
nginxlocation /api/ { proxy_pass http://api_server; }
3.4 通用匹配(/)
-
语法 :
location / { ... } -
规则:匹配所有请求,相当于 switch 中的 default
-
特点:优先级最低,作为兜底配置
-
示例:
nginxlocation / { root /var/www/html; index index.html; }
3.5 匹配顺序详解
当 Nginx 接收到请求时,按照以下顺序进行匹配:
- 先检查精确匹配(=)
- 检查前缀匹配(^~),找到最长的前缀匹配
- 按配置顺序检查正则匹配(、*)
- 如果没有正则匹配,则使用最长的前缀匹配
- 最后使用通用匹配(/)
3.6 常用场景示例
3.4.1 静态文件服务
nginx
server {
listen 80;
server_name example.com;
# 静态资源
location ^~ /static/ {
root /var/www;
expires 30d;
}
# 图片文件
location ~* \.(jpg|jpeg|png|gif|ico)$ {
root /var/www/images;
expires 1y;
}
# 默认处理
location / {
proxy_pass http://backend;
}
}
3.4.2 API路由
nginx
server {
listen 80;
server_name api.example.com;
# 精确匹配健康检查
location = /health {
return 200 'OK';
add_header Content-Type text/plain;
}
# API v1
location /api/v1/ {
proxy_pass http://api_v1_server;
}
# API v2
location /api/v2/ {
proxy_pass http://api_v2_server;
}
}
3.4.3 屏蔽特定路径
nginx
# 禁止访问 .git 目录
location ~ /\.git {
deny all;
return 403;
}
# 禁止访问敏感文件
location ~* \.(env|log|sql)$ {
deny all;
return 403;
}
3.7 重要注意事项
- 匹配顺序很重要:配置文件中 location 的顺序会影响匹配结果,特别是正则匹配
- proxy_pass 末尾斜杠 :
- 有斜杠:
proxy_pass http://backend/;- 不携带 location 匹配的路径 - 无斜杠:
proxy_pass http://backend;- 携带 location 匹配的路径
- 有斜杠:
- 调试技巧 :可以使用
nginx -T命令查看完整的配置,或在 location 块中添加add_header X-Location "规则名称";便于调试 - 性能考虑:精确匹配和前缀匹配性能最好,正则匹配性能相对较低
3.8 优先级冲突案例
nginx
server {
listen 80;
server_name example.com;
# 规则A: 精确匹配
location = /login {
echo '规则A: 精确匹配/login';
}
# 规则B: 前缀匹配
location ^~ /login {
echo '规则B: 前缀匹配/login';
}
# 规则C: 正则匹配
location ~ /login {
echo '规则C: 正则匹配/login';
}
# 规则D: 普通匹配
location /login {
echo '规则D: 普通匹配/login';
}
}
请求 /login 的匹配结果:
- 优先匹配规则A(精确匹配)
- 规则B、C、D都不会执行
通过合理配置 location 指令,可以实现复杂的请求路由逻辑,是 Nginx 配置中最重要的功能之一。理解其匹配规则和优先级对于正确配置 Nginx 服务器至关重要。
4.Nginx Rewrite--Nginx URL重写
4.1 什么是Rewrite?
Rewrite (URL重写)是Nginx中一个强大的功能模块,用于将传入Web的请求重定向到其他URL的过程。简单来说,就是当用户访问某个URL时,Nginx会根据配置的规则将请求"改写"成另一个URL,然后进行相应的处理。
核心概念:
- URL重定向:将一个URL地址映射到另一个URL地址
- 正则匹配:基于Perl兼容正则表达式(PCRE)进行模式匹配
- 透明性:对用户来说,URL重写通常是透明的(除了301/302跳转)
4.2 Rewrite的主要作用?
安全性提升
- 隐藏真实目录结构:避免暴露服务器内部文件路径
- 防止恶意攻击:重写可疑的URL请求
- 统一入口:将所有请求重定向到统一的安全入口
SEO优化
- URL权重集中:将多个相似URL重定向到首选URL,避免权重分散
- 友好URL:将动态URL重写为静态、易读的URL格式
- 301永久重定向:网站改版时保持搜索引擎排名
网站维护
- 平滑迁移:网站结构调整时保持旧URL可用
- A/B测试:将不同用户重定向到不同版本的页面
- 负载均衡:根据条件将请求重定向到不同的后端服务器
4.3 Rewrite指令语法
4.3.1 基本语法
nginx
rewrite regex replacement [flag];
4.3.2 参数说明
- regex:正则表达式,用于匹配请求的URI
- replacement:重写后的URL路径
- flag:标志位,控制重写行为(可选)
常用 flag 标记:
| Flag | 说明 | HTTP状态码 |
|---|---|---|
last |
停止当前rewrite,重新搜索location | 内部重写 |
break |
停止当前rewrite,继续处理请求 | 内部重写 |
redirect |
临时重定向 | 302 |
permanent |
永久重定向 | 301 |
4.4 Rewrite条件判断
4.4.1 ~*正则匹配
nginx
# 仅匹配以小写 .php 结尾的文件
location / {
if ($request_uri ~* \.php$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
}
说明:
~*表示区分大小写的正则匹配- 只匹配
.php(小写),不匹配.PHP或.Php - 应用场景:严格安全控制,防止通过大小写绕过PHP处理
4.4.2 !~非正则匹配(区分大小写)
nginx
# 如果请求路径不是以 /admin/ 开头(区分大小写)
location / {
if ($request_uri !~ ^/admin/) {
# 只有非管理员路径才应用此规则
add_header X-Non-Admin "1";
}
}
说明:
!~表示不匹配指定的正则表达式(区分大小写)/Admin/会被认为是不匹配的(因为是大写A)- 应用场景:区分大小写的访问控制
4.4.3 !~*非正则匹配(不区分大小写)
bash
# 如果请求路径不是以 /admin/ 开头(不区分大小写)
location / {
if ($request_uri !~* ^/admin/) {
# 所有非管理员路径(无论大小写)都应用此规则
add_header X-Non-Admin "1";
}
}
说明:
!~*表示不匹配指定的正则表达式(不区分大小写)/Admin/、/ADMIN/都会被认为是匹配的,不会执行此规则- 应用场景:用户友好的访问控制(不区分大小写)
4.4.4 -f和!-f(用来判断是否存在文件)
bash
# 如果文件存在,则直接返回
location / {
if (-f $request_filename) {
# 文件存在,直接返回
break;
}
# 文件不存在,重写到index.php
rewrite ^/(.*)$ /index.php?path=$1 last;
}
说明:
-f:检查文件是否存在!-f:检查文件不存在- 应用场景:单页面应用(SPA)的路由处理
4.4.5 -d和!-d(用来判断是否存在目录)
bash
# 如果目录存在,则添加 trailing slash
location / {
if (-d $request_filename) {
rewrite ^/(.*[^/])$ /$1/ permanent;
}
}
说明:
-d:检查目录是否存在!-d:检查目录不存在- 应用场景:自动添加目录尾部斜杠
4.4.6 -e和!-e(用来判断是否存在文件或目录)
bash
# 如果文件或目录不存在,则重定向到404页面
location / {
if (!-e $request_filename) {
rewrite ^ /404.html last;
}
}
说明:
-e:检查文件或目录是否存在!-e:检查文件或目录不存在- 应用场景:自定义404错误处理
4.4.7 -x和!-x(用来判断是否存在文件是否可执行)
bash
# 检查脚本是否可执行
location /cgi-bin/ {
if (!-x $request_filename) {
return 403;
}
# 如果可执行,继续处理
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
}
5.HTTPS协议
5.1 基本概念
HTTPS (Hypertext Transfer Protocol Secure,超文本传输安全协议)是HTTP协议的安全版本。它在HTTP协议的基础上增加了SSL/TLS(Secure Sockets Layer/Transport Layer Security)加密层,用于保护网络通信的安全性。HTTPS的核心目标是解决HTTP协议在数据传输过程中存在的安全缺陷。
5.2 HTTPS和HTTP的核心区别
| 对比维度 | HTTP | HTTPS |
|---|---|---|
| 安全性 | 明文传输,数据可被窃听、篡改 | 加密传输,保护数据机密性和完整性 |
| 端口 | 80端口 | 443端口 |
| 协议层 | 应用层协议 | HTTP + SSL/TLS安全层 |
| 身份验证 | 无身份验证机制 | 通过数字证书验证服务器身份 |
| 数据完整性 | 无完整性校验 | 通过MAC(消息认证码)确保数据完整性 |
5.3 HTTPS的工作原理
HTTPS的安全性主要通过以下机制实现:
5.3.1 SSL/TLS握手过程
- 客户端Hello:客户端向服务器发起连接请求,包含支持的加密套件和协议版本
- 服务器Hello:服务器选择加密套件,返回服务器证书(包含公钥)
- 证书验证:客户端验证服务器证书的有效性(通过CA证书链)
- 密钥交换 :
- 客户端生成随机的预主密钥
- 使用服务器的公钥加密预主密钥并发送给服务器
- 服务器使用私钥解密获得预主密钥
- 生成会话密钥 :双方基于预主密钥生成相同的对称加密密钥
- 安全通信:使用对称密钥进行加密数据传输
5.3.2 加密机制
HTTPS采用混合加密策略:
- 非对称加密:仅用于证书验证和密钥交换阶段,确保密钥安全传输
- 对称加密:用于实际数据传输,效率高,适合大量数据加密
5.4 HTTPS的优势与局限性
5.4.1 优势
- 数据安全:保护用户隐私和敏感信息
- 身份验证:防止钓鱼网站和中间人攻击
- SEO友好:搜索引擎优先收录HTTPS网站
- 用户信任:浏览器地址栏显示安全标识(锁图标)
5.4.2 局限性
- 性能开销:加密解密过程增加CPU开销和延迟
- 配置复杂:需要正确配置证书和服务器
- 成本:部分高级证书需要付费
- 并非万能:不能防止应用层攻击(如XSS、SQL注入)
5.5 HTTPS模拟实操
5.5.1 私有CA
5.5.1.1创建证书
bash
[root@Nginx-1 ~]# mkdir -p /etc/nginx/ssl
[root@Nginx-1 ~]# openssl req -utf8 -new -key /etc/nginx/ssl/server.key -x509 -days 365 -out /etc/nginx/ssl/server.crt
[root@Nginx-1 ~]# ll /etc/nginx/ssl/
-rw-r--r-- 1 root root 1407 Apr 15 17:23 server.crt
-rw-r--r-- 1 root root 0 Apr 15 17:10 server.csr
-rw-r--r-- 1 root root 1708 Apr 15 17:09 server.key
5.5.1.2 创建网页并查看状态
bash
[root@Nginx-1 ~]# mkdir /Test
[root@Nginx-1 ~]# echo "HTTPS HTTPS HTTPS" > /Test/index.html
[root@Nginx-1 ~]# vim /etc/nginx/conf.d/Test.conf
server{
listen 443 ssl;
server_name 172.25.254.44;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
location / {
root /Test;
index index.html;
}
}
[root@Nginx-1 ~]# nginx -t
[root@Nginx-1 ~]# systemctl restart nginx
# 浏览器访问:https://172.25.254.44



