ADJ網路實驗室
打印

[分享] R-Proxy - 使用Apache架設

R-Proxy - 使用Apache架設

參考資料:
http://www.sans.org/rr/whitepapers/webservers/302.php

作者: Duncan Lo < duncan@twn.wox.org >   -- Apache 1.3
      kefore  <kefore.bbs@bbs.sayya.org> -- Apache 2


更新日期: 2003.01.17
適用對象: 防火牆或系統管理員.
適用條件: 對 Linux 環境有基礎的管理及操作能力.
文章附註: 本篇文章為自由文件,歡迎非商業性質轉載,並請註明出處!
          商業性質轉載請來信告知!
特別注意: 1.本篇文章提供之程式及設定*不一定*符合您的環境,
            請依您的系統環境適當地修改程式及設定.
          2.在執行任何具破壞性的動作及行為前,
            請確認您已作好完整可用的資料備份工作.
          3.請把整篇文章看完再發問,謝謝!


-

  本文共分四個單元,第一單元是簡介 R-Proxy 基本觀念,及使用 Apache 架設
R-Proxy 的方法基本設定,第二單元是利用 Apache Rewrite 模組,使用 R-Proxy 設定
Web 主機的分散負載及主機容錯的功能,第三單元是探討 Apache 1.3 上的 mod_proxy
模組之安全性問題,第四個單元是由 kefore 網友提供的 Apache 2 上的 R-Proxy 架設
心得.


-

第一單元: 架設 R-Proxy


  一般的 Proxy 主機,是服務內部的 Client 上網用的,通常都是用 Squid 架設,
同時為了存取效率及節省頻寬, Squid 本身也提供 Cache 的功能,所以一般 Proxy
主機也稱為 Proxy Cache Server 代理快取伺服器.


  R-Proxy 本身也是一種代理伺服器,那個 R 代表的是 Reverse 反向的意思,
最主要的用途是反過來代理,替 Internet 的使用者代理存取內部受限制的網站,
假如有開啟 Cache 功能,它同樣可以提供 File Cache 的功能,簡單來說 R-Proxy
就像是把 Proxy 的架構及需求,反向過來,使用者角色對調的意思.詳細的介紹
可以參考最後面的 Netscape Proxy Server - Reverse Proxy 圖文.


  R-Proxy 實際應用上多與防火牆整合在一起,代理存取內部的網站,不讓外部使用者
直接存取內部受限制及保護之網站,或是將 Web 依目錄結構由數台主機來分散服務,
實測上,只要路徑及設定正確,該 R-Proxy 可以支援如html,php,asp,java及cgi程式的
Web 環境.而內部的 Web 主機可以設限只有 R-Proxy 的 IP 位置才可來存取,而一般的
Internet 使用者不行直接存取,相當於把 R-Proxy 當成一台虛的 Web 主機,相對的,
網站的安全性也提高了.


  在使用上, Proxy Cache 需要 Clien t在 IE, Netscape 內設定,或是在 Firewall
上設成通透式的Cache方式,才可以使用 Proxy Cache 的功能,但用 R-Proxy, 使用者
是完全不用作任何設定,只要 Firewall 或 Web 管理員把 R-Proxy 設好就行了.


  R-Proxy 的作法有很多種,使用 Apache 架設是目前最容易的方法,請特別注意,
以下的教學是以 TurboLinux 7 Server 及 Apache 1.3.20 作示範,你實際的環境
可能會需要作一些修改.還有以下的所說的 Proxy 是指一種功能,請不要跟 Squid 這個
作快取代理的軟體弄混了...


  首先,你要先確認你的 Apache 有 proxy 這個 modules, 通常在httpd.conf內
會有像下面兩行的 modules 設定:

    LoadModule proxy_module /usr/libexec/apache/libproxy.so
    AddModule mod_proxy.c


  確定 Apache 有 Proxy 這 modules 後,就可以開始來設定,找到下面這一段:

    <IfModule mod_proxy.c>
    </IfModule>


  在裡面加上或把某幾行的#拿掉,內容大概會像這樣:

    ProxyRequests On
    <Directory proxy:*>
       Order deny,allow
       Deny from all
       Allow from .your_domain.com
    </Directory>


  把 Allow from 修改成你予許的來源位置.接下要設定你要代理的Web主機位置,
把設定加入:

    ProxyPass  /  http://192.168.1.7/


  上面那個 / 是指 Web 根目錄,後面的網址是內部的 Web 主機位置.


  Ok!完成,可以用 Browser 連到你架的 R-Proxy 主機試試,若是 R-Proxy 架在
  Firewall 上,可能要把 httpd port 作適度的開放,但不再需要作轉 port 的動作,
你會發現,你連到 R-Proxy 主機的網頁內容就是你指定的那台 Web 主機.


  你也可以把網頁分散在不同的主機上,因為只有一個 Web 主目錄,所以可以依
Web 目錄來分,設定的方法像:

    ProxyPass /         http://192.168.1.3/
    ProxyPass /webmail  http://192.168.1.2/webmail/
    ProxyPass /sales    http://192.168.1.7/
    ProxyPass /bbs      http://192.168.1.10:8888/


  這邊有個重點,就是各主機網頁的目錄結構位置最好也是依循Web主目錄的結構,像上面
第 1 跟第 2 行執行應該不會有問題,不過第 3, 4 行,就不一定可行,因為 Web 路徑可能會
不對,特別是該目錄有又有次目錄時,因為這 R-Proxy 是作代理存取的動作,而不是作轉址的
動作,所以可能需要另外搭配 ProxyPassReverse 的指令.就像這樣:

    ProxyPass         /         http://192.168.1.3/
    ProxyPass         /webmail  http://192.168.1.2/webmail/
    ProxyPassReverse  /webmail  http://192.168.1.2/webmail/
    ProxyPass         /sales    http://192.168.1.7/
    ProxyPassReverse  /sales    http://192.168.1.7/
    ProxyPass         /bbs      http://192.168.1.10:8888/   


  這樣像 http://192.168.1.2/webmail/images 就會轉到 /webmail/images 去,
而不是 /images 這個錯誤路徑,不過還需注意的,就是次目錄的指定在網頁程式內的寫法,
還是必須以"相對位置"的方式撰寫,使用"絕對位置"的方式還是有出錯的可能.

  我測試的 Apache proxy module 是不提供輪詢的功能,所以假如你的設定是下:

    ProxyPass /         http://192.168.1.3/
    ProxyPass /         http://192.168.1.2/


  基本上,還是只有第 1 條設定生效,而且也不提供容錯的功能,所以上面設定指的第 1 台
主機掛了,網頁還是連不到的,因為它不會自動啟用第 2 條設定,這部份就必須要搭配 Apache
的 rewrite 模組或其他具有錯誤偵測的 r-rproxy 模組了.


  假如你想啟動 Cache 功能,可以參考 Apache 設定手冊,增加幾個有關 Cache 的設定,
實際使用上因為 R-Proxy 也許只代理存取內部的 Web 主機, File Cache 的異動及數量不大,
在一些較複雜及中大型的 Web 網站比較適合,你可以自己斟酌要不要使用 Cache 的功能.
相關的設定參數如下:

    CacheRoot "/var/proxy"
    CacheSize 5
    CacheGcInterval 4
    CacheMaxExpire 24
    CacheLastModifiedFactor 0.1
    CacheDefaultExpire 1
    NoCache a_domain.com another_domain.edu joes.garage_sale.com


  使用了 R-Proxy 之後,還有一點不同的地方,就是 httpd log 的內容,原本讓任何使用者直接
存取 Web 主機時, httpd log 內紀錄的是連線 Client 的 IP 位置,但使用了 R-Proxy 後, log
內紀錄的都將會是 R-Proxy 的 IP 位置,而 Client 的真實存取紀錄則會紀錄在 R-Proxy 內的
httpd log 內,所以要追查連線問題,則需要多檢查 R-Proxy 的 httpd log 內容.


  目前 R-Proxy 主機只有少數中大型網站有架設,但實際應用上, R-Proxy 是可以改善
Web 存取效能,增加實體 Web 主機的安全性,我手上的有關 R-Proxy 資料還不完整,商業產品
有很多已利用 R-Proxy 的觀念作到多線,異地的負載平衡及容錯存取,而且可以支援非 httpd
服務.而在要作到像那些產品的功能可能就要考慮以 Squid 來實作 R-Proxy 功能了...


  參考資料:
  
    1.Apache2 - module mod_proxy
      http://httpd.apache.org/docs/2.0/mod/mod_proxy.html
      https://customer.nylitc.com.tw/manual/ibm/9acdprox.htm   

    2.Netscape Proxy Server - Reverse Proxy
      http://developer.netscape.com/do ... /adminux/revpxy.htm
      
    3.IBM HTTP Server
      http://tst.sinica.edu.tw/manual/ibm/index.html
      
      
-

第二單元: R-Proxy 的分散負載及主機容錯


  在上一個單元內,可以發現基本的 R-Proxy 只能單純的依網頁目錄分散在不同的主機,
而且一個網頁目錄只能連結一台主機,當某台主機當機,該連結的網頁目錄便失效了,這種
單一靜態的分散服務及缺乏容錯機制的功能,並不是較好的 R-Proxy 功能.


  在 http://pihl.kumpu.org/mod_curltunnel.html 有提供一個 CrulTunnel 模組,它
提供類似於 ProxyPass 及 ProxyPassReverse 的指令 CrulTunnelPass 及 CrulTunnelPassReverse,
安裝 CurlTunnel 模組系統必需要有 http://curl.haxx.se/ 的 libcurl 函數,但實測後
發現, CurlTunnel 模組只是使錯誤連結的 404 錯誤訊息不再出現,還是不提供容錯的功能,
所以這也不是我們想要的.


  想要解決網頁連結錯誤的問題,必須在 URL 路徑發生問題時, Apache 就要自動辨識錯誤,
並導向正確或是錯誤訊息回應的網址,在 Apache 中就有一個提供這樣可以依條件及規則轉換
URL 路徑的模組 - Rewrite, Apache Rewrite 模組是一個功能強大的 URL 路徑維護模組,
它可以依條件,規則或外部程式,資料來轉換網頁的 URL 路徑.


  以下的測試環境,同樣是將 R-Proxy 架設在防火牆上,而防火牆內有數台 Web 主機.
  

  首先,你要先確認在你主機上有 Rewrite 模組,而且在 httpd.conf 內有類似下面的設定:

    LoadModule rewrite_module /usr/libexec/apache/mod_rewrite.so
    AddModule mod_rewrite.c


  首先,啟用 Apache Server Status 功能,找到下面這一段,把前的 # 號拿掉,並適當的修改
Allow from 的位置:
  
    <Location /server-status>
      SetHandler server-status
      Order deny,allow
      Deny from all
      Allow from .yourdomain.com
    </Location>

   
  再來,在 httpd.conf 內加入 Rewrite 模組的設定,像下面:
  
    # Rewrite
    <IfModule mod_rewrite.c>
       RewriteEngine   on
       RewriteLogLevel 0

       RewriteMap      server  rnd:/etc/httpd/conf/rproxy-server

       RewriteRule     ^/rproxy-status.*       -       [L]
       RewriteRule     ^(http|ftp)://.*        -       [F]

       RewriteRule     ^/(.*\.(cgi|shtml))$    to://${server:dynamic}/$1       [S=1]
       RewriteRule     ^/(.*)$                 to://${server:static}/$1

       RewriteRule     ^to://([^/]+)/(.*)      http://$1/$2    [E=SERVER:$1,P,L]

       RewriteRule     .*      -       [F]
    </IfModule>

   
  上面的 RewriteMap 後面是指定一個設定檔,設定檔內是所有要當作分散負載的主機群成員
位置,主機的性質有兩種,一種是只有存有靜態資料的 Static 主機,另一種是存有 cgi 及 shtml
(Server Side Include )的動態處理,假如有數台 Web 主機,就可以將它們的位置設定在上面
所指定的 rproxy-server 內,內容像下面:
  
    static  w1.test.com|w2.test.com|w3.test.com|w4.test.com
    dynamic w5.test.com|w6.test.com
  
  
  然後在 httpd.conf 內把 proxy 模組的設定加入,像下面:
  
    <IfModule mod_proxy.c>
      ProxyRequests On
      NoCache *
      ProxyPassReverse  /  http://w1.test.com/
      ProxyPassReverse  /  http://w2.test.com/
      ProxyPassReverse  /  http://w3.test.com/
      ProxyPassReverse  /  http://w4.test.com/
      ProxyPassReverse  /  http://w5.test.com/
      ProxyPassReverse  /  http://w6.test.com/
    </IfModule>

   
  再來只要重新啟動 httpd 就可以了,你可以先在這 6 台 Web 主機存放不同的網頁內容,再使用
Browser 連線測試,你可以發現網頁的內容,會在一直不斷的輪詢,若是將其中一台主機離線,再測試,
你可以發現並不會發生連線錯誤,也就是說 proxy + rewrite 的 R-Proxy 功能,除了會分散負載,
還有主機容錯的功能.


  等要正試上線時,只要定時同步這 6 台網頁主機的內容,而 cgi 動態處理部份是由於上面範例中的
w5,w6 兩台主機來處理. httpd log 部份如同第一單位所說, Client 的真實 IP 只會存在於 R-Proxy
那台的 httpd log 內,而其他所有的 Web 主機,只會記錄 R-Proxy 主機 IP 來存取.


  目前上面這些設定的環境,都是以主機同時存在同一個地方為主,要作到異地的 Web 網站平衡負載,
就要搭配 DNS Round-Robin 的方式來達成.


  利用 R-Proxy 的作法是比 Linux LVS 的作法單純而且簡單多,假如在 Rewrite 內多加一些權重的
計算及分配, R-Proxy 所以提供的功能並不會輸給 Linux LVS, 功能上主要的差別應該是 Linux LVS
可以提供多台 Cluster 的 Controler, 而且可以自動備援切換.


  參考資料:
  
    1.Apache module mod_rewrite
      http://httpd.apache.org/docs/mod/mod_rewrite.html
      
    2.Apache URL Rewriting Guide
      http://www.engelschall.com/pw/apache/rewriteguide/


-

第三單元: Apache 1.3 mod_proxy 模組安全性問題


  有許多網友跟我反應,架了 R-Proxy Server 後, Web 主機讓外人當成 Public Proxy Server 存取,
造成網路流量的突增及管理上的問題.


  我找了很多的文章及討論,用人說改用 Apache 2 的 ProxyMatch 方式,或是用 Rewrite Rules 去限制,
不過似乎都沒辦法徹底解決這個問題.有一天,我不小心才看到下面 Apache mod_proxy 網站上的一段文字:

    Warning: Do not enable proxying with ProxyRequests until you have secured your server.
      Open proxy servers are dangerous both to your network and to the Internet at large.


  意思是大概說,假如你無法保護你的主機的安全性,那請不要把 ProxyRequests 功能打開,不然可能會
影響你網路的頻寬及安全.


  於是我找了一台 FreeBSD 4.7p3 及 Apache 1.3.27 來測試,發現其實只需要下面這幾行就可以達到
R-Proxy 的功能:

    ProxyPass         /webmail  http://192.168.1.2/webmail/
    ProxyPassReverse  /webmail  http://192.168.1.2/webmail/


  然後確認下面這幾行前面加上 # 以取消 ProxyRequests 的功能:

    #ProxyRequests On
    #<Directory proxy:*>
    #   Order deny,allow
    #   Deny from all
    #   Allow from .your_domain.com
    #</Directory>


  因為 mod_proxy 還是有載入,所以 ProxyPass 的功能還是存在,只是沒有 ProxyRequests 的功能,
而且也就沒有 Cache 的支援,不過,安全性才是首要考量的,至於 R-Proxy 跟 Firewall 間的整合性問題,
可以參考下面參考資料中的第二篇文章.


  參考資料:
  
    1.Apache - module mod_proxy
      http://httpd.apache.org/docs/mod/mod_proxy.html

    2.A Reverse Proxy Is A Proxy By Any Other Name
      http://www.sans.org/rr/web/reverse_proxy.php


-

第四單元: apache 2.0.43 reverse proxy的安裝方式
          (本單元由 kefore 網友熱情提供分享)

                                                                                
tall ball的位置:
http://apache.oregonstate.edu/httpd/httpd-2.0.43.tar.gz

                                                                                
主要功能:
替 Internet 的使用者代理存取內部受限制的網站

                                                                                
安裝步驟:
                                                                           
Step 1.
wget  http://apache.oregonstate.edu/httpd/httpd-2.0.43.tar.gz


Step 2.
tar -zvxf httpd-2.0.43.tar.gz


Step 3.
cd httpd-2.0.43


Step 4.
##啟動proxy模組及安裝於/usr/local/apache2
./configure --prefix="/usr/local/apache2" --enable-proxy=shared


Step 5.
make;make install


Step 6.
##修改httpd.conf檔
vi /usr/local/apache2/httpd/httpd.conf
在裡面加W或把某幾行的#拿掉

##別忘了這一行,不然您的網頁default charset將會是ISO-8859-1
AddDefaultCharset Big5

LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_connect_module /usr/local/apache2/modules/mod_proxy_connect.so
LoadModule proxy_http_module /usr/local/apache2/modules/mod_proxy_http.so

ProxyPass        / http://192.168.2.5/
ProxyPassReverse / http://192.168.2.5/


Step 7.
#啟動apache
/usr/local/apache2/httpd -f ./conf/httpd.conf -k start





TOP

ARTERY.cn