配置文件中的指令可以应用于整个服务器,或者可以被限制为仅应用于特定的目录,文件,主机或URL。本文档描述了如何使用配置节容器或.htaccess
文件来更改其他配置指令的范围。
相关模块 | 相关指令 |
---|---|
容器有两种基本类型。每个请求都会评估大多数容器。随附的指令仅适用于与容器匹配的那些请求。的<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>
可以通过在测试之前加“!”来应用否定条件。同样,可以嵌套这些部分以实现更复杂的限制。
最常用的配置节容器是那些更改文件系统或Web空间中特定位置的配置的容器。首先,重要的是要了解两者之间的区别。文件系统是操作系统所看到的磁盘视图。例如,在默认安装中,Apache httpd驻留在/usr/local/apache2
Unix文件系统或"c:/Program Files/Apache Group/Apache2"
Windows文件系统中。(请注意,即使在Windows中,正斜杠也应始终用作Apache httpd配置文件中的路径分隔符,即使对于Windows也是如此。)相比之下,Web空间是由Web服务器交付并由客户端看到的站点视图。所以/dir/
网站空间中的路径对应于该路径
/usr/local/apache2/htdocs/dir/
在Unix上默认安装的Apache httpd的文件系统中。Web空间不必直接映射到文件系统,因为可以从数据库或其他位置动态生成网页。
在<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
,和任何其它实例的private.html
所述下找到/var/web/dir1/
目录。
<Directory "/var/web/dir1"> <Files "private.html"> Require all denied </Files> </Directory>
另一方面,该<Location>
指令及其对应的regex会更改Web空间中内容的配置。例如,以下配置阻止访问任何以/ private开头的URL路径。特别是,它会应用到的请求
http://yoursite.example.com/private
,
http://yoursite.example.com/private123
和
http://yoursite.example.com/private/dir/file.html
以及任何其他请求开始的/private
字符串。
<LocationMatch "^/private"> Require all denied </LocationMatch>
该<Location>
指令与文件系统没有任何关系。例如,以下示例显示了如何将特定的URL映射到所提供的内部Apache HTTP Server处理程序mod_status
。文件server-status
系统中无需存在任何被调用的文件。
<Location "/server-status"> SetHandler server-status </Location>
为了具有两个重叠的URL,必须考虑某些节或指令的评估顺序。为此
<Location>
将是:
<Location "/foo"> </Location> <Location "/foo/bar"> </Location>
<Alias>
es相反,反之亦然:
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>
指令可以在每次使用壳式通配符作为
fnmatch
从C标准库。字符“ *”与任何字符序列“?”匹配 匹配任何单个字符,而“[ SEQ ]”中的任何字符匹配SEQ。“ /”字符不会与任何通配符匹配;必须明确指定。
如果需要更灵活的匹配,每个容器具有规则则表达式(regex)对应<DirectoryMatch>
,<FilesMatch>
以及<LocationMatch>
允许Perl兼容
的正则表达式
中选择的匹配中使用。但是请参阅下面有关配置合并的部分,以了解使用正则表达式部分将如何更改指令的应用方式。
更改所有用户目录配置的非正则表达式通配符部分如下所示:
<Directory "/home/*/public_html"> Options Indexes </Directory>
使用正则表达式部分,我们可以一次拒绝访问多种类型的图像文件:
<FilesMatch "\.(?i:gif|jpe?g|png)$"> Require all denied </FilesMatch>
将包含命名组和反向引用的正则表达式以大写形式添加到具有相应名称的环境中。这样就可以从表达式
和模块(如)中引用文件名路径和URL的元素mod_rewrite
。
<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>
实际上,在文件系统容器和Webspace容器之间进行选择非常容易。将指令应用于驻留在文件系统中的对象时,请始终使用<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>
)。命名部分的正则表达式对应的行为相同。
嵌套部分在相同类型的非嵌套部分之后合并。
该<VirtualHost>
容器封装,适用于特定主机的指令。当从同一台计算机为多台主机提供不同配置时,这很有用。有关更多信息,请参见《虚拟主机文档》。
在<Proxy>
与<ProxyMatch>
容器所适用中的指令只有通过访问网站mod_proxy
匹配指定的URL,它的代理服务器。例如,以下配置将仅允许一部分客户端www.example.com
使用代理服务器访问
网站:
<Proxy "http://www.example.com/*"> Require host yournetwork.example.com </Proxy>
要找出在哪些类型的配置节中允许使用哪些指令,请检查指令的上下文。被允许在一切
<Directory>
的部分也被语法允许
<DirectoryMatch>
,
<Files>
,
<FilesMatch>
,
<Location>
,
<LocationMatch>
,
<Proxy>
,和<ProxyMatch>
部分。但是,有一些例外情况:
AllowOverride
指令仅在<Directory>
部分中有效。FollowSymLinks
和
SymLinksIfOwnerMatch
Options
只在工作<Directory>
段或
.htaccess
文件。Options
指令不能在<Files>
和<FilesMatch>
部分中使用。配置部分以非常特殊的顺序应用。由于这会对配置指令的解释方式产生重要影响,因此了解其工作原理非常重要。
合并顺序为:
<Directory>
(正则表达式除外)并.htaccess
同时完成(使用
.htaccess
,如果允许,则覆盖
<Directory>
)<DirectoryMatch>
(和<Directory "~">
)<Files>
同时<FilesMatch>
完成<Location>
同时<LocationMatch>
完成<If>
一些重要的评论:
<Directory>
,在每个组中,将按节在配置文件中出现的顺序对其进行处理。例如,对/ foo / bar的请求将匹配
<Location "/foo/bar">
和
<Location "/foo">
(在本例中为第4组):将评估两个部分,但将按照它们在配置文件中出现的顺序进行评估。<Directory>
(上面的组1)按顺序最短目录组件中的最长来处理。例如,
<Directory "/var/web/dir">
将在之前进行处理
<Directory "/var/web/dir/subdir">
。<Directory>
部分应用于同一目录,则将按配置文件顺序对其进行处理。Include
伪指令包含的配置将被视为位于Include
伪指令所在位置的包含文件中
。<VirtualHost>
将应用部分内部的部分。这允许虚拟主机覆盖主服务器配置。mod_proxy
,
<Proxy>
容器将按<Directory>
处理顺序代替容器。<Location>
/ <LocationMatch>
序列(其中Aliases
和DocumentRoots
用于将URL映射到文件名)。翻译完成后,此序列的结果将被完全丢弃。
在阅读了如何合并配置节之后,经常会出现一个问题,即如何处理和何时mod_rewrite
处理特定模块的指令。答案并不简单,需要一些背景知识。每个httpd模块管理自己的配置,并且httpd.conf中的每个指令都在特定上下文中指定一个配置。httpd在读取时不执行命令。
在运行时,httpd的核心按照上述顺序遍历已定义的配置节,以确定哪些节适用于当前请求。当第一部分匹配时,它将被视为此请求的当前配置。如果后续部分也匹配,则每个部分中带有指令的每个模块都有机会在两个部分之间合并其配置。结果是第三个配置,该过程一直进行到评估所有配置部分为止。
完成上述步骤后,HTTP请求的“实际”处理开始:每个模块都有机会运行并执行所需的任何任务。他们可以从httpd的核心中检索自己的最终合并配置,以确定应如何操作。
一个示例可以帮助可视化整个过程。以下配置使用
Header
伪指令of mod_headers
设置特定的HTTP标头。httpd将在CustomHeaderName
请求的标头中
设置什么值/example/index.html
?
<Directory "/"> Header set CustomHeaderName one <FilesMatch ".*"> Header set CustomHeaderName three </FilesMatch> </Directory> <Directory "/example"> Header set CustomHeaderName two </Directory>
Directory
“ /”匹配,并创建一个初始配置,以CustomHeaderName
使用该值设置标题one
。Directory
“ / example”匹配,并且由于mod_headers
在其代码中指定了在合并的情况下要覆盖的内容,因此创建了一个新配置,以将CustomHeaderName
标头设置为value two
。FilesMatch
“。*”匹配,并且出现另一个合并机会,从而使CustomHeaderName
标头设置为value three
。mod_headers
调用该处理,它将接收用于将CustomHeaderName
标头设置为value 的配置three
。mod_headers
通常使用此配置执行其工作,即设置foo标头。这并不意味着模块无法执行更复杂的操作,例如丢弃指令,因为不需要或不赞成使用该指令等。.htaccess也是如此,因为它们具有与Directory
合并顺序相同的优先级。要理解的重要概念是,配置节之类的 模块指令不能与之相比,Directory
并且FilesMatch
不能与之类似Header
,RewriteRule
因为它们在不同级别上运行。
以下是显示合并顺序的人工示例。假设它们都适用于请求,则本示例中的指令将按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>