Apache 环境变量

2021-10-13 18:21 更新

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

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

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

尽管这些变量称为环境变量,但它们与底层操作系统控制的环境变量不同。相反,这些变量在内部Apache结构中存储和操作。它们仅在提供给CGI脚本和服务器端包含脚本时才成为实际的操作系统环境变量。如果您希望操作服务器本身运行的操作系统环境,则必须使用操作系统shell提供的标准环境操作机制。

设置环境变量

基本环境操作

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

有条件的每请求设置

为了提高灵活性,mod_setenvif提供的指令允许在每个请求的基础上设置环境变量,具体取决于特定请求的特征。例如,只有在特定浏览器(用户代理)发出请求时,或者仅在找到特定的Referer [sic]标头时才能设置变量。通过mod_rewrite的RewriteRule可以获得更大的灵活性,它使用[E = ...]选项来设置环境变量。

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

标准CGI变量

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

一些警告

  • 使用环境操作指令无法覆盖或更改标准CGI变量。
  • 当suexec用于启动CGI脚本时,在启动CGI脚本之前,环境将被清除为一组安全变量。安全变量列表在suexec.c中的编译时定义。
  • 出于可移植性的原因,环境变量的名称可能只包含字母,数字和下划线字符。另外,第一个字符可能不是数字。传递给CGI脚本和SSI页面时,与此限制不匹配的字符将被下划线替换。
  • 一个特殊情况是HTTP标头,它通过环境变量传递给CGI脚本等(见下文)。它们被转换为大写,只有短划线被替换为下划线;如果标头包含任何其他(无效)字符,则会以静默方式删除整个标头。
  • SetEnv指令在请求处理期间运行较晚,这意味着SetEnvIf和RewriteCond等指令不会看到使用它设置的变量。
  • 当服务器通过内部子请求查找路径(例如查找DirectoryIndex或使用mod_autoindex生成目录列表)时,子请求中不会继承每个请求的环境变量。此外,由于mod_setenvif采取行动的API阶段,因此不会在子请求中单独评估SetEnvIf指令。

使用环境变量

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

SSI页面

由mod_include的INCLUDES过滤器处理的服务器解析(SSI)文档可以使用echo元素打印环境变量,并且可以使用流控制元素中的环境变量来使页面的某些部分以请求的特征为条件。如上所述,Apache还为SSI页面提供标准CGI环境变量。有关更多详细信息,请参阅SSI教程。

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

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

条件响应标头Header指令可以使用环境变量的存在或不存在来确定是否将某个HTTP标头放置在对客户端的响应中。例如,这允许仅在来自客户端的请求中接收到对应的报头时才发送特定的响应报头。

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

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

特殊用途环境变量

互操作性问题导致引入了修改Apache与特定客户端沟通时的行为方式。为了使这些机制尽可能灵活,可以通过定义环境变量来调用它们,通常使用BrowserMatch,例如也可以使用SetEnv和PassEnv。

downgrade-1.0这会强制将请求视为HTTP/1.0请求,即使它是在后来的方言中。

force-gzip

如果激活了DEFLATE过滤器,则此环境变量将忽略浏览器的accept-encoding设置,并将无条件地发送压缩输出。

force-no-vary这会导致在将响应标头发送回客户端之前从响应标头中删除任何Vary字段。有些客户没有正确解释这个字段; 设置此变量可以解决此问题。设置此变量还暗含着force-response-1.0。

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

gzip-only-text/html设置为值1时,此变量将禁用mod_deflate为text/html以外的内容类型提供的DEFLATE输出过滤器。如果愿意使用静态压缩文件,mod_negotiation也会评估变量(不仅适用于gzip,还适用于所有与“identity”不同的编码)。

no-gzip设置后,mod_deflate的DEFLATE过滤器将关闭,mod_negotiation将拒绝提供编码资源。

no-cache适用于Apache-2.2.12及更高版本。设置后,mod_cache将不会保存其他可缓存的响应。此环境变量不会影响是否将为当前请求提供缓存中已有的响应。

nokeepalive这会在设置时禁用KeepAlive。

prefer-language这会影响mod_negotiation的行为。如果它包含语言标记(例如en,ja或x-klingon),则mod_negotiation会尝试使用该语言提供变体。如果没有这样的变体,则适用正常的协商过程。

redirect-carefully这会强制服务器在向客户端发送重定向时更加小心。这通常在客户端处理重定向的已知问题时使用。这最初是由于Microsoft WebFolders软件出现问题而导致的,该软件在通过DAV方法处理目录资源上的重定向时遇到问题。

suppress-error-charset

适用于2.0.54之后的版本。当Apache发出重定向以响应客户端请求时,响应包括一些实际文本,以防客户端无法(或不自动)遵循重定向。Apache通常根据它使用的字符集标记此文本,即ISO-8859-1。

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

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

示例

将损坏的标题传递给CGI脚本从Apache 2.4开始,Apache对于如何在mod_cgi和其他模块中将HTTP标头转换为环境变量更为严格:以前,标头名称中的任何无效字符都只是转换为下划线。这允许通过标头注入进行一些潜在的跨站点脚本攻击(参见Unusual Web Bugs,slide 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
Shell

改变行为不端的客户端的协议行为

早期版本建议在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
Shell

不需要在访问日志中记录图像请求

此示例使图像请求不会出现在访问日志中。可以轻松修改它以防止记录特定目录,或防止记录来自特定主机的请求。

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
Shell

防止图片盗链此示例说明如何防止服务器上的人员将服务器上的图像用作其页面上的内嵌图像。这不是推荐的配置,但它可以在有限的情况下工作。我们假设您的所有图像都位于名为/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>




以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号