目录
一、重写功能rewrite
1. ngx_http_rewrite_module模块指令
1.1 if 指令
1.2 return 指令
1.3 set 指令
1.4 break 指令
2. rewrite 指令
3. 防盗链
3.1 实现盗链
3.2 实现防盗链
4. 实用网址
二、反向代理
1. 概述
2. 相关概念
3. 反向代理模块
4. 参数配置
5. 示例
5.1 反向代理单台web服务器,实现单台反向代理。
5.2 指定location实现反向代理动静分离
6. 缓存功能
7. 自定义添加响应报文头部信息
一、重写功能rewrite
1. ngx_http_rewrite_module模块指令
1.1 if 指令
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
示例:
① 修改子配置文件
[root@localhost conf.d]# vim pc.conf
server {
listen 80;
root /data/;
location / {
if ( $scheme = http ) { #如果请求协议是http
echo "if------->$scheme"; #则打印协议
}
}
}
[root@localhost conf.d]# nginx -t
[root@localhost conf.d]# nginx -s reload
② 访问页面
[root@localhost ~]# curl 192.168.190.102
if------->http
1.2 return 指令
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置。
语法格式:
www.pc.com/test/
404
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url; #返回给客户端的URL地址
示例:
① 修改子配置文件
[root@localhost conf.d]# vim pc.conf
server {
listen 80;
root /data/;
location / {
if (!-e $request_filename) { #如果访问的页面不存在
return 302 /index.html; #返回302,跳转至主页面
}
}
}
[root@localhost conf.d]# nginx -t
[root@localhost conf.d]# nginx -s reload
② 访问不存在页面,查看是否可以跳转
[root@localhost ~]# curl 192.168.190.102/x
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[root@localhost ~]# curl 192.168.190.102/x -L
welcome
#-vL选项可以查看详情信息
③ 当然也可以跳转至百度
return 302 http://www.baidu.com;
http状态码301和302区别?
301:永久重定向,读取过一次就会将此条配置缓存在我们的客户端,即使nginx服务器宕机,在缓存时间内还是可以跳转
302:临时重定向,不会有缓存在客户端,每次跳转需要nginx服务器解析,一旦服务器宕机就无法跳转
302状态码宕机服务器查看详情:
301状态码宕机服务器查看详情:
server {
listen 80;
root /data/;
location /test {
default_type text/plain;
return 301 /index.html;
}
}
1.3 set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。
语法格式:
Syntax: set $variable value;
Default: —
Context: server, location, if
示例:
① 修改配置文件
server {
listen 80;
location / {
set $name yun;
echo $name;
set $my_port $server_port; #将内置变量定义给自定义变量
echo $my_port;
}
}
② 访问页面
[root@localhost ~]# curl 192.168.190.102
yun
80
1.4 break 指令
用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和locationif块中使用。
注意:如果break指令在location块中后续指令还会继续执行只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行。
2. rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理。
rewrite可以配置在 server、location、if。语法格式:
rewrite可以配置在 server、location、if
语法格式 :
rewrite regex replacement(www.baidu.com) [flag];
正则匹配原始访问url 替代的url链接 标志 ()premanent301 redirect302 break last
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI。
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301。
正则表达式格式:
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字 [0-9]
\b #匹配单词的开始或结束
^ #匹配字付串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
(n) #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^kgc] #匹配除了kgc 这几个字母以外的任意字符
示例:
访问 bj 跳转到 beijing
① 修改配置文件
server {
listen 80;
server_name www.pc.com;
root /data/;
location /bj {
rewrite ^/bj/(.*) /beijing/$1 permanent;
}
}
② 新建对应文件夹及页面文件
[root@localhost ~]# mkdir /data/beijing
[root@localhost ~]# echo beijing nihao > /data/beijing/index.html
③ 访问页面bj
[root@localhost ~]# curl 192.168.190.102/bj/ -L
beijing nihao #可以跳转
整个网站重写:
① 配置文件
server {
listen 80;
server_name www.pc.com;
root /data/;
location / {
rewrite / http://www.baidu.com permanent; #如果访问根就跳转到百度
}
}
② 访问根查看是否跳转百度
实战案例:http转https
① 配置文件
server {
listen 80;
listen 443 ssl;
root /data/;
ssl_certificate /data/ssl/www.kgc.com.crt;
ssl_certificate_key /data/ssl/www.kgc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
location / {
if ( $scheme = http ) { #如果请求协议是http
rewrite /(.*) https://$host/$1 permanent; #重写成https
}
}
}
② 访问页面
last 与 break:
location /break { #访问break
rewrite .* /test break; #重写到test
}
location /last { #访问break
rewrite .* /test last; #重写到test
}
location /test {
rewrite 403; #last返回403,因为last会多次匹配
}
说明:
- redirect;302:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
- permanent;301:重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
- break:重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用,适用于一个URL一次重写
- last:重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用。适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301
其他示例:
案例1:更换目录访问方式,目录转化为对象存储形式
要求:
/20200106/static->/static?id=20200106
/20200123/image ->/image?id=20200123
方法:
rewrite ^/(\d+)/(.+)/ /$2?id=$1 break;
\d+:一个以上数字;.+:一个以上的字符
案例2:多目录转换访问方式
要求:
www.lucky.com/images/20200106/1.jpg => www.lucky.com/index.do?name=images&dir=20200106=&fi1e=1.jpg
规则配置:
if($host ~* (.*)\.lucky\.com) {
rewrite ^/(.*)/(\d+)/(.*)$ /index.do?name=$1&dir=$2&file=$3 last;}
3. 防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
- none:#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
- blocked:#请求报文有referer首部,但无有效值,比如为空。
- server_names:#referer首部中包含本主机名及即nginx 监听的server_name。
- arbitrary_string:#自定义指定字符串,但可使用*作通配符。示例: *.kgc.org www.kgc.*
- regular expression:#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.kgc\.com
3.1 实现盗链
① 被盗端添加文件a.jpg
[root@localhost data]# ls
a.jpg beijing favicon.ico index.html ssl
② 盗取端开启httpd服务,添加web前端配置
[root@localhost ~]# cd /var/www/html/
<html>
<body>
<h1>ni hao </h1>
<img src="http://192.168.190.102/a.jpg"/> #这里如果写域名,需要修改hosts配置添加域名解析
</body>
</html>
[root@localhost html]# systemctl restart httpd
③ 访问盗取端地址,可以直接获得被盗端图片
3.2 实现防盗链
① 配置文件
server{
listen 80;
server_name www.pc.com;
root /data;
location ~* \.(jpg|gif|swf)$ {
root /data/nginx/pc;
valid_referers none blocked *.pc.com pc.com;
if ( $invalid_referer ) {
rewrite ^/ http://www.pc.com/error.png;
}
}
}
② 再次访问盗取端地址
③ 无法盗取图片,状态码403
4. 实用网址
https://www.digitalocean.com/community/tools/nginx
#自动生成nginx配置文件
https://github.com/agile6v/awesome-nginx/
#第三方模块
https://www.runoob.com/lua/lua-tutorial.html
#lua帮助
https://666666.dev/#/
#it人工具箱
二、反向代理
1. 概述
Nginx 反向代理是一种网络通信方式,它允许 Nginx 服务器代表客户端向其他服务器发送请求,并将收到的响应返回给客户端。这种代理方式隐藏了真实的服务器信息,提供了负载均衡、安全性和性能优化等好处。
2. 相关概念
正向反向代理区别:
- 正向代理:代理客户端去访问服务器
- 反向代理:代理的是服务器
同构代理和异构代理:
- 同构代理:客户到至代理端和代理端至服务端使用请求协议一致
- 异构代理:客户到至代理端和代理端至服务端使用请求协议不一致
3. 反向代理模块
ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module:#将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module:#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处理
4. 参数配置
proxy_pass;
#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP
地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
5. 示例
5.1 反向代理单台web服务器,实现单台反向代理。
客户端:192.168.190.101,服务器:192.168.190.100;代理服务器:192.168.190.102
① 代理服务器配置文件
server{
listen 80;
server_name www.pc.com;
root /data;
location / {
proxy_pass http://192.168.190.100; #访问本机的根等于访问指定地址
}
}
② 客户端开启httpd服务
[root@localhost html]# cat index.html
<html>
<body>
<h1>ni hao </h1>
</body>
</html>
③ 客户端访问代理服务器
[root@localhost ~]# curl 192.168.190.102
<html>
<body>
<h1>ni hao </h1>
</body>
</html>
在真实服务器上做防火墙规则:
丢弃:
① 服务端添加防火墙规则
iptables -A INPUT -s 192.168.190.102 -j DROP
#客户端再次访问会出现504网关超时(有可能只是处理时间久,服务器不一定挂了),时间较长1分钟,没有定义代理超时时间
② 客户端访问代理服务器
[root@localhost ~]# curl 192.168.190.102 -I
HTTP/1.1 504 Gateway Time-out
Server: nginx/1.18.0
Date: Mon, 26 Feb 2024 10:50:47 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
#提示504超时
拒绝:
① 服务器修改防火墙规则
[root@localhost html]# iptables -R INPUT 1 -s 192.168.190.102 -j REJECT
#客户端再次访问,会出现502,一般出现502代表后端真实服务器挂了
② 客户端访问代理服务器
[root@localhost ~]# curl 192.168.190.102 -I
HTTP/1.1 502 Bad Gateway
Server: nginx/1.18.0
Date: Mon, 26 Feb 2024 10:55:15 GMT
Content-Type: text/html
Content-Length: 157
Connection: keep-alive
针对某个uri 进行访问:
要求:将用户对域www.pc.com的请求转发给后端服务器处理
① 代理端配置文件
server{
listen 80;
server_name www.pc.com;
root /data;
location ~* /api { #只要包含api的都替换成192.168.190.100
proxy_pass http://192.168.190.100;
}
}
http://192.168.91.101 不加/ 是将location上的url追加在后面
http://192.168.91.101/ 加上/ 是将1ocation上的url替换后proxy配置里的连接
5.2 指定location实现反向代理动静分离
环境:动态服务器7-0:192.168.190.100;静态服务器7-1:192.168.190.101;代理服务器:192.168.190.102;客户端:192.168.190.103
① 两台服务器分别开启httpd服务,新建对应web文件
192.168.190.100 7-0:
[root@localhost ~]# cd /var/www/html/
[root@localhost html]# mkdir api
[root@localhost html]# echo dongtai 7-0 > api/index.html
192.1681.190.101 7-1:
[root@localhost ~]# cd /var/www/html/
[root@localhost html]# echo jingtai 7-1 > index.html
[root@localhost html]# ls
a.jpg index.html
② 代理服务器配置文件
server {
listen 80;
server_name www.pc.com;
root /data;
location ~* /api {
proxy_pass http://192.168.190.100;
#访问代理的api的url就跳转到http://192.168.190.100/api/index.html
}
location ~* \.(jpg|jpeg|png|gif|bmp)$ {
proxy_pass http://192.168.190.101;
#访问以这些结尾的文件,代理地址/a.jpg,那么就去http://192.168.190.101/a.jpg
}
}
访问192.168.190.102/a.jpg转到访问192.168.190.101/a.jpg:
6. 缓存功能
缓存功能可以加速访问,如果没有缓存关闭后端服务器后,图片将无法访问,缓存功能默认关闭,需要开启。
相关选项:
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
操作示例:为代理服务器开启缓存功能
① 主配置文件的http模块中添加配置
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
proxy_cache_path /data/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
#开启缓存 缓存路径 生成文件夹比例是3级 从内存中借调20M专门存放缓存 有效期120秒 最大存储空间为1g
[root@localhost ~]# mkdir /data/nginx/
[root@localhost ~]# nginx -t
② 子配置文件添加配置
[root@localhost ~]# vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.pc.com;
root /data/;
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
#proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 5m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
location ~* /api {
proxy_pass http://192.168.190.100;
}
location ~* \.(jpg|jpeg|png|gif|bmp)$ {
proxy_pass http://192.168.190.101;
}
}
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
③ 访问代理端
④ 查看缓存内容
[root@localhost proyxcache]# tree /data/nginx/proyxcache/
/data/nginx/proyxcache/
└── a
└── 2
└── 4
└── 9dd678f60ef22cf1fc31474b6abac42a
3 directories, 1 file
⑤ 关闭服务端,再次访问
7. 自定义添加响应报文头部信息
① 添加子配置
server {
listen 80;
server_name www.pc.com;
root /data/;
proxy_cache proxycache;
proxy_cache_key $request_uri;
#proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 5m;
add_header ip $server_addr; #当前nginx主机ip
add_header status $upstream_cache_status; #是否缓存命中,hit命中,miss未命中
add_header name $server_name; #客户端访问的FQDN
location ~* /api {
proxy_pass http://192.168.190.100;
}
location ~* \.(jpg|jpeg|png|gif|bmp)$ {
proxy_pass http://192.168.190.101;
}
}
② 查看新增头部字段信息
[root@localhost html]# curl 192.168.190.102/a.jpg -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 27 Feb 2024 07:16:10 GMT
Content-Type: image/jpeg
Content-Length: 62447
Connection: keep-alive
Last-Modified: Mon, 26 Feb 2024 15:46:56 GMT
ETag: "f3ef-6124ad1bd7c00"
ip: 192.168.190.102
status: HIT
name: www.pc.com
Accept-Ranges: bytes