`
风过无声
  • 浏览: 92461 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Nginx 配置指令的执行顺序(八)11个阶段(转载)

 
阅读更多

转载自 http://blog.sina.com.cn/openresty

前面我们详细讨论了 rewrite、access 和 content 这三个最为常见的 Nginx 请求处理阶段,在此过程中,也顺便介绍了运行在这三个阶段的众多 Nginx 模块及其配置指令。同时可以看到,请求处理阶段的划分直接影响到了配置指令的执行顺序,熟悉这些阶段对于正确配置不同的 Nginx 模块并实现它们彼此之间的协同工作是非常必要的。所以接下来我们接着讨论余下的那些阶段。

 

    前面在 (一) 中提到,Nginx 处理请求的过程一共划分为 11 个阶段,按照执行顺序依次是 post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log.

 

    最先执行的 post-read 阶段在 Nginx 读取并解析完请求头(request headers)之后就立即开始运行。这个阶段像前面介绍过的 rewrite 阶段那样支持 Nginx 模块注册处理程序。比如标准模块 ngx_realip 就在 post-read 阶段注册了处理程序,它的功能是迫使 Nginx 认为当前请求的来源地址是指定的某一个请求头的值。下面这个例子就使用了 ngx_realip 模块提供的 set_real_ip_from 和 real_ip_header 这两条配置指令:

    server {

        listen 8080;

 

        set_real_ip_from 127.0.0.1;

        real_ip_header   X-My-IP;

 

        location /test {

            set $addr $remote_addr;

            echo "from: $addr";

        }

    }

这里的配置是让 Nginx 把那些来自 127.0.0.1 的所有请求的来源地址,都改写为请求头 X-My-IP 所指定的值。同时该例使用了标准内建变量 $remote_addr 来输出当前请求的来源地址,以确认是否被成功改写。

 

    首先在本地请求一下这个 /test 接口:

    $ curl -H 'X-My-IP: 1.2.3.4' localhost:8080/test

    from: 1.2.3.4

这里使用了 curl 工具的 -H 选项指定了额外的 HTTP 请求头 X-My-IP: 1.2.3.4. 从输出可以看到,$remote_addr 变量的值确实在 rewrite 阶段就已经成为了 X-My-IP 请求头中指定的值,即 1.2.3.4. 那么 Nginx 究竟是在什么时候改写了当前请求的来源地址呢?答案是:在 post-read 阶段。由于 rewrite 阶段的运行远在 post-read 阶段之后,所以当在 location 配置块中通过 set 配置指令读取 $remote_addr 内建变量时,读出的来源地址已经是经过 post-read 阶段篡改过的。

 

    如果在请求上例中的 /test 接口时没有指定 X-My-IP 请求头,或者提供的 X-My-IP 请求头的值不是合法的 IP 地址,那么 Nginx 就不会对来源地址进行改写,例如:

    $ curl localhost:8080/test

    from: 127.0.0.1

 

    $ curl -H 'X-My-IP: abc' localhost:8080/test

    from: 127.0.0.1

如果从另一台机器访问这个 /test 接口,那么即使指定了合法的 X-My-IP 请求头,也不会触发 Nginx 对来源地址进行改写。这是因为上例已经使用 set_real_ip_from 指令规定了来源地址的改写操作只对那些来自 127.0.0.1 的请求生效。这种过滤机制可以避免来自其他不受信任的地址的恶意欺骗。当然,也可以通过 set_real_ip_from 指令指定一个 IP 网段(利用 (三) 中介绍过的“CIDR 记法”)。此外,同时配置多个 set_real_ip_from 语句也是允许的,这样可以指定多个受信任的来源地址或地址段。下面是一个例子:

    set_real_ip_from 10.32.10.5;

    set_real_ip_from 127.0.0.0/24;

有的读者可能会问,ngx_realip 模块究竟有什么实际用途呢?为什么我们需要去改写请求的来源地址呢?答案是:当 Nginx 处理的请求经过了某个 HTTP 代理服务器的转发时,这个模块就变得特别有用。当原始的用户请求经过转发之后,Nginx 接收到的请求的来源地址无一例外地变成了该代理服务器的 IP 地址,于是 Nginx 以及 Nginx 背后的应用就无法知道原始请求的真实来源。所以,一般我们会在 Nginx 之前的代理服务器中把请求的原始来源地址编码进某个特殊的 HTTP 请求头中(例如上例中的 X-My-IP 请求头),然后再在 Nginx 一侧把这个请求头中编码的地址恢复出来。这样 Nginx 中的后续处理阶段(包括 Nginx 背后的各种后端应用)就会认为这些请求直接来自那些原始的地址,代理服务器就仿佛不存在一样。正是因为这个需求,所以 ngx_realip 模块才需要在第一个处理阶段,即 post-read 阶段,注册处理程序,以便尽可能早地改写请求的来源。

 

    post-read 阶段之后便是 server-rewrite 阶段。我们曾在 (二) 中简单提到,当 ngx_rewrite 模块的配置指令直接书写在 server 配置块中时,基本上都是运行在 server-rewrite 阶段。下面就来看这样的一个例子:

    server {

        listen 8080;

 

        location /test {

            set $b "$a, world";

            echo $b;

        }

 

        set $a hello;

    }

这里,配置语句 set $a hello 直接写在了 server 配置块中,因此它就运行在 server-rewrite 阶段。而 server-rewrite 阶段要早于 rewrite 阶段运行,因此写在 location 配置块中的语句 set $b "$a, world" 便晚于外面的 set $a hello 语句运行。该例的测试结果证明了这一点:

    $ curl localhost:8080/test

    hello, world

由于 server-rewrite 阶段位于 post-read 阶段之后,所以 server 配置块中的 set 指令也就总是运行在 ngx_realip 模块改写请求的来源地址之后。来看下面这个例子:

    server {

        listen 8080;

 

        set $addr $remote_addr;

 

        set_real_ip_from 127.0.0.1;

        real_ip_header   X-Real-IP;

 

        location /test {

            echo "from: $addr";

        }

    }

请求 /test 接口的结果如下:

    $ curl -H 'X-Real-IP: 1.2.3.4' localhost:8080/test

    from: 1.2.3.4

 

在这个例子中,虽然 set 指令写在了 ngx_realip 的配置指令之前,但仍然晚于 ngx_realip 模块执行。所以 $addr 变量在 server-rewrite 阶段被 set 指令赋值时,从 $remote_addr 变量读出的来源地址已经是经过改写过的了。

分享到:
评论

相关推荐

    Nginx关于Rewrite执行顺序详解.docx

    2. **执行Rewrite规则**:在找到的location块内,按照配置文件中的顺序逐个执行`rewrite`指令。每次重写都会重新检查location匹配,因为新的URL可能与之前的不匹配。 3. **last标志的处理**:如果`rewrite`指令后面...

    nginx配置多个静态资源.docx

    本文将详细介绍nginx配置多个静态资源的知识点,从基本概念到配置实践,涵盖了nginx配置文件的各个组件和指令。 nginx配置文件结构 nginx配置文件主要由以下几个部分组成: * main块:定义nginx服务器的基本设置...

    Nginx完整配置说明

    Nginx完整配置说明 Nginx是当前最流行的Web服务器软件之一,...这个配置文件涵盖了Nginx的基本配置、反向代理、FastCGI等方面的知识点,是一个入门级的配置文件。但是,高级指令和配置项需要通过其他渠道学习和了解。

    Nginx配置文件(nginx.conf)配置详解[定义].pdf

    Nginx配置文件(nginx.conf)配置详解 Nginx配置文件(nginx.conf)是Nginx服务器的核心配置文件,用于定义Nginx服务器的行为和配置。下面是Nginx配置文件的详细配置解释: 用户和组 Nginx配置文件中指定了用户和组,...

    Nginx 配置文件 nginx.conf 详解

    Nginx 配置文件中,用户和组的设置是通过 `user` 指令来实现的,例如 `user nobody;`,这将设置 Nginx 进程的用户为 nobody。这个设置项非常重要,因为它将影响 Nginx 服务器的安全性和稳定性。 工作进程 工作进程...

    Nginx配置多个访问路径

    Nginx配置多个service 多个访问路径 找到conf/nginx.conf修改配置文件 #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid ...

    windows下nginx配置https以及同一个端口监听多个网站即监听多个虚拟主机

    在Windows环境下,配置Nginx以支持HTTPS及在同一端口监听多个网站,即配置多个虚拟主机,是一项常见的网络服务设置任务。Nginx是一个高性能的HTTP和反向代理服务器,以其稳定性、高并发处理能力而受到广泛使用。下面...

    nginx配置步骤详细

    * 虚拟主机配置是 Nginx 的一项重要功能,允许在同一个 IP 地址上运行多个网站。 * 需要根据实际情况进行调整和优化,以提高网站的性能和稳定性。 Nginx 配置需要根据实际情况进行调整和优化,以提高网站的性能和...

    nginx配置 +负载均衡+https协议

    - 对于负载均衡,可以通过在Nginx配置文件中定义多个后端服务器,并使用`proxy_pass`指令来实现。 ```nginx upstream backend { server backend1.example.com; server backend2.example.com; } server { ...

    Windows平台,Nginx配置文件修改自动加载重启

    这是一个监听配置文件变化并执行相应操作的小程序,这里包含了三个文件:`nginx-conf-watcher.bat`、`nginx-conf-watcher.exe`和`nginx-conf-watcher.js`。`nginx-conf-watcher.bat`是一个批处理文件,用于启动监控...

    nginx配置多域名访问以及完整配置

    要统计Nginx的访问数量,可以使用`access_log`指令记录日志,然后通过外部工具如`awstats`或`logrotate`进行分析。例如: ```nginx access_log /var/log/nginx/access.log combined; ``` `combined`是日志格式,...

    centos8 nginx1.20.1 与nginx配置文件

    在这个主题中,我们主要关注如何在CentOS 8操作系统上安装Nginx 1.20.1版本以及配置Nginx以支持HTTPS服务。以下是详细的步骤和相关知识点: 首先,我们需要确保CentOS 8系统已经更新到最新状态,通过运行以下命令:...

    微信小程序https服务nginx配置示例.pdf

    6. 反向代理配置:在nginx配置中,proxy_pass指令用于指定后端的服务器地址,这里指向了本地的8080端口。同时,还通过proxy_set_header指令设置了传递给后端服务器的HTTP头信息,如X-Forwarded-For(客户端IP地址)...

    nginx配置.zip

    本教程将详细讲解如何在Linux系统(如CentOS)上配置Nginx,特别是涉及`nginx.conf`主配置文件和`conf.d`目录的用法。 1. **Nginx配置基础** Nginx的配置文件通常位于`/etc/nginx/`目录下,其中`nginx.conf`是主...

    notepad++编辑nginx配置文件支持高亮

    描述中提到的方法就是通过导入一个名为"userDefineLang_nginx.xml"的文件,这个文件包含了Nginx配置文件的语法规则,如关键字、注释、字符串等的定义。导入步骤如下: 1. 首先,确保你已经下载了"userDefineLang_...

    nginx 配置及优化

    5. **location**块:这是Nginx配置中最细粒度的部分,用于匹配请求的URL并执行相应的操作。 ### 二、Nginx负载均衡 Nginx支持多种负载均衡策略,如轮询、最少连接数、IP哈希等,可以有效地分发客户端请求到后端...

    nginx搭建配置详细说明

    7.5. 可以将代理配置单独放在一个配置文件中 8. nginx的负载均衡(自学) 8.1. 什么是负载均衡 8.2. 负载均衡的优点 8.3. 负载均衡的分配策略 8.4. 负载均衡配置 9. 安装PHP 10. PHP-FPM 10.1. 什么是PHP-FPM ...

Global site tag (gtag.js) - Google Analytics