nginx-md-diange/nginx-md/第五章:Nginx地址重写.md

421 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<h1><center>Nginx地址重写</center></h1>
作者:行癫(盗版必究)
------
## 一:地址重写
#### 1.rewrite简介
Rewrite对称URL Rewrite即URL重写就是把传入Web的请求重定向到其他URL的过程
URL Rewrite最常见的应用是URL伪静态化是将动态页面显示为静态页面方式的一种技术
从安全角度上讲如果在URL中暴露太多的参数无疑会造成一定量的信息泄漏所以静态化的URL地址具有更高的安全性
实现网站地址跳转例如用户访问360buy.com将其跳转到jd.com当用户访问xingdian.com的80端口时将其跳转到443端口
#### 2.rewrite指令
Nginx Rewrite 相关指令有 if、rewrite、set、return
## 二if语句
#### 1.应用环境
serverlocation
#### 2.使用语法
```shell
if (condition) {}
```
#### 3.判断符号
```shell
~ 正则匹配 (区分大小写)
~* 正则匹配 (不区分大小写)
!~ 正则不匹配 (区分大小写)
!~* 正则不匹配 (不区分大小写)
-f 和!-f 用来判断是否存在文件
-d 和!-d 用来判断是否存在目录
-e 和!-e 用来判断是否存在文件或目录
-x 和!-x 用来判断文件是否可执行
```
#### 4.全局变量
在匹配过程中可以引用一些Nginx的全局变量
```shell
$args 请求中的参数;
$document_root 针对当前请求的根路径设置值;
$host 请求信息中的"Host"如果请求中没有Host行则等于设置的服务器名; http://www.qf.com
$limit_rate 对连接速率的限制;
$request_method 请求的方法,比如"GET""POST";
$remote_addr 客户端地址;
$remote_port 客户端端口号;
$remote_user 客户端用户名,认证用;
$request_filename 当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images /a.jpg
$request_uri 当前请求的文件路径名(不带网站的主目录/images/a.jpg
$query_string$args相同;
$scheme 用的协议比如http或者是https
$server_protocol 请求的协议版本,"HTTP/1.0""HTTP/1.1";
$server_addr 服务器地址如果没有用listen指明服务器地址使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 请求到达的服务器名;
$document_uri$uri一样URI地址;
$server_port 请求到达的服务器端口号;
```
#### 5.使用案例
匹配访问的url地址是否是个目录
```shell
if (-d $request_filename) { 当前请求的文件路径名
;
}
```
匹配访问的地址是否以www开头
```shell
if ( $host ~* ^www) {
;
}
```
## 三rewrite语句
#### 1.使用简介
rewrite 指令根据表达式来重定向URI或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记
#### 2.标记
```shell
last 相当于Apache里的[L]标记表示完成rewrite。默认为last
break 本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect 返回302临时重定向浏览器地址会显示跳转后的URL地址
permanent 返回301永久重定向浏览器地址会显示跳转后URL地址
```
#### 3.使用案例
http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html
```shell
location /a {
root /html;
index 1.html index.htm;
rewrite .* /b/2.html permanent;
}
location /b {
root /html;
index 2.html index.htm;
}
```
http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html
```shell
location /2019/a {
root /var/www/html;
index 1.html index.hml;
rewrite ^/2019/(.*)$ /2018/$1 permanent;
}
location /2018/a {
root /var/www/html;
index 1.html index.htl;
}
```
准备工作
![image-20230506222159398](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20230506222159398.png)
http://www.qf.com/a/1.html ==> http://jd.com
```shell
location /a {
root /html;
if ($host ~* qf.com ) {
rewrite .* http://jd.com permanent;
}
}
```
http://www.qf.com/a/1.html ==> http://jd.com/a/1.html
```shell
location /a {
root /html;
if ( $host ~* qf.com ){
rewrite .* http://jd.com$request_uri permanent;
}
}
```
在访问目录后添加/ (如果目录后已有/,则不加/)
```shell
# http://www.tianyun.com/a/b/c
# $1: /a/b
# $2: c
# http://$host$1$2/
location /a/b/c {
root /usr/share/nginx/html;
index index.html index.hml;
if (-d $request_filename) {
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
}
}
```
http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyun
```shell
location /login {
root /usr/share/nginx/html;
rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;
}
location /reg {
root /usr/share/nginx/html;
index login.html;
}
```
http://www.tianyun.com/qf/11-22-33/1.html ==> http://www.tianyun.com/qf/11/22/33/1.html
```shell
location /qf {
rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
}
location /qf/11/22/33 {
root /html;
index 1.html;
}
```
## 四set指令
#### 1.简介
set 指令是用于定义一个变量,并且赋值
#### 2.应用环境
server,location,if
#### 3.应用案例
http://alice.testpm.com ==> http://www.testpm.com/alice
http://jack.testpm.com ==> http://www.testpm.com/jack
准备工作:
```shell
[root@nginx-server conf.d]# cd /usr/share/nginx/html/
[root@nginx-server html]# mkdir jack alice
[root@nginx-server html]# echo "jack.." >> jack/index.html
[root@nginx-server html]# echo "alice.." >> alice/index.html
本地解析域名host文件
10.0.105.202 www.testpm.com
10.0.105.202 alice.testpm.com
10.0.105.202 jack.testpm.com
```
配置文件:
```shell
server {
listen 80;
server_name www.testpm.com;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if ( $host ~* www.testpm.com) {
break;
}
if ( $host ~* "^(.*)\.testpm\.com$" ) {
set $user $1;
rewrite .* http://www.testpm.com/$user permanent;
}
}
location /jack {
root /usr/share/nginx/html;
index index.html index.hml;
}
location /alice {
root /usr/share/nginx/html;
index index.html index.hml;
}
}
```
## 五return指令
#### 1.简介
return指令用于返回状态码给客户端
#### 2.应用环境
server,location,if
#### 3.应用案例
如果访问的.sh结尾的文件则返回403操作拒绝错误
```shell
server {
listen 80;
server_name www.testpm.cn;
#access_log /var/log/nginx/http_access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* \.sh$ {
return 403;
}
}
```
80 ======> 443 80转443端口
```shell
server {
listen 80;
server_name www.testpm.cn;
access_log /var/log/nginx/http_access.log main;
return 301 https://www.testpm.cn$request_uri;
}
server {
listen 443 ssl;
server_name www.testpm.cn;
access_log /var/log/nginx/https_access.log main;
#ssl on;
ssl_certificate /etc/nginx/cert/2447549_www.testpm.cn.pem;
ssl_certificate_key /etc/nginx/cert/2447549_www.testpm.cn.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
```
## 六break和last
#### 1.使用案例
```shell
[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/last.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /break/ {
root /usr/share/nginx/html;
rewrite .* /test/break.html break;
}
location /last/ {
root /usr/share/nginx/html;
rewrite .* /test/last.html last;
}
location /test/ {
root /usr/share/nginx/html;
rewrite .* /test/test.html break;
}
}
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# mkdir test
[root@localhost html]# echo "last" > test/last.html
[root@localhost html]# echo "break" > test/break.html
[root@localhost html]# echo "test" > test/test.html
http://10.0.105.196/break/break.html
http://10.0.105.196/last/last.html
```
#### 2.案例总结
last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求
break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配
使用 alias 指令时,必须使用 last
使用 proxy_pass 指令时,则必须使用break
## 七https案例
使用rewrite的方式进行http转https
```shell
server {
listen 80;
server_name *.vip9999.top vip9999.top;
if ($host ~* "^www.vip9999.top$|^vip9999.top$" ) {
return 301 https://www.vip9999.top$request_uri;
}
if ($host ~* "^(.*).vip9999.top$" ) {
set $user $1;
return 301 https://www.vip9999.top/$user;
}
}
# Settings for a TLS enabled server.
server {
listen 443 ssl;
server_name www.vip9999.top;
location / {
root /usr/share/nginx/html;
index index.php index.html;
}
#pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
ssl on;
ssl_certificate cert/214025315060640.pem;
ssl_certificate_key cert/214025315060640.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
```