运维八一 运维八一
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)

运维八一

运维,运维!
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)
  • 操作系统

  • 域名解析

  • 公有云

  • CI&CD

  • 数据库

  • 负载均衡&反向代理

  • 存储系统

  • 容器&容器编排

  • 批量管理

  • 邮件系统

  • 监控系统

  • Web服务

    • HTTP介绍
    • nginx进阶
    • nginx优化
    • nginx容器化部署
    • Nginx反向代理问题
    • nginx日志切割脚本
    • nginx log各种过滤分析
    • nginx安全问题处理
    • Nginx location Rewrite参数
      • 1. Nginxn location 规则匹配
      • 2 、正则表达式
      • 3 、正则 表达式 补充:
      • 4 、Nginx locatnion 应用规则
      • flag 标志位
      • if 指令与全局变量
      • Nginx 变量
    • 查看apache、nginx、mysql、php编译参数
    • Tomcat优化
    • centos下tomcat启动很慢
    • tomcat升级
    • PHP优化
    • apache+tomcat负载均衡
    • apache部署
    • apache限制地址和用户访问
    • httpd虚拟主机
    • apache配置文件参数详解
    • apache优化
    • nginx&apache&lighttpd介绍
    • Lighttpd优化
    • web程序性能动态追踪简明手册
  • 虚拟化

  • 防火墙

  • 压测

  • 文件同步

  • 私有云

  • 日志系统

  • 代码仓库&版本管理

  • 安全审计

  • 远程拨号

  • 大数据

  • 统一认证

  • 消息队列

  • Apollo

  • 运维杂记
  • Web服务
lyndon
2022-06-10
目录

Nginx location Rewrite参数

# 一 、Nginx 正则及 location 匹配

# 1. Nginxn location 规则匹配

^~  标识符匹配后面跟一个字符串。匹配字符串后将停止对后续的正则表达式进行匹配,如 location ^~ /images/,在匹配了/images/这个字符串后就停止对后续的正则匹配

=  精准匹配,如 location = /,只会匹配 url 为/的请求

~  区分大小写的匹配

~* 不区分大小写的匹配

!~  对区分大小写的匹配取非

!~* 对不区分大小写的匹配取非

/ 通用匹配, 如果没有其它匹配,任何请求都会被匹配到
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2 、正则表达式

*  重复前面的字符 0 次或多次
?  重复前面的字符 0 次或 1 次
+  重复前面的字符 1 次或多次
.  匹配除换行符以外的任意 1 个字符
(a|b)  匹配 a 或 b
^  以…开头
$  以…结尾
{n} 重复前面的字符 n 次
{n,} 重复前面的字符 n 次或更多次
{n,m}  重复前面的字符 n 到 m 次
*?  重复前面的字符 0 次或多次,但尽可能少重复
+?  重复前面的字符 1 次或更多次,但尽可能少重复
??  重复前面的字符 0 次或 1 次,但尽可能少重复
{n,m}?  重复前面的字符 n 到 m 次,但尽可能少重复
{n,}? 重复前面的字符 n 次以上,但尽可能少重复
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 3 、正则 表达式 补充:

\W 匹配任意不是字母,数字,下划线,汉字的字符
\S  匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B  匹配不是单词开头或结束的位置
[a] 匹配单个字符 a
[a-z] 匹配 a-z 小写字母的任意一个
[^a] 匹配除了 a 以外的任意字符
[^abc]  匹配除了 abc 这几个字母以外的任意字符
1
2
3
4
5
6
7
8

# 4 、Nginx locatnion 应用规则

location [=|~|~*|^~|!~|!~*] /url/{...}
1

默认值:no

使用字段:server

location 参数根据 URL 的不同需求来进行配置,可以使用字符串与正则表达式匹配

location = / {

# 精确匹配 / ,主机名后面不能带任何字符串

[ configuration A ]
}
location / {

# 因为所有的地址都以 /  开头,所以这条规则将匹配到所有请求

# 但是正则和最长字符串会优先匹配

[ configuration B ]
}
location /documents/ {

#  匹配任何以 /documents/  开头的地址,匹配符合以后,还要继续往下搜索

#  只有后面的正则表达式没有匹配到时,这一条才会采用这一条

[ configuration C ]
}
location ~ /documents/Abc {

#  匹配任何以 /documents/  开头的地址,匹配符合以后,还要继续往下搜索

#  只有后面的正则表达式没有匹配到时,这一条才会采用这一条

[ configuration CC ]
}
location ^~ /images/ {

#  匹配任何以 /images/  开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。

[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {

#  匹配所有以 gif,jpg 或 或 jpeg  结尾的请求

#  然而,所有请求 /images/  下的图片会被 config D  处理,因为 ^~  到达不了这一条正则

[ configuration E ]
}
location /images/ {

#  字符匹配到 /images/ ,继续往下, 会发现 ^~  存在

[ configuration F ]
}
location /images/abc {

#  最长字符匹配到 /images/abc ,继续往下,会发现 ^~  存在

# F 与 G 的放置顺序是没有关系的

[ configuration G ]
}
location ~ /images/abc/ {

#  只有去掉 config D 才有效:先最长匹配 config G  开头的地址,继续往下搜索,匹配到这一条正则,采用 [ configuration H ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

匹配顺序优先级:

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
1

按照上面的 location 匹配,分析以下案例:

/ ->config A
精确完全匹配,即使/index.html 也匹配不了

/downloads/download.html ->config B
匹配 B 以后,往下没有任何匹配,采用 B

/images/1.gif -> configuration D
匹配到 B,往下匹配到 D,停止往下

/images/abc/def ->config D
最长匹配到 G,往下匹配 D,停止往下,你可以看到 任何以/images/开头的都会匹配到 D 并停止,FG 写在这里是没有任何意义的,H 是永远轮不到的,这里只是为了说明匹配顺序

/documents/document.html ->config C
匹配到 C,往下没有任何匹配,采用 C

/documents/1.jpg -> configuration E
匹配到 C,往下正则匹配到 E

/documents/Abc.jpg ->config CC
最长匹配到 C,往下正则顺序匹配到 CC,不会往下到 E
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

实际使用建议 所以实际使用中,个人觉得至少有三个匹配规则定义,如下:

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理。这里是直接转发给后端应用服务器了,也可以是一个静态首页。

第一个必选规则

location = / {
proxy_pass http://tomcat:8080/index
}
1
2
3

第二个必选规则

处理静态文件请求,这是 nginx 作为 http 服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {
root /usr/local/nginx/html/static/;
}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
1
2
3
4
5
6
7

第三个规则

通用规则,用来转发动态请求到后端应用服务器,非静态文件请求就默认 是动态请求,自己根据实际把握。毕竟目前的一些框架的流行,带.php,.jsp 后缀的情况很少了。

location / {
proxy_pass http://tomcat:8080/
}
1
2
3

# 二、Nginx Rewrite 规则

rewrite 功能就是,使用 nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 url 重写以及重定向。rewrite 只能放在 server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用。

Nginx 的 Rewrite 规则采用 PCRE(Perl compatible Regular Expressions)Perl 兼容正则表达式的语法进行规则匹配,如果需要Ningx的Rewrite功能,在编译安装Nginx之前,必须安装 PCRE 库。

例如:http://www.crushlinux.com/a/we/index.php?id=1&u=admin 只对 URL 中的/a/we/index.php 等字符串起作用。

URL 是 Uniform Resource Location 的缩写,译为“统一资源定位符”。如:http://www.crushlinux.com:80/123/welcome.htm

语法 :

rewrite 正则表达式 更换目标 [标志位];
1

rewrite 和 location 功能有点像,都能实现跳转。主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而 location 是对路径做控制访问或反向代理,可以使用 proxy_pass 到其他机器。很多情况下 rewrite 也会写在 location 里,它们的执行顺序是:

  • 执行 server 块的 rewrite 指令

  • 执行 location 匹配

  • 执行选定的 location 中的 rewrite 指令

    注意:如果其中某步 URI 被重写,则重新循环执行 1-3,直到找到真实存在的文件;循环超过 10 次,则返回 500 Internal Server Error 错误。

# flag 标志位

  •  last : 相当于 Apache 的[L]标记,表示完成 rewrite
  •  break : 本条规则匹配完成后,终止匹配,不再匹配后面的规则
  •  redirect : 返回 302 临时重定向,浏览器地址栏会显示跳转后的 URL 地址
  •  permanent : 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址

last 一般写在 server 和 if 中,而 break 一般使用在 location 中;

last 不终止重写后的 url 匹配,即新的 url 会再从 server 走一遍匹配流程,而 break 终止重写后的匹配;

break 和 last 都能组织继续执行后面的 rewrite 指令;

last 和 break 用来实现 URI 重写,浏览器地址栏 URL 地址不变;

redirect 和 permanent 用来实现 URL 跳转,浏览器地址栏会显示跳转后的 URL 地址。

# if 指令与全局变量

if 判断指令 语法:

if(condition){...}
1

对给定的条件 condition 进行判断。如果为真,大括号内的 rewrite指令将被执行。

当表达式只是一个变量时,如果其值为空或任何以 0 开头的字符串时都会当作条件为 false。

  • =或!= 直接比较变量和内容

  • -f 和!-f 用来判断是否存在文件

  • -d 和!-d 用来判断是否存在目录

  • -e 和!-e 用来判断是否存在文件或目录

  • -x 和!-x 用来判断文件是否可执行

例如:

if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} // 如果 UA  包含"MSIE" ,rewrite  请求到/msid/ 目录下

if ($request_method = POST) {
return 405;
} // 如果提交方法为 POST ,则返回状态 405 (Method not allowed )。return  不能返回 301,302*
1
2
3
4
5
6
7

注意:因为返回 301 和 302 不能只返回状态码,还必须有重定向的 URL,所以 return 指令无法返回 301,302。

if ($slow) {
limit_rate 10k;
} // 限速,$slow  可以通过 set  指令设置

if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
} // 如果请求的文件名不存在,则反向代理到 localhost  。这里的 break  也是停止 rewrite  检查

if ($args ~ post=140){
rewrite ^ http://example.com/ permanent;
} // 如果 query string  中包含"post=140" ,永久重定向到example.com

location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;

if ($invalid_referer) {
return 404;
} // 防盗链
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Nginx 变量

下面是可以用作 if 判断的变量:

  • $args: 记录请求行中的参数,同$query_string
  • $content_length: 记录请求头中的 Content-length 字段。
  • $content_type: 记录请求头中的 Content-Type 字段。
  • $document_root: 记录当前请求在 root 指令中指定的值。
  • $host : 记录请求主机头字段,否则为服务器名称。
  • $http_user_agent: 记录用于记录客户端浏览器的相关信息
  • $http_cookie: 记录客户端 cookie 信息
  • $limit_rate: 记录可以限制连接速率。
  • $request_method: 记录客户端请求的动作,通常为 GET 或 POST。
  • $request_filename: 记录当前请求的文件路径,由 root 或 alias 指令与 URI 请求生成。
  • $scheme : 记录 HTTP 方法(如 http,https)。
  • $server_protocol: 记录请求使用的协议,通常是 HTTP/1.0 或 HTTP/1.1。
  • $server_addr: 记录服务器地址,在完成一次系统调用后可以确定这个值。
  • $server_name: 记录服务器名称。
  • $server_port: 记录请求到达服务器的端口号。
  • $request_uri: 记录包含请求参数的原始 URI,不包含主机名,如:”
  • /foo/bar.php?arg=baz”。
  • $uri: 记录不带请求参数的当前 URI,$uri 不包含主机名,如”/foo/bar.html”。
  • $document_uri: 与$uri 相同。
  • $http_x_forwarded_for 记录远程客户端的 ip 地址
  • $remote_addr: 记录远程客户端的 IP 地址。
  • $remote_port: 记录远程客户端的端口。
  • $remote_user 记录远程客户端用户名称
  • $time_local 记录访问时间及时区
  • $request 记录请求的 URL 与 HTTP 协议
  • $status 记录请求的状态,例如成功时为 200,页面找不到时为 404
  • $body_byte_sent 记录发送给客户端的文件主体内容大小
  • $http_referer 记录是从哪个页面链接访问过来的

URL 分析 :

http://localhost:88/test1/test2/test.php

$host :localhost
$server_port :88
$request_uri :http://localhost:88/test1/test2/test.php
$documenturi :/test1/test2/test.php
$document_root :/var/www/html
$request_filename :/var/www/html/test1/test2/test.php
1
2
3
4
5
6
7
8

Nginx 日志案例:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
//IP  地址- 用户名 [ 本地时间] “ 请求”  状态码主体内容大小“ 访问来源链接” ”浏览器信息”“ 客户端 IP  地址”

192.168.200.2 - -[21/Nov/2016:10:14:57 +0800]"GET / HTTP/1.1"3040"-""Mozilla/4.0
(compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET
CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E)"
1
2
3
4
5
6
7
8

示例:如果访问的 URL 以".sh" ".bash"结尾,则返回状态码 403

location ~ .*\.(sh|bash)?$
{
return 403;
}
1
2
3
4

将原来要访问/data 目录重写为/bbs

rewrite ^/data/?$ /bbs/ permanent;
1

防止盗链

localtion ~*\.(gif|jpg|png|swf|flv)${
valid_referers none blocked www.test.com *.test.com;
if($incalid_referer){
rewrite ^/(.*)http://www.test.com/block.html;
}
}
1
2
3
4
5
6

实现域名跳转,所有对 www.360buy.com 的访问,rewrite 到 www.jd.com

server {
listen 80;
server_name www.jd.com;
charset utf-8;
root html;
index index.html index.htm;
if ($host = "www.360buy.com") {
rewrite ^/(.*)$ http://www.jd.com/$1 permanent;
}
}
1
2
3
4
5
6
7
8
9
10
上次更新: 2022/06/12, 15:48:09
nginx安全问题处理
查看apache、nginx、mysql、php编译参数

← nginx安全问题处理 查看apache、nginx、mysql、php编译参数→

最近更新
01
ctr和crictl显示镜像不一致
03-13
02
alpine镜像集成常用数据库客户端
03-13
03
create-cluster
02-26
更多文章>
Theme by Vdoing | Copyright © 2015-2024 op81.com
苏ICP备18041258号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式