Apache的proxy指令

日期:2008-07-11  作者:喜騰小二  來源:PHPChina


apahce可以配置為proxy使用,涉及的模組為mod_proxy.so,mod_proxy_connect.so, mod_proxy_http.so和mod_proxy_ftp.so.其中mod_proxy.so是開啓後麵三個功能的基本模組,如果需要開通proxy功能,則mod_proxy.so必須加入到apache的執行空間中。在win平臺下,對apache一般都是采用二進位檔案進行的直接安裝,此時這些.so模組都已經編譯完成,並安裝在apache主目錄的modules檔案夾中。在linux/unix中,一般采用程式碼包編譯的方式進行安裝,在進行configure配置的時候需要把上述模組編譯進apache的核心模組中,或者編譯成DSO的形式動態調用。基本配置步驟:在完成上述步驟後,主要的工作就是修改apache的http.conf這個配置檔案了。在http.conf中移除下麵四條陳述式的#,apache啓動時進行dso模組的載入:LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
mod_proxy.so必須有效.根據不同的使用目的,可以有選擇性的使用後麵三個dso的功能。connect.so 提供對 HTTP 的 CONNECT 方法的支援,主要用於處理 透過代理伺服器的隧道 SSL 請求。http.so 提供代理HTTP請求的功能。但不提供任何快取的能力,快取功能需要mod_cache模組提供。ftp.so 提供代理ftp請求的功能。然後在http.conf中加入 ProxyRequest On 這麼一句話,啓動apache,此時的apache就可以俱有proxy的功能了。訪問控制配置:對proxy的訪問控制是透過和ProxyBlock兩個指令來實現的.指令對特定的使用者進行限定,ProxyBlock則是全域設定,對所有使用者都起作用。例子如下。
Order allow,deny
Allow from all
Deny from 127.0.0.1
此配置的意思是,允許除本機電腦之外的所有電腦訪問代理。http://www.google.com/>
Order deny,allow
Deny from all
Allow from 127.0.0.1
http://www.yahoo.co.jp/r/*>
Order allow,deny
Allow from all
Deny from 127.0.0.1
的意思是,僅允許本機電腦訪問http://www.google.com/,並且禁止本機電腦對於http://www.yahoo.co.jp/r/下的資源的訪問。
ProxyBlock的作用是設定對所有使用者都起作用,如
ProxyBlock microsoft co.jp www.google.com組織所有使用者透過proxy訪問俱有microsoft, co.jp, www.google.com特徵的網址。用Apache Proxy的指令改進LAMP安全性

在本文中,Nick Maynard 描述了一種使用 Apache 的 mod_proxy 模組改進 LAMP 設定的安全性的方法。本文專門針對 Linux;但是,也可以將一些原理應用於其他操作係統。

Apache Software Foundation 的 HTTP 伺服器項目(通常稱為 Apache)是當今網際網路上占據優勢的 Web 伺服器,它占據了 60% 以上的市場份額。Apache 伺服器是日漸流行的 LAMP 軟體配置的一部分。LAMP 是一套免費軟體程式,是在 Linux®、Apache、MySQL 和 PHP 等開放源碼技術之上建置的 Web 平臺。在本文中,您將學習一種使用 mod_proxy 模組和多個後端伺服器來改進 LAMP 安全性的方法。我將討論這種方法的優點和缺點,並提供一個配置範例。

PHP 和 Apache:安全性難題

LAMP 管理員麵對的一個挑戰是,提供完整 PHP 係統的所有特性,同時確保為係統的所有使用者提供一個安全的環境。使用 PHP 的安全模式是實現這一目的的一種技術,但是它也過度地限制了使用者,而且啓用了這個設施之後,一些 PHP 應用程式就不能發揮作用。

PHP 安全問題的根源在於大多數 Apache 伺服器的配置方式。因為大多數 Apache 配置執行在特殊的 www-data 使用者 ID 下,對 Web 站點進行主機託管的所有使用者在預設情況下必須確保這個使用者可以讀取他們的檔案。因此,係統上的所有其他使用者都可能訪問一個使用者的所有 Web 可訪問檔案;所以係統上原本與您無關的安全漏洞會成為攻擊您的 Web 站點的突破口。如果檔案或目錄必須設定為 www-data 使用者可寫的,那麼這種情況會更加嚴重。

透過使用 CGI 程式,比如用 Perl 和 Python 等流行語言編寫的程式,可以在使用 suEXEC 機制時消除這個問題的部分影響。簡單地說,suEXEC 使用一個特殊的中間程式以程式所有者的使用者 ID 執行 CGI 程式。(更多細節請參見 參考資料 中文章的連結。)這是一種非常有效的機制,已經使用了許多年了。

但是,在使用 mod_php 模組主機託管時,PHP 页面作為 Apache 主處理序的一部分執行。因此,它們繼承 Apache 處理序的所有憑證,而且它們在檔案係統上執行的任何工作必須作為 www-data 使用者執行。

在多個使用者 ID 下執行 Apache

對於上麵描述的問題,明顯的解決方案是要求對一個使用者域的所有請求都來自一個隻擁有此使用者的憑證的 Apache 實例。可以將 Apache 配置為在啓動時獲取任何使用者的憑證。對於給每個使用者分配一個單獨的網際網路可見 IP 地址/連接埠組合的簡單設定,這種方法可以解決問題。

對於更復雜的設定(在其中 IP 地址很寶貴),這種方法是無效的。當單一 Apache 實例可以控制一個特定的 IP 地址/連接埠組合時,隻能使用虛擬主機,這是 Apache 係統中廣泛使用的一種技術。這就排除了讓屬於多個使用者的多個域使用同一個 IP 地址/連接埠組合的可能性。

Apache 2.0 引入了多處理模組(multiprocessing module,MPM) 的概念。在基本 Apache 2.0 包提供的 MPM 中有一個實驗性的模組 perchild,它可以將一個分佈器執行緒分配給 IP 地址/連接埠組合,並將請求傳遞給在單獨使用者的憑證下執行的子執行緒,從而實現多個使用者 ID 下的虛擬主機。遺憾的是,perchild 仍然是實驗性的,它不一定能夠發揮作用,而且在 Apache 2.2 發佈時從正式 Apache 發行包中移除了。在此之前,由於認識到仍然需要一個穩定的能夠發揮作用的與 perchild 相似的 MPM,Apache 社區開始研發許多 MPM 來彌補這一欠缺。MetuxMPM 以及麵嚮過程的 peruser 正在朝着這個方嚮努力。(關於 MetuxMPM 和 peruser MPM 的更多資訊,參見 參考資料)。

一個解決方案:mod_proxy

儘管還沒有正式的 Apache MPM 能夠直接提供多個使用者 ID 下的虛擬主機,但是仍然可以透過某些配置和管理在 Apache 係統中實現這種行為。這種方法的核心概念是使用 mod_proxy 模組,這個模組(加上其他功能)使 Apache 能夠將页面請求轉發給其他伺服器,並將回應傳遞回原來發出請求的客戶機。

清單 1. 基本請求轉發的反嚮代理配置範例:

ProxyRequests Off

ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar

清單 1 中的程式碼是一個簡單的範例,它將對一個主機的 /foo 層次結構下任何页面的請求轉發到 http://foo.example.com/bar 的對應页面。例如,對 /foo/index.htm 页面的請求會轉發到 http://foo.example.com/bar/index.htm。可以使用這一原理解決問題。

範例場景

我們來考慮一個場景:Apache 管理員必須為兩個單獨的客戶建立兩個域。一個客戶是線上創業企業,很關注線上安全性。另一個是個人客戶,他在站點安全性方麵比較寬鬆,可能將不安全的程式碼上載到這個站點。因此,Apache 管理員必須采取措施將這兩個站點隔離開。

因此,管理員有兩個域:www.startup.tld,它屬於線上創業企業(使用者 ID startup);以及 www.reckless.tld,它屬於個人(使用者 ID nimrod)。為瞭解決這個問題,管理員決定使用 mod_proxy 解決方案。管理員給每個使用者一個單獨的 Apache 實例,這個實例執行在使用者自己的使用者 ID 下,使用私有的 IP 地址/連接埠組合,並使用 mod_proxy 解決方案透過一個 facade 伺服器提供對這兩個使用者的域的訪問,這個伺服器作為 www-data 執行,使用一個公共的 IP 地址/連接埠組合。圖 1 幫助了整個場景。

圖 1. 場景範例

推薦的 Apache 版本

對於範例應用程式配置中的每個元素,Apache 管理員應該使用 表 1 中列出的 Apache 版本。

後端 Apache 實例的配置

清單 2 和 清單 3 中的程式碼片段幫助了與標準 Apache 配置的基本差異。應該根據需要將它們新增到適當的配置中,比如這裡略過的 PHP 功能配置。

清單 2. 線上創業企業的 Apache 配置:

# Stuff every Apache configuration needs
ServerType standalone
LockFile /var/lock/apache/accept.startup.lock
PidFile /var/run/apache.startup.pid

ServerName necessaryevil.startup.tld
DocumentRoot "/home/startup/web"

# Essential modules
LoadModule access_module /usr/lib/apache/1.3/mod_access.so

# Which user to run this Apache configuration as
User startup
Group startup

# This must be off else the host isn't passed correctly
UseCanonicalName Off

# The IP/port combination to listen on
Listen 127.0.0.2:10000

# Using name-based virtual hosting allows
you to host multiple sites per IP/port combo
NameVirtualHost 127.0.0.2:10000

ServerName www.startup.tld

# You can add aliases so long as the facade server is aware of them!
ServerAlias startup.tld

DocumentRoot "/home/startup/web/www.startup.tld"

Options Indexes FollowSymLinks MultiViews ExecCGI Includes
AllowOverride All
Order allow,deny
Allow from all

清單 3. 個人客戶的 Apache 配置

# Stuff every Apache configuration needs
ServerType standalone
LockFile /var/lock/apache/accept.nimrod.lock
PidFile /var/run/apache.nimrod.pid

ServerName necessaryevil.nimrod.tld
DocumentRoot "/home/nimrod/web"

# Essential modules
LoadModule access_module /usr/lib/apache/1.3/mod_access.so

# Which user to run this Apache configuration as
User nimrod
Group nimrod

# This must be off else the host isn't passed correctly
UseCanonicalName Off

# The IP/port combination to listen on
Listen 127.0.0.2:10001

# Using name-based virtual hosting allows you
to host multiple sites per IP/port combo
NameVirtualHost 127.0.0.2:10001

ServerName www.reckless.tld

# You can add aliases so long as the facade server is aware of them!
ServerAlias reckless.tld

DocumentRoot "/home/nimrod/web/www.reckless.tld"

Options Indexes FollowSymLinks MultiViews ExecCGI Includes
AllowOverride All
Order allow,deny
Allow from all

清單 4. 門麵 Apache 實例的 Apache 配置

# Stuff every Apache configuration needs
LockFile /var/lock/apache/accept.www-data.lock
PidFile /var/run/apache.www-data.pid

ServerName necessaryevil.facade.server
DocumentRoot "/home/www-data"

# Essential modules
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so

# Which user to run this Apache configuration as
User www-data
Group www-data

# These must be set else the host isn't passed correctly
UseCanonicalName Off
ProxyVia On
ProxyRequests Off
# This must also be set, though it's only an option in Apache2
ProxyPreserveHost On

# The IP/port combination to listen on
Listen 9.20.1.1:80

# Using name-based virtual hosting allows
you to host multiple sites per IP/port combo
NameVirtualHost 9.20.1.1:80

# Configuration to forward requests for startup.tld
ServerName www.startup.tld
ServerAlias startup.tld

ProxyPass / http://127.0.0.2:10000/
ProxyPassReverse / http://127.0.0.2:10000/
ProxyPassReverse / http://www.startup.tld:10000/
ProxyPassReverse / http://startup.tld:10000/

# Configuration to forward requests for reckless.tld
ServerName www.reckless.tld
ServerAlias reckless.tld

ProxyPass / http://127.0.0.2:10001/
ProxyPassReverse / http://127.0.0.2:10001/
ProxyPassReverse / http://www.reckless.tld:10001/
ProxyPassReverse / http://reckless.tld:10001/
一定要注意這裡的 ProxyPreserveHost 指令。這個指令是 Apache 2 提供的,它解決了將正確的 HTTP 頭轉發給後端伺服器的一些問題。因此,強烈建議使用 Apache 2 實例作為 facade 伺服器。
 
執行範例配置
根使用者應該執行每個配置。Apache 將取得配置檔案中指定的特權,並將其用於所有與主機相關的處理序。 清單 5. 啓動範例伺服器
 
/usr/sbin/apache -f /etc/apache/startup.tld.conf
/usr/sbin/apache -f /etc/apache/nimrod.tld.conf
/usr/sbin/apache2 -f /etc/apache2/facade.tld.conf
mod_proxy 方法的限制
一定要注意,本文中描述的方法不適用於需要 SSL 連線的域。這是因為 SSL 協定不允許域的虛擬主機。由於這個限制,任何 SSL 主機必須以適當的方式執行,讓每個 SSL 域使用它自己的 IP/連接埠組合。這個限制對所有 Apache 配置都存在,使用這個解決方案的 Apache 也不例外。仍然可以在它們的所有者的使用者 ID 下執行 SSL 域。
結束語

在本文中,使用 Apache 的 mod_proxy 模組建置了一個環境,在這個環境中有一個門麵伺服器將請求轉發給兩個後端伺服器。可以對一係列後端伺服器采用同樣的方法。這種方法使係統管理員能夠降低潛在的安全風險,同時保持 PHP 等工俱提供的靈活性

<<<返回技術中心

技術文章

站內新聞