Nginx的rewrite模块疑问排查

简介:

标题索引


  • 追溯原因

  • 实验分析

  • 原理总结


追踪原因

    最近心态"一步一印,有印为证",在Nginx的rewrite模块在工作过程中,客户端发起包到服务器解包整体过程浏览器做了什么?服务器做了什么?到底是服务器端接收请求匹配跳转条件后先执行跳转并将执行结果反馈给客户端呢?还是服务器端接收到请求后先反馈给客户端跳转后的路径,然后客户端再次重新发起请求,服务器端再次接收请求并执行请求,最后将执行结果反馈给客户端?为此决定抓包分析一探究竟。

过程分析

    为验证此做四个实验,第一个实验利用rewrite指令进行永久性重定向,抓包分析过程及内容,第二个实验利用rewrite指令临时重定向redirect,抓包分析过程及内容,第三个实验利用rewrite指令后续跟last选项,抓包分析过程及内容,第四个实验利用rewrite指令做http跳转https,,然后分析过程及内容,最后总结rewrite工作原理及过程。

    实验环境:一台虚拟服务器、一台普通PC机,虚拟服务器做Nginx服务器,PC机做测试,具体拓扑如下:

e8faf043036a7449f174c20decccfa3b.png

图1-1 测试环境拓扑图    

 


   实验一:服务器rewrite参数配置为永久性重定向,具体配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ root@nginxagent conf.d ] #pwd
/etc/nginx/conf .d
[ root@nginxagent conf.d ] mkdir  /app/website01/jn
[ root@nginxagent conf.d ] mkdir  /app/website01/jncsy
[ root@nginxagent conf.d ] echo  jn > /app/website01/jn
[ root@nginxagent conf.d ] echo  jncshy > /app/website01/jncsy
[ root@nginxagent conf.d ] #vim virtual.conf
  #server test
  server {
      listen 80;
      index index.html;
      server_name 
       root  /app/website01/ ;
      location  /zz  {
          rewrite ^ /jn/ (.*)$  /jncsy/ $1 permanent;
      }
  }

     Client客户端通过浏览器访问www.a.com,IP地址即172.18.27.22,同时在客户端利用Wireshark抓包分析如图:

ee795fcea2281ca441edd86c03d58492.png

图1-2 永久性重定抓包分析图

    由上图可知,在客户端第一次发起请求http://www.a.com/jn/到达服务器后,服务器对回应301永久性重定向返回新的地址链接,第二次重新发起新的地址请求后,重新获取数据。 


    实验二:服务器rewrite参数配置为last时,具体如下

1
2
3
4
5
6
7
8
9
10
11
[ root@nginxagent conf.d ] #vim virtual.conf
  #server test
  server {
      listen 80;
      index index.html;
      server_name www.a.com;
       root  /app/website01/ ;
      location  /zz  {
          rewrite ^ /jn/ (.*)$  /jncsy/ $1 last;
      }
  }

    Client客户端通过浏览器访问www.a.com,IP地址即172.18.27.22,同时在客户端利用Wireshark抓包分析如图:

1-3 last重定向工作抓包分析图

    当服务器第一次发起请求时,通过http://www.a.com/jn/,请求到达服务器后,服务器内部根据跳转规则直接进行跳转,并将跳转后的最终结果数据反馈给客户端,客户端无需进行第二次请求。


    实验三:服务器rewrite参数配置为redirect时,具体如下

1
2
3
4
5
6
7
8
9
10
11
[ root@nginxagent conf.d ] #vim virtual.conf
  #server test
  server {
      listen 80;
      index index.html;
      server_name www.a.com;
       root  /app/website01/ ;
      location  /zz  {
          rewrite ^ /jn/ (.*)$  /jncsy/ $1 redirect;
      }
  }

    Client客户端通过浏览器访问www.a.com,IP地址即172.18.27.22,同时在客户端利用Wireshark抓包分析如图:

9c49561e4eb77f20c199edf02d118967.jpg

图1-4 临时重定向工作抓包分析图

    由上图可知,在客户端第一次发起请求http://www.a.com/jn/到达服务器后,服务器对回应302临时重定向返回新的地址链接,第二次重新发起新的地址请求后,重新获取数据。


    实验四:当服务器配置https,由http跳转至https时,且重定向为redirect,实验如下:

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
[ root@nginxagent ~ ] #mkdir /etc/nginx/ssl
#----------------------------------生成自签名秘钥和证书------------
[ root@nginxagent ~ ] #cd /etc/pki/tls/certs
[ root@nginxser01 certs ] #make nginx.crt
umask  77 ; \
/usr/bin/openssl  genrsa -aes128 2048 > nginx.key
Generating RSA private key, 2048 bit long modulus
.........+++
.........................................+++
e is 65537 (0x10001)
Enter pass phrase:  #创建私钥,并输入密码#
Verifying - Enter pass phrase:  #确认密码#
umask  77 ; \
/usr/bin/openssl  req -utf8 -new -key nginx.key -x509 -days 365 -out nginx.crt -set_serial 0
Enter pass phrase  for  nginx.key:  #利用私钥生成证书,输入私钥密码#
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter  '.' , the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SHANXI
Locality Name (eg, city) [Default City]:XI'AN  
Organization Name (eg, company) [Default Company Ltd]:JNCSY
Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's  hostname ) []:www.a.com
Email Address []:
#-------------------------验证生成的证书和秘钥------------------------------
[ root@nginxser01 certs ] #ll ngi*
-rw------- 1 root root 1289 Oct 28 06:47 nginx.crt
-rw------- 1 root root 1766 Oct 28 06:43 nginx.key
#-------------------------避免每次调用私钥进行输入密码验证进行解密-----------
[ root@nginxser01 certs ] #openssl rsa -in nginx.key -out nginx.key
Enter pass phrase  for  nginx.key:
writing RSA key
[ root@nginxser01 certs ] #cp ngi* /etc/nginx/ssl
[ root@nginxagent conf.d ] #vim virtual.conf
  #server test
  server {
      listen 80;
      index index.html;
      server_name www.a.com;
      root  /app/website01/ ;
      location / {
           rewrite ^/(.*)$  https: //172 .18.27.22/$1 redirect;
           }
  server {
      listen 443 ssl;
      server_name www.a.com;
      index index.html;
      root  /app/website01/ ;
      ssl on;
      ssl_certificate  /etc/nginx/ssl/nginx .crt;
      ssl_certificate_key  /etc/nginx/ssl/nginx .key;
      ssl_session_cache  builtin :1000 shared:SSL:20m;
      ssl_session_timeout 10m;
      }

    Client客户端通过浏览器访问www.a.com,IP地址即172.18.27.22,同时在客户端利用Wireshark抓包分析如图:

af470a63bf07291117261d63864a8ff5.jpg

图1-5 http跳转https工作抓包分析图

    由上图可知,在客户端第一次发起请求http://www.a.com/jn/到达服务器后,服务器对回应302临时重定向返回新的地址https://www.a.com/jn/,第二次重新发起新的地址请求后,重新获取数据。


总结对比

    由此实验总结得知:在临时重定向和永久重定向中,服务器端返回给客户端新的链接,客户端根据服务器端返回的新连接重新发起请求。而rewrite模块的last参数则较为特殊,服务器收到请求后在内部跳转并将跳转执行后的结果直接一次性返回客户端。



本文转自 薛伟博 51CTO博客,原文链接:http://blog.51cto.com/weiboxue/1976905,如需转载请自行联系原作者


相关文章
|
1月前
|
应用服务中间件 nginx
Nginx安装nginx-rtmp-module模块
【2月更文挑战第4天】 nginx中的模块虽然就是类似插件的概念,但是它无法像VsCode那样轻松的安装扩展。 nginx要安装其它模块必须同时拿到nginx源代码和模块源代码,然后手动编译,将模块打到nginx中,最终生成一个名为nginx的可执行文件。
72 6
|
3月前
|
应用服务中间件 nginx
百度搜索:蓝易云【利用nginx内置ngx_http_mirror_module模块实现流量复制及流量放大】
以上就是使用Nginx内置 `ngx_http_mirror_module`模块实现流量复制和流量放大的简要示例。通过合理配置和利用该模块,可以实现更复杂的流量控制和调试需求。
56 1
|
25天前
|
应用服务中间件 Linux PHP
Linux下安装php环境并且配置Nginx支持php-fpm模块
Linux下安装php环境并且配置Nginx支持php-fpm模块
22 0
|
2月前
|
消息中间件 关系型数据库 MySQL
使用Nginx的stream模块实现MySQL反向代理与RabbitMQ负载均衡
使用Nginx的stream模块实现MySQL反向代理与RabbitMQ负载均衡
61 0
|
3月前
|
存储 应用服务中间件 nginx
Nginx模块开发:handler模块实现
Nginx模块开发:handler模块实现
28 0
|
3月前
|
存储 应用服务中间件 nginx
Nginx模块开发:模块结构的源码阅读以及过滤器(Filter)模块的实现
Nginx模块开发:模块结构的源码阅读以及过滤器(Filter)模块的实现
65 0
|
3月前
|
存储 应用服务中间件 nginx
Nginx:过滤模块的实现
Nginx:过滤模块的实现
|
3月前
|
存储 负载均衡 网络协议
Nginx: handler 模块的实现
Nginx: handler 模块的实现
|
3月前
|
前端开发 应用服务中间件 nginx
nginx过滤器模块
nginx过滤器模块
|
3月前
|
应用服务中间件 nginx
nginx日志模块 ngx_http_log_module
nginx日志模块 ngx_http_log_module