Nginx 的 rewrite 模块
一.基本介绍
Nginx 的 rewrite 模块是ngx_http_rewrite_module
,它主要用于改写请求 URI,是 Nginx 默认安装的模块之一。通过使用 rewrite,可以实现 URL 重写和重定向,这在网站开发和维护中有着广泛的应用。
1. 隐藏真实目录结构
使用 rewrite 可以隐藏服务器上的真实文件路径和目录结构,增加安全性,防止攻击者通过直接访问文件路径获取敏感信息。例如,可以通过以下配置实现:
rewrite ^/api/(.*)$ /backend/$1 break;
这样,所有的/api/
请求都会被重写到/backend/
目录下,而外界无法直接通过 URL 猜测真实的文件路径。
2. 规范化 URL
强制规范化 URL 格式可以避免一些常见的安全问题,如路径遍历攻击或路径参数欺骗。例如,确保 URL 以特定的格式展示:
rewrite ^/(.*)/$ //$1.html last;
这个规则将所有以斜杠结尾的请求重写为对应的.html
文件。
3. 防止盗链
通过 rewrite 实施防盗链策略,防止其他网站直接链接到本站的资源,减轻服务器负载,提高资源的安全性。例如:
rewrite ^/images/(.*)$ /notfound.gif if-not-referer($http_referer, "http://www.yoursite.com");
这个规则会检查 Referer 头,如果不是来自指定的站点,则重写到一个占位符图片。
4. HTTP 到 HTTPS 的强制重定向
通过 rewrite 将 HTTP 请求强制重定向到 HTTPS,确保数据在传输过程中的安全性。例如:
server {
listen 80;
server_name example.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
这个配置会将所有的 HTTP 请求重定向到 HTTPS。
5. 条件性重写
可以根据请求中的条件来选择是否进行重写,例如,只有特定 IP 范围的请求才允许进行某种操作。例如:
map $remote_addr $allowed {
default 0;
192.168.1.1 1;
}
location /admin {
rewrite ^/admin(.*)$ /access_denied last;
if ($allowed = 0) {
return 403;
}
}
这个配置会阻止未授权的 IP 访问/admin
目录。
6. 统一资源标识符(URI)规范化
通过强制规范化 URI,可以防止攻击者尝试混淆或绕过安全策略。例如:
rewrite ^([^.]*[^/])$ /$1.html last;
这个规则会将没有扩展名的请求重写为.html
文件。
7. 避免敏感信息泄露
通过 rewrite 可以限制对某些敏感信息或文件的访问,确保只有授权用户能够获取特定内容。例如:
location ~* ^/sensitive/.*\.php$ {
deny all;
}
这个配置会阻止所有用户访问/sensitive/
目录下的 PHP 文件。
8.工作原理
Rewrite 模块的指令包括break
, if
, return
, rewrite
, set
等。Rewrite 指令会根据 PCRE 正则匹配重写 URI,然后发起内部跳转再匹配 location,或者直接做 30x 重定向返回客户端。如果新 URI 包含协议信息,如http://
或https://
,则会直接返回客户端重定向。
9.Rewrite Flag 参数
last
:停止处理任何 rewrite 相关的指令,立即用替换后的新 URI 开始下一轮的 location 匹配。break
:停止处理任何 rewrite 的相关指令,直接用新的 URI 进一步处理请求。redirect
:返回 302 临时重定向。permanent
:返回 301 永久重定向。
二.代码实战
location /test/server {
rewrite ^/test(.*)$ $1 break;
proxy_pass http://xxxx.xxx.xx.xx:8320$1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
client_max_body_size 600M;
client_body_buffer_size 600M;
uwsgi_send_timeout 1800;
uwsgi_connect_timeout 1800;
uwsgi_read_timeout 1800;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
proxy_send_timeout 1800;
}
在 Nginx 的配置文件中,$1
是一个变量,它代表正则表达式捕获的分组。在你提供的配置片段中:
这里的正则表达式 ^/test(.*)$
用于匹配 URL 中以 /test
开头的部分,并且将 /test
后面的所有内容捕获为一个分组,这个分组就是 $1
。
- rewrite ^/test(.*)$ $1 break;
这行代码的作用是将匹配到的 URL 重写为它自己,实际上这个 rewrite
规则并没有改变 URL,break
表示重写完成后不再进行后续的重写检查。
- proxy_pass http://xxxx:8320$1;
这行代码的作用是将请求代理到 http://xxxx:8320
这个后端服务器,并且将原始请求中的 /test
及其后面的部分(即 $1
)附加到代理服务器的 URL 后面。
举个例子,如果有一个请求的 URL 是 http://yourserver.com/test/some/path
,那么经过上述配置后,Nginx 会将请求转发到 http://xxxxxxx:8320/some/path
。这里的 /some/path
就是 $1
代表的内容。
- 点赞
- 收藏
- 关注作者
评论(0)