Apache 中的环境变量

有两种环境变量会影响 Apache HTTP Server。

首先,存在由底层 os 控制的环境变量。这些是在服务器启动之前设置的。它们可以在配置文件的扩展中使用,也可以选择使用 PassEnv 指令传递给 CGI 脚本和 SSI。

其次,Apache HTTP Server 提供了一种将信息存储在命名变量(也称为环境变量)中的机制。此信息可用于控制各种操作,例如日志记录或访问控制。变量还用作与外部程序(例如 CGI 脚本)进行通信的机制。本文档讨论了操纵和使用这些变量的不同方法。

尽管这些变量称为“环境变量”,但它们与底层 os 控制的环境变量不同。而是将这些变量存储在内部 Apache 结构中并进行操作。仅当将它们提供给 CGI 脚本和“服务器端包含”脚本时,它们才成为实际的 os 环境变量。如果要操纵服务器本身运行的 os 环境,则必须使用 osShell 程序提供的标准环境操纵机制。

设置环境变量

Related Modules Related Directives
mod_cache
mod_env
mod_rewrite
mod_setenvif
mod_unique_id
BrowserMatch
BrowserMatchNoCase
PassEnv
RewriteRule
SetEnv
SetEnvIf
SetEnvIfNoCase
UnsetEnv

基本环境操作

在 Apache 中设置环境变量的最基本方法是使用无条件的SetEnv指令。也可以使用PassEnv指令从启动服务器的 Shell 环境中传递变量。

每个请求的条件设置

为了获得更大的灵 Active,mod_setenvif提供的指令允许根据特定请求的 Feature,在每个请求的基础上设置环境变量。例如,仅当特定的浏览器(User-Agent)发出请求时才设置变量,或者仅当找到特定的 Referer [sic]Headers 时才可以设置变量。通过使用[E=...]选项设置环境变量的mod_rewriteRewriteRule可以提供更大的灵 Active。

Unique Identifiers

最后,mod_unique_id将每个请求的环境变量UNIQUE_ID设置为一个值,该值在非常特定的条件下保证在“所有”请求中是唯一的。

标准 CGI 变量

除了在 Apache 配置中设置并从 shell 传递的所有环境变量之外,CGI 脚本和 SSI 页面还提供了一组环境变量,其中包含CGI specification所要求的有关请求的元信息。

Some Caveats

使用环境变量

Related Modules Related Directives
mod_authz_host
mod_cgi
mod_ext_filter
mod_headers
mod_include
mod_log_config
mod_rewrite
Require
CustomLog
Deny
ExtFilterDefine
Header
LogFormat
RewriteCond
RewriteRule

CGI Scripts

环境变量的主要用途之一是将信息传达给 CGI 脚本。如上所述,传递给 CGI 脚本的环境除了 Apache 配置中设置的任何变量外,还包括有关请求的标准元信息。有关更多详细信息,请参见CGI tutorial

SSI Pages

mod_includeINCLUDES过滤器处理的服务器解析(SSI)文档可以使用echo元素打印环境变量,并且可以在流控制元素中使用环境变量使页面的某些部分取决于请求的 Feature。 Apache 还为 SSI 页面提供了如上所述的标准 CGI 环境变量。有关更多详细信息,请参见SSI tutorial

Access Control

可以使用allow from env=deny from env=指令基于环境变量的值来控制对服务器的访问。与SetEnvIf结合使用,可以根据 Client 端的特性灵活控制对服务器的访问。例如,您可以使用这些指令来拒绝对特定浏览器(User-Agent)的访问。

Conditional Logging

可以使用LogFormat选项%e将环境变量记录在访问日志中。此外,可以使用CustomLog指令的条件形式根据环境变量的状态来决定是否记录请求。与SetEnvIf结合使用,可以灵活地控制记录哪些请求。例如,您可以选择不记录以gif结尾的文件名的请求,或者可以选择仅记录来自子网外部 Client 端的请求。

条件响应标题

Header指令可以使用是否存在环境变量来确定是否将某些 HTTP Headers 放置在对 Client 端的响应中。例如,这允许仅在从 Client 端的请求中接收到相应的 Headers 时才发送特定的响应 Headers。

外部过滤器激活

可以使用disableenv=enableenv=选项根据环境变量激活由mod_ext_filter使用ExtFilterDefine指令配置的外部过滤器。

URL Rewriting

RewriteCond中的* TestString *的%{ENV:variable}形式允许mod_rewrite的重写引擎根据环境变量进行决策。请注意,在mod_rewrite中不带ENV:前缀的可访问变量实际上不是环境变量。相反,它们是mod_rewrite专用的变量,无法从其他模块访问。

专用环境变量

互操作性问题导致引入了一些机制来修改 Apache 在与特定 Client 端通信时的行为方式。为了使这些机制尽可能地灵活,可以通过定义环境变量(通常使用BrowserMatch)来调用它们,例如,也可以使用SetEnvPassEnv

downgrade-1.0

这将强制该请求被视为 HTTP/1.0 请求,即使该请求位于更高的方言中也是如此。

force-gzip

如果您激活了DEFLATE过滤器,则此环境变量将忽略浏览器的接受编码设置,并将无条件发送压缩输出。

force-no-vary

这将导致将任何Vary字段从响应 Headers 中删除,然后再将其发送回 Client 端。一些 Client 不能正确地解释该字段。设置此变量可以解决此问题。设置此变量还意味着 force-response-1.0

force-response-1.0

这会强制向发出 HTTP/1.0 请求的 Client 端发出 HTTP/1.0 响应。它最初是由于 AOL 代理出现问题而实施的。给定 HTTP/1.1 响应时,某些 HTTP/1.0 Client 端可能无法正常运行,并且可以用于与它们进行互操作。

gzip-only-text/html

当设置为值“ 1”时,此变量将禁用text/html以外的 Content Type 的mod_deflate提供的DEFLATE输出过滤器。如果您想使用静态压缩的文件,则mod_negotiation也会评估该变量(不仅适用于 gzip,而且适用于所有不同于“ identity”的编码)。

no-gzip

设置后,mod_deflateDEFLATE过滤器将关闭,而mod_negotiation将拒绝提供编码的资源。

no-cache

在 2.2.12 和更高版本中可用

设置后,mod_cache将不会保存其他可缓存的响应。此环境变量不会影响是否已为当前请求提供缓存中已存在的响应。

nokeepalive

设置后会禁用KeepAlive

prefer-language

这会影响mod_negotiation的行为。如果它包含语言标签(例如enjax-klingon),则mod_negotiation尝试提供该语言的变体。如果没有此类变体,则正常的negotiation流程适用。

redirect-carefully

这将迫使服务器在向 Client 端发送重定向时更加谨慎。通常在 Client 端具有处理重定向的已知问题时使用。这最初是由于 Microsoft 的 WebFolders 软件出现问题而实现的,该软件在通过 DAV 方法处理目录资源的重定向方面存在问题。

suppress-error-charset

在 2.0.54 之后的版本中可用

当 Apache 响应 Client 端请求发出重定向时,响应中将包含一些实际显示的文本,以防 Client 端无法(或不自动)遵循重定向。 Apache 通常根据其使用的字符集(ISO-8859-1)来标记此文本。

但是,如果重定向到使用其他字符集的页面,则某些损坏的浏览器版本将尝试使用重定向文本中的字符集,而不是实际页面。例如,这可能会导致希腊语渲染错误。

设置此环境变量会使 Apache 忽略重定向文本的字符集,然后这些损坏的浏览器将正确使用目标页面的字符集。

Security note

发送没有指定字符集的错误页面可能会导致不遵循 HTTP/1.1 规范并尝试从内容中“猜测”字符集的现有浏览器(MSIE)进行跨站点脚本攻击。这样的浏览器很容易被愚弄,使用 UTF-7 字符集,而 Importing 数据(例如 request-URI)中的 UTF-7 内容也不会被旨在防止跨站点脚本攻击的常规转义机制所转义。

force-proxy-request-1.0,proxy-nokeepalive,proxy-sendchunked,proxy-sendcl,proxy-chain-auth,proxy-interim-response,proxy-initial-not-pooled

这些指令更改了mod_proxy的协议行为。有关更多详细信息,请参见mod_proxymod_proxy_http文档。

Examples

将损坏的 Headers 传递给 CGI 脚本

从 2.4 版开始,Apache 更加严格地将 HTTP Headers 如何转换为mod_cgi和其他模块中的环境变量:以前,Headers 名称中的所有无效字符都被简单地转换为下划线。这允许通过 Headers 注入进行一些潜在的跨站点脚本攻击(请参阅异常的 Web 错误,幻灯片 19/20)。

如果您必须支持发送不完整 Headers 且无法修复的 Client 端,则涉及mod_setenvifmod_headers的简单变通办法可以让您仍然接受这些 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

更改 Client 端行为时的协议行为

早期版本建议在 httpd.conf 中包含以下行,以处理已知的 Client 端问题。由于不再在野外看到受影响的 Client 端,因此此配置可能不再需要。

#
# 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 上的“ 防止图像装饰其他网站”教程。

首页