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)境變量。此信息可用于控制各種操作,如日志記錄或訪問控制。變量還用作與外部程序(如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)境變量的最基本方法是使用無條件的SetEnv指令。也可以使用PassEnv指令從啟動(dòng)服務(wù)器的shell環(huán)境傳遞變量。

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

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

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

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

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

一些警告

  • 使用環(huán)境操作指令無法覆蓋或更改標(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頁面時(shí),與此限制不匹配的字符將被下劃線替換。
  • 一個(gè)特殊情況是HTTP標(biāo)頭,它通過環(huán)境變量傳遞給CGI腳本等(見下文)。它們被轉(zhuǎn)換為大寫,只有短劃線被替換為下劃線;如果標(biāo)頭包含任何其他(無效)字符,則會(huì)以靜默方式刪除整個(gè)標(biāo)頭。
  • SetEnv指令在請求處理期間運(yùn)行較晚,這意味著SetEnvIf和RewriteCond等指令不會(huì)看到使用它設(shè)置的變量。
  • 當(dāng)服務(wù)器通過內(nèi)部子請求查找路徑(例如查找DirectoryIndex或使用mod_autoindex生成目錄列表)時(shí),子請求中不會(huì)繼承每個(gè)請求的環(huán)境變量。此外,由于mod_setenvif采取行動(dòng)的API階段,因此不會(huì)在子請求中單獨(dú)評估SetEnvIf指令。

使用環(huán)境變量

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

SSI頁面

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

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

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

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

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

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

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

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

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

force-gzip

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

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

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

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

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

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

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

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

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

suppress-error-charset

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

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

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

示例

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

如果您必須支持發(fā)送損壞的標(biāo)頭且無法修復(fù)的客戶端,則涉及mod_setenvif和mod_headers的簡單解決方法用于仍然接受這些標(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中包含以下行以處理已知的客戶端問題。由于不再能夠看到受影響的客戶端,因此不再需要此配置。

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

不需要在訪問日志中記錄圖像請求

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

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

防止圖片盜鏈此示例說明如何防止服務(wù)器上的人員將服務(wù)器上的圖像用作其頁面上的內(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)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)