Apache 環(huán)境變量

2021-10-13 18:21 更新

有兩種環(huán)境變量會(huì)影響Apache HTTP Server。

首先,存在由底層操作系統(tǒng)控制的環(huán)境變量。這些是在服務(wù)器啟動(dòng)之前設(shè)置的。它們可以在配置文件的擴(kuò)展中使用,也可以使用PassEnv指令傳遞給CGI腳本和SSI。

其次,Apache HTTP Server提供了一種機(jī)制,用于在命名變量中存儲(chǔ)信息,這些變量也稱為環(huán)境變量。此信息可用于控制各種操作,如日志記錄或訪問(wèn)控制。變量還用作與外部程序(如CGI腳本)通信的機(jī)制。本文將討論了操作和使用這些變量的不同方法。

盡管這些變量稱為環(huán)境變量,但它們與底層操作系統(tǒng)控制的環(huán)境變量不同。相反,這些變量在內(nèi)部Apache結(jié)構(gòu)中存儲(chǔ)和操作。它們僅在提供給CGI腳本和服務(wù)器端包含腳本時(shí)才成為實(shí)際的操作系統(tǒng)環(huán)境變量。如果您希望操作服務(wù)器本身運(yùn)行的操作系統(tǒng)環(huán)境,則必須使用操作系統(tǒng)shell提供的標(biāo)準(zhǔn)環(huán)境操作機(jī)制。

設(shè)置環(huán)境變量

基本環(huán)境操作

在Apache中設(shè)置環(huán)境變量的最基本方法是使用無(wú)條件的SetEnv指令。也可以使用PassEnv指令從啟動(dòng)服務(wù)器的shell環(huán)境傳遞變量。

有條件的每請(qǐng)求設(shè)置

為了提高靈活性,mod_setenvif提供的指令允許在每個(gè)請(qǐng)求的基礎(chǔ)上設(shè)置環(huán)境變量,具體取決于特定請(qǐng)求的特征。例如,只有在特定瀏覽器(用戶代理)發(fā)出請(qǐng)求時(shí),或者僅在找到特定的Referer [sic]標(biāo)頭時(shí)才能設(shè)置變量。通過(guò)mod_rewrite的RewriteRule可以獲得更大的靈活性,它使用[E = ...]選項(xiàng)來(lái)設(shè)置環(huán)境變量。

唯一標(biāo)識(shí)符最后,mod_unique_id將每個(gè)請(qǐng)求的環(huán)境變量UNIQUE_ID設(shè)置為一個(gè)值,該值在非常特定的條件下保證在“所有”請(qǐng)求中是唯一的。

標(biāo)準(zhǔn)CGI變量

除了在Apache配置中設(shè)置并從shell傳遞的所有環(huán)境變量之外,CGI腳本和SSI頁(yè)面還提供了一組環(huán)境變量,其中包含有關(guān)CGI規(guī)范所要求的請(qǐng)求的元信息。

一些警告

  • 使用環(huán)境操作指令無(wú)法覆蓋或更改標(biāo)準(zhǔn)CGI變量。
  • 當(dāng)suexec用于啟動(dòng)CGI腳本時(shí),在啟動(dòng)CGI腳本之前,環(huán)境將被清除為一組安全變量。安全變量列表在suexec.c中的編譯時(shí)定義。
  • 出于可移植性的原因,環(huán)境變量的名稱可能只包含字母,數(shù)字和下劃線字符。另外,第一個(gè)字符可能不是數(shù)字。傳遞給CGI腳本和SSI頁(yè)面時(shí),與此限制不匹配的字符將被下劃線替換。
  • 一個(gè)特殊情況是HTTP標(biāo)頭,它通過(guò)環(huán)境變量傳遞給CGI腳本等(見(jiàn)下文)。它們被轉(zhuǎn)換為大寫(xiě),只有短劃線被替換為下劃線;如果標(biāo)頭包含任何其他(無(wú)效)字符,則會(huì)以靜默方式刪除整個(gè)標(biāo)頭。
  • SetEnv指令在請(qǐng)求處理期間運(yùn)行較晚,這意味著SetEnvIf和RewriteCond等指令不會(huì)看到使用它設(shè)置的變量。
  • 當(dāng)服務(wù)器通過(guò)內(nèi)部子請(qǐng)求查找路徑(例如查找DirectoryIndex或使用mod_autoindex生成目錄列表)時(shí),子請(qǐng)求中不會(huì)繼承每個(gè)請(qǐng)求的環(huán)境變量。此外,由于mod_setenvif采取行動(dòng)的API階段,因此不會(huì)在子請(qǐng)求中單獨(dú)評(píng)估SetEnvIf指令。

使用環(huán)境變量

CGI腳本環(huán)境變量的主要用途之一是將信息傳遞給CGI腳本。如上所述,除了在Apache配置中設(shè)置的任何變量之外,傳遞給CGI腳本的環(huán)境還包括有關(guān)請(qǐng)求的標(biāo)準(zhǔn)元信息。

SSI頁(yè)面

由mod_include的INCLUDES過(guò)濾器處理的服務(wù)器解析(SSI)文檔可以使用echo元素打印環(huán)境變量,并且可以使用流控制元素中的環(huán)境變量來(lái)使頁(yè)面的某些部分以請(qǐng)求的特征為條件。如上所述,Apache還為SSI頁(yè)面提供標(biāo)準(zhǔn)CGI環(huán)境變量。有關(guān)更多詳細(xì)信息,請(qǐng)參閱SSI教程。

訪問(wèn)控制可以使用env=enny和env=directive中的deny,根據(jù)環(huán)境變量的值來(lái)控制對(duì)服務(wù)器的訪問(wèn)。與SetEnvIf結(jié)合使用,可以根據(jù)客戶端的特性靈活控制對(duì)服務(wù)器的訪問(wèn)。例如,可以使用這些指令拒絕訪問(wèn)特定瀏覽器(User-Agent)。

條件記錄可以使用LogFormat選項(xiàng)%e在訪問(wèn)日志中記錄環(huán)境變量。此外,可以使用CustomLog指令的條件形式基于環(huán)境變量的狀態(tài)來(lái)決定是否記錄請(qǐng)求。與SetEnvIf結(jié)合使用,可以靈活控制記錄哪些請(qǐng)求。例如,您可以選擇不記錄以gif結(jié)尾的文件名請(qǐng)求,也可以選擇僅記錄來(lái)自子網(wǎng)外的客戶端的請(qǐng)求。

條件響應(yīng)標(biāo)頭Header指令可以使用環(huán)境變量的存在或不存在來(lái)確定是否將某個(gè)HTTP標(biāo)頭放置在對(duì)客戶端的響應(yīng)中。例如,這允許僅在來(lái)自客戶端的請(qǐng)求中接收到對(duì)應(yīng)的報(bào)頭時(shí)才發(fā)送特定的響應(yīng)報(bào)頭。

外部過(guò)濾器激活mod_ext_filter使用ExtFilterDefine指令配置的外部過(guò)濾器可以使用disableenv =和enableenv =選項(xiàng)激活環(huán)境變量的條件。

URL重寫(xiě)RewriteCond中的%{ENV:variable}形式的TestString允許mod_rewrite的重寫(xiě)引擎根據(jù)環(huán)境變量做出決策。請(qǐng)注意,沒(méi)有ENV:前綴的mod_rewrite中可訪問(wèn)的變量實(shí)際上不是環(huán)境變量。相反,它們是mod_rewrite特有的變量,無(wú)法從其他模塊訪問(wèn)。

特殊用途環(huán)境變量

互操作性問(wèn)題導(dǎo)致引入了修改Apache與特定客戶端溝通時(shí)的行為方式。為了使這些機(jī)制盡可能靈活,可以通過(guò)定義環(huán)境變量來(lái)調(diào)用它們,通常使用BrowserMatch,例如也可以使用SetEnv和PassEnv。

downgrade-1.0這會(huì)強(qiáng)制將請(qǐng)求視為HTTP/1.0請(qǐng)求,即使它是在后來(lái)的方言中。

force-gzip

如果激活了DEFLATE過(guò)濾器,則此環(huán)境變量將忽略瀏覽器的accept-encoding設(shè)置,并將無(wú)條件地發(fā)送壓縮輸出。

force-no-vary這會(huì)導(dǎo)致在將響應(yīng)標(biāo)頭發(fā)送回客戶端之前從響應(yīng)標(biāo)頭中刪除任何Vary字段。有些客戶沒(méi)有正確解釋這個(gè)字段; 設(shè)置此變量可以解決此問(wèn)題。設(shè)置此變量還暗含著force-response-1.0。

force-response-1.0這會(huì)強(qiáng)制對(duì)發(fā)出HTTP/1.0請(qǐng)求的客戶端發(fā)出HTTP/1.0響應(yīng)。它最初是由于AOL的代理問(wèn)題而實(shí)現(xiàn)的。給定HTTP/1.1響應(yīng)時(shí),某些HTTP/1.0客戶端可能無(wú)法正常運(yùn)行,這可用于與它們進(jìn)行互操作。

gzip-only-text/html設(shè)置為值1時(shí),此變量將禁用mod_deflate為text/html以外的內(nèi)容類(lèi)型提供的DEFLATE輸出過(guò)濾器。如果愿意使用靜態(tài)壓縮文件,mod_negotiation也會(huì)評(píng)估變量(不僅適用于gzip,還適用于所有與“identity”不同的編碼)。

no-gzip設(shè)置后,mod_deflate的DEFLATE過(guò)濾器將關(guān)閉,mod_negotiation將拒絕提供編碼資源。

no-cache適用于Apache-2.2.12及更高版本。設(shè)置后,mod_cache將不會(huì)保存其他可緩存的響應(yīng)。此環(huán)境變量不會(huì)影響是否將為當(dāng)前請(qǐng)求提供緩存中已有的響應(yīng)。

nokeepalive這會(huì)在設(shè)置時(shí)禁用KeepAlive。

prefer-language這會(huì)影響mod_negotiation的行為。如果它包含語(yǔ)言標(biāo)記(例如en,ja或x-klingon),則mod_negotiation會(huì)嘗試使用該語(yǔ)言提供變體。如果沒(méi)有這樣的變體,則適用正常的協(xié)商過(guò)程。

redirect-carefully這會(huì)強(qiáng)制服務(wù)器在向客戶端發(fā)送重定向時(shí)更加小心。這通常在客戶端處理重定向的已知問(wèn)題時(shí)使用。這最初是由于Microsoft WebFolders軟件出現(xiàn)問(wèn)題而導(dǎo)致的,該軟件在通過(guò)DAV方法處理目錄資源上的重定向時(shí)遇到問(wèn)題。

suppress-error-charset

適用于2.0.54之后的版本。當(dāng)Apache發(fā)出重定向以響應(yīng)客戶端請(qǐng)求時(shí),響應(yīng)包括一些實(shí)際文本,以防客戶端無(wú)法(或不自動(dòng))遵循重定向。Apache通常根據(jù)它使用的字符集標(biāo)記此文本,即ISO-8859-1。

但是,如果重定向是使用不同字符集的頁(yè)面,則某些損壞的瀏覽器版本將嘗試使用重定向文本中的字符集而不是實(shí)際頁(yè)面。例如,這可能導(dǎo)致希臘語(yǔ)被錯(cuò)誤地渲染。

設(shè)置此環(huán)境變量會(huì)導(dǎo)致Apache省略重定向文本的字符集,然后這些損壞的瀏覽器將正確使用目標(biāo)頁(yè)面的字符集。

示例

將損壞的標(biāo)題傳遞給CGI腳本從Apache 2.4開(kāi)始,Apache對(duì)于如何在mod_cgi和其他模塊中將HTTP標(biāo)頭轉(zhuǎn)換為環(huán)境變量更為嚴(yán)格:以前,標(biāo)頭名稱中的任何無(wú)效字符都只是轉(zhuǎn)換為下劃線。這允許通過(guò)標(biāo)頭注入進(jìn)行一些潛在的跨站點(diǎn)腳本攻擊(參見(jiàn)Unusual Web Bugs,slide 19/20)。

如果您必須支持發(fā)送損壞的標(biāo)頭且無(wú)法修復(fù)的客戶端,則涉及mod_setenvif和mod_headers的簡(jiǎn)單解決方法用于仍然接受這些標(biāo)頭:

# 
# 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

改變行為不端的客戶端的協(xié)議行為

早期版本建議在httpd.conf中包含以下行以處理已知的客戶端問(wèn)題。由于不再能夠看到受影響的客戶端,因此不再需要此配置。

#
# 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

不需要在訪問(wèn)日志中記錄圖像請(qǐng)求

此示例使圖像請(qǐng)求不會(huì)出現(xiàn)在訪問(wèn)日志中。可以輕松修改它以防止記錄特定目錄,或防止記錄來(lái)自特定主機(jī)的請(qǐng)求。

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

防止圖片盜鏈此示例說(shuō)明如何防止服務(wù)器上的人員將服務(wù)器上的圖像用作其頁(yè)面上的內(nèi)嵌圖像。這不是推薦的配置,但它可以在有限的情況下工作。我們假設(shè)您的所有圖像都位于名為/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>




以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)