:::

pfSense 實作反向代理伺服器(Reverse Proxy)

2011-08-12_182742 lighttpd

最近在研究用pfSense(1.2.3版)當做路由器架設內部網路,然後利用FQDN(Fully Qualified Domain Name)透過pfSense連到內部網路中的網頁伺服器的方法。

最簡單的作法是連接埠轉遞(port forward),可是網址帶個連接埠號就是不好看。在此介紹在pfSense中設定Lighttpd的反向代理伺服器(Reverse Proxy),以FQDN連接到內部網路伺服器的作法。這方法只能適用於HTTP跟HTTPS,其他通訊協定就要另外想辦法了。


網路拓蹼狀況說明

網路拓蹼

在介紹原理跟作法之前,必須先讓人搞清楚我現在的網路拓蹼狀況。上圖是目前的網路拓蹼圖。中間的伺服器是用pfSense架設,主機名稱為pfSense,對外網卡的IP是140.119.61.254,這也是我唯一一個可以使用的公用IP(public IP)。對內的內部網卡是192.168.1.1,提供內部區域網路連線到網際網路。內部區域網路中有兩台甚至更多的伺服器,其中一台主機名稱為joomla,內部區域IP為192.168.1.20,執行我架設的joomla網站

現在我跟DNS註冊一個FQDN:joomla.example.com,對應到公用IP 140.119.61.254,也就是pfSense主機。而我要藉由設定pfSense作為反向代理伺服器,讓joomla.example.com連到joomla主機。

再回到上面的網路拓蹼圖,圖片上方是網際網路(internet)的電腦,當他想要連結到「http://joomla.example.com」時,實際上是會先連到pfSense主機,然後我們要想辦法讓pfSense主機再去存取Joolma主機,以達到我們的目標:用FQDN連到pfSense伺服器背後內部區域網路中的網頁伺服器。

達到這個目標的方法很多,其中一個方法就是將pfSense主機設置成反向代理伺服器。


反向代理伺服器(Reverse Proxy)

一般常聽到的代理伺服器(Proxy),像是在家裡要用圖書館的資料庫要先設定代理伺服器的這種,指的都是正向代理伺服器(Forward Proxy)。其運作方式為:客戶端(client)跟代理伺服器要求要下載的資料,代理伺服器先去抓好,然後再回傳給客戶端。

而本篇討論的網路拓蹼中,目標是要讓網際網路的電腦連到內部區域網路的伺服器,這個作法則是透過中間的反向代理伺服器來進行。反向代理伺服器的運作方式一樣是根據網際網路上客戶端的請求,從內部區域網路中的伺服器抓取資料,然後回傳給客戶端。

反向代理伺服器的好處有:

  1. 當網路被隔離外部與內部時,可以讓外部電腦取用內部伺服器的網站。
  2. 可以直接用FQDN來連接內部伺服器,如:http://joomla.example.com;不需要像連接埠轉遞還附帶額外的連接埠,如:http://joomla.example.com:64080/
  3. 代理伺服器可以進行快取與負載平衡的機制。

詳細的內容請參考聯成電腦的使用 Reverse Proxy代理服務

然而,跟NAT的連接埠轉遞相比之下,反向代理伺服器設定比較麻煩,還有一些額外的速度考量等缺點。

在本篇要討論的情況中,pfSense就是扮演反向代理伺服器的角色。

架設反向代理伺服器的工具很多種,網路上大家常使用的工具為SquidApache。pfSense雖然可以安裝Squid,但是Squid設定反向代理伺服器的配置挺複雜的,我沒有仔細研究。Apache的反向代理伺服器設定就很簡單,但是pfSense預設不是用Apache執行網頁伺服器,而是用Lighttpd

Vadim Tkachenko有介紹Lighttpd設定反向代理伺服器的方法,但在pfSense中操作Lighttpd的方式有點不同。在此我主要介紹的是在pfSense(1.2.3版)中設定Lighttpd作為反向代理伺服器的過程。


Lighttpd設定反向代理伺服器

現在我們要設定Lighttpd作為反向代理伺服器,而我們有個FQDN:joomla.example.com,指向pfSense主機的IP。而實際上架設joomla的主機內部IP為192.168.1.20。這些設定必須事先配置好,接下來才能開始設定反向代理伺服器。

1. 開啟pfSense的SSH連線

我大部分的操作都是用SSH進行,遠端操作比起在主機前面還要方便,要編修檔案時也可以用FileZilla以sftp來傳送,所以在此建議打開pfSense的SSH連線。

pfSense開啟SSH連線的設定是在Adcanced中的Secure Shell,請勾選「Enable Secure Shell」,再按下「Save」按鈕儲存。

2. 下載/var/etc/lighty-webConfigurator.conf

你可以利用FileZilla下載該檔案到本機電腦編輯。我一直無法習慣pfSense內建的vi編輯器,還是下載回來編輯,然後再上傳回比較方便。

3. 加入反向代理伺服器設定

接著我們編輯lighty-webConfigurator.conf這個檔案。

首先是要先額外載入mod_proxy模組,請在server.modules參數中加入"mod_proxy”。請注意以下紅字的部份,中間要相隔逗號:

## modules to load
server.modules = (

"mod_access", "mod_accesslog",
"mod_fastcgi", "mod_cgi",
"mod_proxy"

)

然後在檔案的最後插入反向代理伺服器的設定:

#### Reserve Porxy
$HTTP["host"] == "joomla.example.com" {
cache.enable = "false"
proxy.server = ( "" => ( ( "host" => "192.168.1.20") ) )
}

必須要說明的是cache.enable設定。在本篇當中,反向代理伺服器的目的不在於加速,而只是在於連結外網與內網而已。因此這邊是不使用快取,避免讀取到過期的舊檔案。

詳細的代理伺服器設定請參考Lighttpd的mod_proxy說明

修改之後,請再上傳到/var/etc/目錄,覆寫原本的lighty-webConfigurator.conf檔案。

4. 重新啟動Lighttpd服務

pfSense主機上的Lighttpd服務要重新啟動,剛剛修改的設定才會生效。但是pfSense的Lighttpd不知道是怎麼執行的,我找不到restart選項來用。所以在此我是關閉既有的Lighttpd,再開啟Lighttpd服務,來達到重新啟動的效果。

請以SSH連接到pfSense主機,然後用以下步驟來重新啟動Lighttpd。

4.1 關閉執行中的Lighttpd

pfSense預設開啟時會執行Lighttpd,我們要先把它關掉。

查詢執行中的Lighttpd的指令是ps,執行之後的結果如下,請注意紅字的執行緒編號。這個指令每次執行的結果都不同,執行緒編號也不會相同,請依據你的狀況來取得現在的Lighttpd執行緒編號:

# ps aux | grep light
root 13839 0.0 2.6 5316 3068 ?? S 12:08PM 0:05.15 lighttpd -f /var/etc/lighty-webConfigurator.conf

然後再用kill指令關閉Lighttpd,kill指令後面接的是Lighttpd的執行緒編號:

# kill 13839

這樣就關閉Lighttpd了。

4.2 開啟Lighttpd

開啟Lighttpd的方法如下:

# lighttpd -f /var/etc/lighty-webConfigurator.conf

這樣就重新啟動Lighttpd了。

不過,用kill殺掉執行緒好像會有很多問題,如果可以的話,還是重新啟動pfSense主機,這樣就能確保Lighttpd一定會重新載入。

4.3 測試 joomla.example.com

這樣就設定完成了,請試著用外部網路的電腦連到 joomla.example.com ,看看能不能連接到 joomla主機吧。

討論

反向代理伺服器可以上傳檔案

2011-08-12_202946 phpfilemanager upload 成功

反向代理伺服器看起來只是下載、轉交檔案而已,那麼像是上傳檔案這種要跟伺服器互動的操作,反向代理伺服器可以完成嗎?測試之後是可以的。

我在內部網路伺服器中架設了XAMPPphpFileManager,然後嘗試上傳檔案,結果很順利。

反向代理伺服器效能與速度的考量

由於客戶端瀏覽網站的所有動作都必須經過反向代理伺服器,因此反向代理伺服器的運作效能也不能太差,否則會拖慢網頁速度,這是他的缺點。

不過另一方面,反向代理伺服器也可以考慮設置快取與負載平衡,加快網頁的速度。這部份的設定請參考Lighttpd的mod_proxy說明

只用於HTTP跟HTTPS通訊協定

我這篇主要是用於HTTP通訊協定。

HTTPS的設定有些不同,雖然mod_proxy說明中沒有寫,不過網路上很容易可以找到相關設定說明,例如lighttpd論壇中的SLL trough reverse proxy。我對HTTPS並沒有這麼熟,也沒有急迫需求,所以並沒有動手設定。如果有人設定成功,歡迎留言分享一下作法。

至於其他通訊協定,例如SSH,好像就不是Lighttpd管轄的範圍,必須仰賴其他程式,或是直接設定連接埠轉遞比較快。


結語

網路上pfSense的討論很少提及lighttpd,而pfSense的lighttpd操作也跟一般在FreeBSD上的操作不太一樣,我為此找了好一段時間。上述方法其實並不太漂亮,特別是重新啟動Lighttpd的方法。如果有人對pfSense很熟悉的話,請務必指正我這個錯誤的方法吧!

好,繼續研究pfSense。