<-
Apache > HTTP 服务器 > 文档 > 版本 2.4

配置节

可用语言:  en  |  fr  |  ja  |  ko  |  tr 

配置文件 中的指令可以应用于整个服务器,也可以限制为仅应用于特定目录、文件、主机或 URL。本文档介绍如何使用配置节容器或.htaccess文件来更改其他配置指令的作用域。

Support Apache!

另请参阅

top

配置节容器类型

容器主要有两种类型。大多数容器会针对每个请求进行评估。封闭的指令仅适用于与容器匹配的请求。另一方面,<IfDefine><IfModule><IfVersion> 容器仅在服务器启动和重启时进行评估。如果它们的条件在启动时为真,则封闭的指令将应用于所有请求。如果条件不为真,则封闭的指令将被忽略。

<IfDefine> 指令包含仅在 httpd 命令行上定义了适当参数时才应用的指令。例如,使用以下配置,只有在使用 httpd -DClosedForNow 启动服务器时,所有请求才会被重定向到另一个站点。

<IfDefine ClosedForNow>
    Redirect "/" "http://otherserver.example.com/"
</IfDefine>

<IfModule> 指令非常类似,只是它包含仅在服务器中提供特定模块时才应用的指令。该模块必须在服务器中静态编译,或者必须动态编译,并且其 LoadModule 行必须在配置文件中更早。只有在需要配置文件在安装或未安装某些模块的情况下都能正常工作时,才应使用此指令。不应使用它来包含始终要工作的指令,因为它会抑制有关缺少模块的有用错误消息。

在以下示例中,MimeMagicFile 指令仅在 mod_mime_magic 可用时才应用。

<IfModule mod_mime_magic.c>
    MimeMagicFile "conf/magic"
</IfModule>

<IfVersion> 指令与 <IfDefine><IfModule> 非常类似,只是它包含仅在执行特定版本的服务器时才应用的指令。此模块旨在用于测试套件和大型网络,这些网络必须处理不同的 httpd 版本和不同的配置。

<IfVersion >= 2.4>
    # this happens only in versions greater or
    # equal 2.4.0.
</IfVersion>

<IfDefine><IfModule><IfVersion> 可以通过在测试前加上 "!" 来应用否定条件。此外,这些节可以嵌套以实现更复杂的限制。

top

文件系统、网络空间和布尔表达式

最常用的配置节容器是那些更改文件系统或网络空间中特定位置的配置的容器。首先,了解两者之间的区别很重要。文件系统是操作系统看到的磁盘视图。例如,在默认安装中,Apache httpd 位于 Unix 文件系统中的 /usr/local/apache2 或 Windows 文件系统中的 "c:/Program Files/Apache Group/Apache2"。(请注意,即使在 Windows 中,也应始终使用正斜杠作为 Apache httpd 配置文件中的路径分隔符。)相反,网络空间是 Web 服务器提供的网站视图,也是客户端看到的视图。因此,网络空间中的路径 /dir/ 对应于在 Unix 上的默认 Apache httpd 安装的文件系统中的路径 /usr/local/apache2/htdocs/dir/。网络空间不必直接映射到文件系统,因为网页可以从数据库或其他位置动态生成。

文件系统容器

<Directory><Files> 指令及其 正则表达式 对应项将指令应用于文件系统的一部分。包含在 <Directory> 节中的指令适用于命名文件系统目录及其所有子目录(以及这些目录中的文件)。使用 .htaccess 文件 可以获得相同的效果。例如,在以下配置中,将为 /var/web/dir1 目录及其所有子目录启用目录索引。

<Directory "/var/web/dir1">
    Options +Indexes
</Directory>

包含在 <Files> 节中的指令适用于任何具有指定名称的文件,无论它位于哪个目录。因此,例如,以下配置指令将在放置在配置文件的主节中时,拒绝访问任何名为 private.html 的文件,无论它在哪里找到。

<Files "private.html">
    Require all denied
</Files>

要处理在文件系统特定部分找到的文件,可以组合使用 <Files><Directory> 节。例如,以下配置将拒绝访问 /var/web/dir1/private.html/var/web/dir1/subdir2/private.html/var/web/dir1/subdir3/private.html 以及在 /var/web/dir1/ 目录下找到的任何其他 private.html 实例。

<Directory "/var/web/dir1">
    <Files "private.html">
        Require all denied
    </Files>
</Directory>

网络空间容器

<Location> 指令及其 正则表达式 对应项,另一方面,会更改网络空间中内容的配置。例如,以下配置阻止访问任何以 /private 开头的 URL 路径。特别是,它将适用于对 http://yoursite.example.com/privatehttp://yoursite.example.com/private123http://yoursite.example.com/private/dir/file.html 的请求,以及任何其他以 /private 字符串开头的请求。

<LocationMatch "^/private">
    Require all denied
</LocationMatch>

<Location> 指令不必与文件系统有任何关系。例如,以下示例显示了如何将特定 URL 映射到由 mod_status 提供的内部 Apache HTTP 服务器处理程序。文件系统中不需要存在名为 server-status 的文件。

<Location "/server-status">
    SetHandler server-status
</Location>

重叠网络空间

为了拥有两个重叠的 URL,必须考虑评估某些节或指令的顺序。对于 <Location>,这将是

<Location "/foo">
</Location>
<Location "/foo/bar">
</Location>

另一方面,<Alias> 是反向映射的

Alias "/foo/bar" "/srv/www/uncommon/bar"
Alias "/foo"     "/srv/www/common/foo"

ProxyPass 指令也是如此

ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On

通配符和正则表达式

<Directory><Files><Location> 指令可以使用 C 标准库中 fnmatch 中的 shell 风格通配符。字符 "*" 匹配任何字符序列,"?" 匹配任何单个字符,而 "[*seq]" 匹配 *seq* 中的任何字符。"/" 字符不会被任何通配符匹配;它必须显式指定。

如果需要更灵活的匹配,每个容器都有一个正则表达式 (regex) 对应项 <DirectoryMatch><FilesMatch><LocationMatch>,它们允许使用与 Perl 兼容的 正则表达式 来选择匹配项。但是,请参阅下面有关配置合并的部分,了解使用正则表达式节将如何更改指令的应用方式。

更改所有用户目录配置的非正则表达式通配符节可能如下所示

<Directory "/home/*/public_html">
    Options Indexes
</Directory>

使用正则表达式节,我们可以一次拒绝访问多种类型的图像文件

<FilesMatch "\.(?i:gif|jpe?g|png)$">
    Require all denied
</FilesMatch>

包含命名组和反向引用的正则表达式将以相应的名称(大写)添加到环境中。这允许在 表达式mod_rewrite 等模块中引用文件名路径和 URL 的元素。

<DirectoryMatch "^/var/www/combined/(?<SITENAME>[^/]+)">
    Require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
</DirectoryMatch>

布尔表达式

<If> 指令根据布尔表达式可以表达的条件更改配置。例如,以下配置在 HTTP Referer 标头不以 "http://www.example.com/" 开头时拒绝访问。

<If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')">
    Require all denied
</If>

何时使用

在文件系统容器和网络空间容器之间进行选择实际上非常容易。当将指令应用于驻留在文件系统中的对象时,始终使用 <Directory><Files>。当将指令应用于不驻留在文件系统中的对象(例如从数据库生成的网页)时,请使用 <Location>

重要的是,在尝试限制对文件系统中对象的访问时,永远不要使用 <Location>。这是因为许多不同的网络空间位置 (URL) 可能映射到相同的文件系统位置,从而允许绕过您的限制。例如,考虑以下配置

<Location "/dir/">
    Require all denied
</Location>

如果请求的是http://yoursite.example.com/dir/,那么这将正常工作。但是,如果您的文件系统不区分大小写呢?那么您的限制很容易被请求http://yoursite.example.com/DIR/绕过。相比之下,<Directory>指令将应用于从该位置提供的任何内容,无论其如何调用。(文件系统链接除外。同一个目录可以使用符号链接放置在文件系统的多个位置。 <Directory>指令将遵循符号链接,而不会重置路径名。因此,为了获得最高级别的安全性,应使用适当的 Options指令禁用符号链接。)

如果您可能认为这些都不适用于您,因为您使用的是区分大小写的文件系统,请记住,还有许多其他方法可以将多个网络空间位置映射到同一个文件系统位置。因此,您应该始终使用文件系统容器,只要可以。但是,此规则有一个例外。将配置限制放在<Location "/">部分是完全安全的,因为此部分将应用于所有请求,无论特定 URL 如何。

部分嵌套

某些部分类型可以嵌套在其他部分类型中。一方面,<Files>可以在 <Directory>内部使用。另一方面,<If>可以在 <Directory><Location><Files>部分内部使用(但不能在另一个 <If>内部使用)。命名部分的正则表达式对应物行为相同。

嵌套部分在合并后,会与相同类型的非嵌套部分合并。

top

虚拟主机

<VirtualHost>容器包含应用于特定主机的指令。当从同一台机器提供多个主机时,这很有用,每个主机都有不同的配置。有关更多信息,请参阅虚拟主机文档

top

代理

<Proxy><ProxyMatch>容器仅将包含的配置指令应用于通过 mod_proxy的代理服务器访问的网站,这些网站与指定的 URL 匹配。例如,以下配置将仅允许一部分客户端使用代理服务器访问www.example.com网站

<Proxy "http://www.example.com/*">
    Require host yournetwork.example.com
</Proxy>
top

允许哪些指令?

要了解在哪些类型的配置部分中允许哪些指令,请检查指令的上下文。在 <Directory>部分中允许的所有内容在语法上也允许在 <DirectoryMatch><Files><FilesMatch><Location><LocationMatch><Proxy><ProxyMatch>部分中使用。但是,有一些例外

top

部分如何合并

配置部分以非常特定的顺序应用。由于这会对配置指令的解释方式产生重要影响,因此了解其工作原理非常重要。

合并顺序为

  1. <Directory>(除正则表达式外)和.htaccess同时完成(如果允许,.htaccess将覆盖 <Directory>
  2. <DirectoryMatch>(和<Directory "~">
  3. <Files><FilesMatch>同时完成
  4. <Location><LocationMatch>同时完成
  5. <If>部分,即使它们包含在上述任何上下文中。

一些重要说明

技术说明

实际上,在名称转换阶段(使用AliasesDocumentRoots将 URL 映射到文件名)之前,会执行一个<Location>/<LocationMatch>序列。转换完成后,此序列的结果将被完全丢弃。

模块和配置部分之间的关系

阅读配置部分如何合并后经常出现的一个问题是,如何以及何时处理特定模块(如 mod_rewrite)的指令。答案并不简单,需要一些背景知识。每个 httpd 模块都管理自己的配置,并且它在 httpd.conf 中的每个指令都在特定上下文中指定一个配置片段。httpd 不会在读取时执行命令。

在运行时,httpd 的核心会按上述顺序迭代定义的配置部分,以确定哪些部分适用于当前请求。当第一个部分匹配时,它被认为是此请求的当前配置。如果后续部分也匹配,则每个在两个部分中都有指令的模块都有机会合并其配置。结果是第三个配置,此过程将一直持续到所有配置部分都被评估为止。

完成上述步骤后,HTTP 请求的“真实”处理将开始:每个模块都有机会运行并执行它们喜欢的任何任务。它们可以从 httpd 的核心检索自己的最终合并配置,以确定它们应该如何行动。

一个例子可以帮助可视化整个过程。以下配置使用 mod_headersHeader指令来设置特定的 HTTP 标头。httpd 将为对/example/index.html的请求在CustomHeaderName标头中设置什么值?

<Directory "/">
    Header set CustomHeaderName one
    <FilesMatch ".*">
        Header set CustomHeaderName three
    </FilesMatch>
</Directory>

<Directory "/example">
    Header set CustomHeaderName two
</Directory>

这对 .htaccess 也是如此,因为它们在合并顺序中与 Directory具有相同的优先级。要理解的重要概念是,配置部分(如 DirectoryFilesMatch)与模块特定指令(如 HeaderRewriteRule)不可比,因为它们在不同的级别上运行。

一些有用的示例

以下是人工示例,用于展示合并顺序。假设所有指令都适用于请求,则此示例中的指令将按以下顺序应用:A > B > C > D > E。

<Location "/">
    E
</Location>

<Files "f.html">
    D
</Files>

<VirtualHost *>
    <Directory "/a/b">
        B
    </Directory>
</VirtualHost>

<DirectoryMatch "^.*b$">
    C
</DirectoryMatch>

<Directory "/a/b">
    A
</Directory>

为了更具体地说明,请考虑以下情况。无论在 <Directory> 部分中设置了哪些访问限制,<Location> 部分将最后进行评估,并允许无限制地访问服务器。换句话说,合并顺序很重要,请谨慎操作!

<Location "/">
    Require all granted
</Location>

# Whoops!  This <Directory> section will have no effect
<Directory "/">
    <RequireAll>
        Require all granted
        Require not host badguy.example.com
    </RequireAll>
</Directory>

可用语言:  en  |  fr  |  ja  |  ko  |  tr 

top

评论

注意
这不是问答区。此处放置的评论应针对改进文档或服务器的建议,如果这些建议已被实施或被认为无效/与主题无关,则可能会被我们的版主删除。有关如何管理 Apache HTTP Server 的问题,请咨询我们的 IRC 频道 #httpd(位于 Libera.chat)或发送到我们的 邮件列表