Apache HTTP Server 版本 2.4
影响 Apache HTTP Server 的环境变量有两种。
首先,是底层操作系统控制的环境变量。这些变量在服务器启动之前设置。它们可以在配置文件中的扩展中使用,并且可以选择使用 PassEnv 指令传递给 CGI 脚本和 SSI。
其次,Apache HTTP Server 提供了一种机制,用于将信息存储在名为环境变量的命名变量中。这些信息可用于控制各种操作,例如日志记录或访问控制。这些变量还用作与外部程序(如 CGI 脚本)通信的机制。本文档讨论了操作和使用这些变量的不同方法。
虽然这些变量被称为环境变量,但它们与底层操作系统控制的环境变量不同。相反,这些变量存储在 Apache 的内部结构中并由其操作。只有在提供给 CGI 脚本和服务器端包含脚本时,它们才会成为实际的操作系统环境变量。如果您希望操作服务器本身运行的操作系统环境,则必须使用您的操作系统 shell 提供的标准环境操作机制。
相关模块 | 相关指令 |
---|---|
在 Apache 中设置环境变量最基本的方法是使用无条件的 SetEnv
指令。还可以使用 PassEnv
指令从启动服务器的 shell 环境中传递变量。
为了提高灵活性,mod_setenvif
提供的指令允许根据特定请求的特征按请求设置环境变量。例如,只有在特定浏览器(User-Agent)发出请求时,或者只有在找到特定 Referer [sic] 标头时,才会设置变量。通过 mod_rewrite
的 RewriteRule
可以获得更大的灵活性,该指令使用 [E=...]
选项设置环境变量。
最后,mod_unique_id
为每个请求设置环境变量 UNIQUE_ID
,其值在非常特定的条件下保证在“所有”请求中都是唯一的。
除了在 Apache 配置中设置并从 shell 传递的所有环境变量之外,CGI 脚本和 SSI 页面还提供了一组环境变量,其中包含有关请求的元信息,如 CGI 规范 所需。
suexec
启动 CGI 脚本时,环境将被清理到一组安全变量,然后才会启动 CGI 脚本。安全变量的列表在 suexec.c
中的编译时定义。SetEnv
指令在请求处理期间运行较晚,这意味着诸如 SetEnvIf
和 RewriteCond
之类的指令将看不到用它设置的变量。DirectoryIndex
或使用 mod_autoindex
生成目录列表)查找路径时,按请求的环境变量不会在子请求中继承。此外,由于 mod_setenvif
执行操作的 API 阶段,SetEnvIf
指令不会在子请求中单独评估。相关模块 | 相关指令 |
---|---|
环境变量的主要用途之一是将信息传递给 CGI 脚本。如上所述,传递给 CGI 脚本的环境包括有关请求的标准元信息,以及在 Apache 配置中设置的任何变量。有关更多详细信息,请参见 CGI 教程。
由 mod_include
的 INCLUDES
过滤器处理的服务器解析 (SSI) 文档可以使用 echo
元素打印环境变量,并且可以使用环境变量在流程控制元素中根据请求的特征使页面的某些部分成为条件。Apache 还为 SSI 页面提供了如上所述的标准 CGI 环境变量。有关更多详细信息,请参见 SSI 教程。
可以使用 Require env
和 Require not env
指令根据环境变量控制对服务器的访问。与 SetEnvIf
结合使用,这允许根据客户端的特征灵活控制对服务器的访问。例如,您可以使用这些指令拒绝特定浏览器(User-Agent)访问。
可以使用 LogFormat
选项 %e
在访问日志中记录环境变量。此外,可以使用 CustomLog
指令的条件形式根据环境变量的状态决定是否记录请求。与 SetEnvIf
结合使用,这允许灵活控制记录哪些请求。例如,您可以选择不记录以 gif
结尾的文件名的请求,或者您可以选择只记录来自您子网之外的客户端的请求。
Header
指令可以使用环境变量的存在与否来确定是否将某个 HTTP 标头放在对客户端的响应中。例如,这允许仅在从客户端的请求中收到相应的标头时才发送某个响应标头。
使用 ExtFilterDefine
指令由 mod_ext_filter
配置的外部过滤器可以使用 disableenv=
和 enableenv=
选项根据环境变量激活。
RewriteCond
中的 TestString 的 %{ENV:variable}
形式允许 mod_rewrite
的重写引擎根据环境变量做出决策。请注意,在 mod_rewrite
中没有 ENV:
前缀即可访问的变量实际上不是环境变量。相反,它们是 mod_rewrite
特有的变量,其他模块无法访问。
互操作性问题导致引入了修改 Apache 与特定客户端通信方式的机制。为了使这些机制尽可能灵活,它们通过定义环境变量来调用,通常使用 BrowserMatch
,尽管也可以使用 SetEnv
和 PassEnv
,例如。
这会强制将请求视为 HTTP/1.0 请求,即使它是在更高版本的方言中。
如果您启用了 DEFLATE
过滤器,则此环境变量将忽略浏览器的 accept-encoding 设置,并无条件地发送压缩输出。
这会导致在将响应标头发送回客户端之前,从响应标头中删除任何 Vary
字段。某些客户端无法正确解释此字段;设置此变量可以解决此问题。设置此变量还意味着force-response-1.0。
这会强制对发出 HTTP/1.0 请求的客户端进行 HTTP/1.0 响应。它最初是由于 AOL 代理出现问题而实现的。某些 HTTP/1.0 客户端在收到 HTTP/1.1 响应时可能无法正常运行,这可以用来与它们进行互操作。
当设置为“1”时,此变量会禁用 mod_deflate
提供的 DEFLATE
输出过滤器,用于除 text/html
之外的内容类型。如果您更愿意使用静态压缩文件,mod_negotiation
也会评估该变量(不仅针对 gzip,而且针对所有与“identity”不同的编码)。
当设置时,mod_deflate
的 DEFLATE
过滤器将被关闭,并且 mod_negotiation
将拒绝提供编码的资源。
在版本 2.2.12 及更高版本中可用
当设置时,mod_cache
不会保存可缓存的响应。此环境变量不会影响是否为当前请求提供缓存中的响应。
当设置时,这会禁用 KeepAlive
。
这会影响 mod_negotiation
的行为。如果它包含语言标签(例如 en
、ja
或 x-klingon
),mod_negotiation
会尝试提供具有该语言的变体。如果没有这样的变体,则会应用正常的 协商 过程。
这会强制服务器在向客户端发送重定向时更加谨慎。这通常用于客户端已知存在处理重定向的问题时。这最初是由于 Microsoft 的 WebFolders 软件存在问题而实现的,该软件在通过 DAV 方法处理目录资源上的重定向时存在问题。
在 2.0.54 之后的版本中可用
当 Apache 响应客户端请求发出重定向时,响应中包含一些实际文本,以防客户端无法(或不)自动遵循重定向。Apache 通常根据其使用的字符集(即 ISO-8859-1)对该文本进行标记。
但是,如果重定向到使用不同字符集的页面,一些损坏的浏览器版本将尝试使用重定向文本中的字符集,而不是实际页面。这会导致希腊语等字符被错误地渲染。
设置此环境变量会导致 Apache 省略重定向文本的字符集,这些损坏的浏览器将正确使用目标页面的字符集。
发送没有指定字符集的错误页面可能会允许针对现有浏览器(MSIE)进行跨站点脚本攻击,这些浏览器不遵循 HTTP/1.1 规范并尝试从内容中“猜测”字符集。这些浏览器很容易被欺骗使用 UTF-7 字符集,并且来自输入数据(例如请求 URI)的 UTF-7 内容不会被用于防止跨站点脚本攻击的常用转义机制转义。
这些指令会改变 mod_proxy
的协议行为。有关更多详细信息,请参阅 mod_proxy
和 mod_proxy_http
文档。
在 2.4.59 及更高版本中可用
此变量允许在 CGI 类模块中运行的脚本提供自己的 Content-Length HTTP 响应头。它应该只在包含受信任脚本的配置部分中设置。
从 2.4 版本开始,Apache 对 HTTP 头如何转换为 mod_cgi
和其他模块中的环境变量更加严格:以前,头名称中的任何无效字符都会简单地转换为下划线。这允许通过头注入进行一些潜在的跨站点脚本攻击(参见 Unusual Web Bugs,幻灯片 19/20)。
如果您必须支持发送损坏的头且无法修复的客户端,则可以使用 mod_setenvif
和 mod_headers
的简单解决方法来仍然接受这些头
# # The following works around a client sending a broken Accept_Encoding # header. # SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_accept_encoding=$1 RequestHeader set Accept-Encoding %{fix_accept_encoding}e env=fix_accept_encoding
早期版本建议在 httpd.conf 中包含以下行来处理已知的客户端问题。由于受影响的客户端不再出现在野外,因此此配置可能不再需要。
# # The following directives modify normal HTTP response behavior. # The first directive disables keepalive for Netscape 2.x and browsers that # spoof it. There are known problems with these browser implementations. # The second directive is for Microsoft Internet Explorer 4.0b2 # which has a broken HTTP/1.1 implementation and does not properly # support keepalive when it is used on 301 or 302 (redirect) responses. # BrowserMatch "Mozilla/2" nokeepalive BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 # # The following directive disables HTTP/1.1 responses to browsers which # are in violation of the HTTP/1.0 spec by not being able to understand a # basic 1.1 response. # BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "JDK/1\.0" force-response-1.0
此示例可防止图像请求出现在访问日志中。它可以轻松地修改为防止记录特定目录的日志,或防止记录来自特定主机的请求。
SetEnvIf Request_URI \.gif image-request SetEnvIf Request_URI \.jpg image-request SetEnvIf Request_URI \.png image-request CustomLog "logs/access_log" common env=!image-request
此示例展示了如何防止不在您服务器上的人员在他们的页面上使用您服务器上的图像作为内联图像。这不是推荐的配置,但它可以在有限的情况下工作。我们假设您所有的图像都位于名为 /web/images
的目录中。
SetEnvIf Referer "^http://www\.example\.com/" local_referal # Allow browsers that do not send Referer info SetEnvIf Referer "^$" local_referal <Directory "/web/images"> Require env local_referal </Directory>
有关此技术的更多信息,请参阅 ServerWatch 上的“Keeping Your Images from Adorning Other Sites”教程。