当前位置:网络安全 > nginx学习笔记(七)Nginx如何处理请求---转载

nginx学习笔记(七)Nginx如何处理请求---转载

  • 发布:2023-10-06 06:10

-->
如何防止未定义主机名的请求被处理
基于混合域名和IP的虚拟主机
一个简单的PHP站点配置

基于名称的虚拟主机

Nginx 首先选择哪个虚拟主机 来处理请求。让我们从一个简单的配置开始(所有 3 个虚拟主机都在端口 *:80 上侦听):

服务器{
听80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
} 服务器{
听80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
} 服务器{
听80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
}

在此配置中,nginx 仅检查请求的“Host”标头,以确定应由哪个虚拟主机处理该请求。如果 Host 标头与任何虚拟主机都不匹配,或者请求根本不包含 Host 标头,则 nginx 会将请求分发到该端口上定义的默认虚拟主机。在上面的配置中,列出的第一个虚拟主机是 nginx 的默认虚拟主机 - 这是 nginx 的默认行为。此外,您还可以显式地将某个主机设置为默认虚拟主机,即在“listen”命令中设置“default_server”参数:

服务器{
听 80 default_server;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
}

default_server”参数从版本 0.8.21 开始可用。在以前的版本中,应使用“default”参数。

请注意,“default_server”是监听端口的属性,而不是主机名。稍后会详细介绍这一点。

如何防止处理未定义主机名的请求

如果不允许请求缺少“Host”标头,则可以定义以下主机并丢弃这些请求:

服务器{
听80;
服务器名称“”;
返回 444;
}

这里,我们将主机名设置为空字符串,以匹配未定义“Host”标头的请求,并返回 nginx 特定的非 http 标准返回码 444,可用于关闭连接。

从版本 0.8.48 开始,这已成为主机名的默认值,因此 server_name "" 可以省略。以前的版本使用计算机的 主机名 作为默认主机名。

基于混合域名和IP的虚拟主机

让我们看一下更复杂的配置。在此配置中,有多个虚拟主机侦听不同的地址:

服务器{
听192.168.1.1:80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
} 服务器{
听192.168.1.1:80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
} 服务器{
听192.168.1.2:80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
}

在此配置中,nginx首先测试请求的IP地址和端口是否与某个服务器配置块中的listen指令配置匹配。然后nginx继续测试请求的Host头是否匹配该server块中的某个server_name值。如果没有找到主机名,nginx会将请求交给默认的虚拟主机。例如,从端口 192.168.1.1:80 收到的访问 www.sychzs.cn 的请求将由侦听端口 192.168.1.1:80 的默认虚拟主机处理,在本例中,该请求是第一个server ,因为在此端口上没有定义名为 www.sychzs.cn 的虚拟主机。

默认服务器是监听端口的属性,因此可以为不同的监听端口设置不同的默认服务器:

服务器{
听192.168.1.1:80;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
} 服务器{
听 192.168.1.1:80 default_server;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
} 服务器{
听 192.168.1.2:80 default_server;
服务器名称 www.sychzs.cn www.sychzs.cn;
...
}

一个简单的PHP站点配置

现在让我们看看 nginx 如何在典型的简单 PHP 站点中为请求选择 位置

服务器{
听80;
服务器名称 www.sychzs.cn www.sychzs.cn;
根/数据/www; 地点/{
索引index.html索引.php;
} 位置 ~* \.(gif|jpg|png)$ {
30 天到期;
} 位置 ~ \.php$ {
fastcgi_pass 本地主机:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
包括 fastcgi_params;
}
}

首先,nginx使用前缀匹配来找到最准确的位置。在此步骤中,nginx 将忽略位置在配置文件中出现的顺序。在上面的配置中,唯一的前缀匹配位置是“/”,并且因为它可以匹配任何请求,所以它被用作最后的选择。然后nginx继续按照配置中的顺序匹配正则表达式的位置,匹配到第一个正则表达式后停止搜索。将使用匹配的位置。如果没有与正则表达式匹配的位置,则使用刚刚找到的前缀匹配最准确的位置。

请注意,所有位置匹配测试仅使用请求的URI部分,而不是参数部分。这是因为参数的写法有很多种,比如:

/index.php?user=john&page=1
/index.php?page=1&user=john

另外,任何人都可以在请求字符串中添加任意字符串:

/index.php?page=1&something+else&user=john

现在让我们看看如何使用上述配置处理请求:

  • 请求“/logo.gif”首先匹配位置“/”,然后匹配正则表达式“\.(gif|jpg|png)$” ”。因此,将由后者处理。 nginx 根据“root /data/www”命令,将请求映射到文件“/data/www/logo.gif”,并将该文件发送给客户端。
  • 请求“/index.php”首先也匹配位置“/”,然后匹配正则表达式“\.(php)$” ”。因此,它将被后者处理并发送到在 localhost:9000 监听的 FastCGI 服务器。 fastcgi_param指令将FastCGI参数SCRIPT_FILENAME的值设置为“/data/www/index.php”,然后FastCGI服务器执行该文件。变量$document_root等于root指令设置的值,变量$fastcgi_script_name的值是请求的uri,“/index.php”。
  • 请求“/about.html”只能匹配位置“/”,因此会使用该位置进行处理。根据“root /data/www”命令,nginx将请求映射到文件“/data/www/about.html”,并将该文件发送给客户端。
  • 请求“/”的处理比较复杂。它只能匹配位置“/”,因此它将使用该位置进行处理。然后,index命令使用其参数和“root /data/www”命令组成的文件路径来检测对应的文件是否存在。如果文件 /data/www/index.html 不存在,但 /data/www/index.php 存在,此命令将执行内部重定向到“” /index.php”,那么nginx会重新寻找匹配“/index.php”的位置,就好像这个请求是从客户端发送的一样。正如我们之前看到的,这个重定向的请求最终会交给FastCGI服务器进行处理。
-->

相关文章

作者:Igor Sysoev
编辑:Brian Mercer
翻译:Jinglong & cfsego