在 Linux 各類 Server 中,主要功能為 Proxy 的 squid 是個相當知名「快取伺服器」(Cache Proxy Server)她應用在加速網頁存取功效卓著,在現代的 IT 應用中,有幾種常見的應用方式:
此類型的 Proxy Server 是放在瀏覽器客戶端前面代取(快取)資料用的,這也是最常見的應用方式,尤其是早期網際網路頻寬不像現在那樣充裕,為了節省頻寬資源往往強制要求客戶端經由 Proxy 才可以存取遠端資料(早期台灣校園網路存取外國資料需透過 Proxy Server 快取)。
至於反向(reverse)Proxy Server 則是放在網頁伺服器前面,通常是當網站網頁需求量超大時,放在 Web Server 前端用以節省 Web Server 資源的架設方式,只要是高流量、客戶端數量大的網站,一般都會架設這種 reverse Proxy 來減少 Web Server 的用量。
談到 Proxy 搭配 Linux NAT(Network Address Translation)亦有所謂的穿透式(Transparent)Proxy Server,這種方式架構出來的 Proxy 優點是可以減少瀏覽器客戶端逐一設定的繁瑣工作,這也是 Linux 常見綜合應用之一(NAT+Proxy)。
至於筆者此文中,是以基本的 squid Proxy 設定為主,接著以資安考量「目的地站台(網域名稱)」存取設定為輔,進階部份談到帳號密碼認證才能使用的 Proxy Server(單一帳號密碼檔案),最終銜接到帳號密碼由 Linux LDAP 或 Windows AD 主機管理的串接設定,實現單一登入(Single sign-on)企業環境;至於文中沒有談到的 transparent Proxy 以及 reverse Proxy 設定,就留待後續有機會再介紹。
接下來就先從基本的安裝、啟停、伺服端與客戶端設定以及觀察 log 檔案開始吧!
在我們 RHEL5 安裝好之後,預設沒有安裝 squid 套件,我們可以使用指令「yum -y install squid」就可以輕輕鬆鬆安裝好 squid 軟體。

使用指令「/etc/init.d/squid start」啟動 squid。
使用指令「chkconfig squid on」使 squid daemon 開機即啟動。
squid 聆聽的埠號預設是 3128,可使用指令「netstat -na | grep -w 3128」來觀察有在聆聽(LISTEN)的狀態。
設定檔 squid.conf 中 http_port 定義聆聽埠號 3128,可使用指令「grep ^http_port /etc/squid/squid.conf」來觀看設定。
指令「ps ax | grep squid」則可以看到 squid 正在運行中。


以下是以 firefox 為例,來說明如何設定網頁瀏覽器經由 squid Proxy 快取存取網頁。
在 firefox「偏好設定」對話框中,設定 firefox 如何連線到網際網路,將代理伺服器(Proxy)改成手動設定 Proxy 至 172.18.0.183(暨 Proxy Server IP 位址或是主機名稱),連接埠欄位則是填上先前的預設值 3128 埠。

對於來自外部客戶端的存取要求,一概都是拒絕的狀態。因此當我們設定好另一台電腦 firefox 以這台 squid 當作 Proxy 後,應該會看到如下的拒絕畫面(Access Denied),這是 squid 預設的安全性設定。

我們可以從 /etc/squid/squid.conf 檔案的內容中的兩個段落,了解到 squid 預設值只允許來自 localhost 來存取 Proxy Server 的來龍去脈。
在 squid.conf 設定檔中搜尋關鍵字「localhost」會找到一堆 acl 開頭的這個段落,此段落主要定義 localhost 這個名稱的 src(來源 IP)是 127.0.0.1/255.255.255.255。

繼續在這個檔案搜尋「localhost」字眼,會找到「http_access allow localhost」(允許 localhost)緊接著「http_access deny all」拒絕全部,這就是預設值只允許客戶端來自 127.0.0.1(localhost)並拒絕其他全部連線的原因。

接下來我們就是要設定 squid.conf 允許特定網段使用我們這台 Proxy Server。
編輯 squid 設定檔案 /etc/squid/squid.conf 依照在上一個段落中所得知的基本概念,模仿這個段落註解的那兩行設定「acl our_networks src 192.168.1.0/24 192.168.2.0/24」、「http_access allow our_networks」來新增我們需要的兩行。
第一行是 acl 定義的部份,與「acl localhost src 127.0.0.1/255.255.255.255」那一行相當地類似,增加「acl our_networks src 172.18.0.0/18」這一行,其中 our_networks 只是一個名稱,不要與其他 acl 名稱重複即可,後半則是設定 Windows/Linux 瀏覽器主機(客戶端)的來源 IP(筆者使用 172.18.0.0/18 暨 172.18.0.0/255.255.192.0)。
第二行則是 http_access 設定允許拒絕的部份,與「http_access allow localhost」那一行相當類似,新增「http_access allow our_networks」(our_networks 就是第一行 acl 定義的名稱)設定時需特別注意到順序,必須要在「http_access deny all」那行之前,不然還是會被 deny all 的設定優先拒絕掉。

接著使用指令「/etc/init.d/squid restart」重新啟動 squid 後,來到瀏覽器客戶端測試是否運作正常。
觀察 squid 的 log 檔案可以讓我們察知一些事情,例如:哪些主機(或帳號)使用我們的 Proxy 存取哪些站台、squid 運作正常與否以及 squid Cache 下來了哪些資料。
預設值 squid log 放在 /var/log/squid/ 目錄下,最常觀看的當屬 access.log 也就是存取紀錄檔,使用指令「tail -f /var/log/squid/access.log」是個相當方便『即時更新』的方式(按下 Ctrl-c 離開)。
另外兩個檔案:一個是 cache.log 記載 Server 啟停訊息,遇到 squid Server 出狀況時,可查看此檔案對於解決問題很有幫助;store.log 則是記載 Cache 下來哪些資料以及放在何處等等。

Proxy 早期應用主要是『加速存取』較多,主要是因為以前網路頻寬沒有現代來的充裕,近年來對於資訊安全的意識抬頭,亦有將 Proxy 應用在『限制』客戶端存取某些特定站台的作法。
舉例來說,企業通常不希望員工上班期間存取下列類型網站:像是求職、色情、外部信箱等等,接著我們以網站(網域)babyface.com.tw 為例,來設定阻擋客戶端無法存取這個網域結尾的站台。
這次在設定的時候,重要的關鍵字在於『dstdomain』這個是「目的地網域名稱」的意思,所以在 squid.conf 中,加上「acl babyface dstdomain .babyface.com.tw」這行 acl 定義 babyface 這個名稱代表著欲存取「目的地網域名稱」為 babyface.com.tw 結尾的站台,接著「http_access deny babyface」設定成拒絕,還是要特別注意 http_access 允許拒絕行次之間是帶有順序的(更改設定後在測試前,記得重新啟動 Daemon)。

中小企業越是講究資訊安全的,對於 Web Proxy 應用越是嚴謹,對於管理方面的要求可能不單單只是某些網站不能去而已(就像先前的範例一樣),還有一個常用的方式就是必須要有帳號密碼登入成功後,才可以存取網頁網站。
至於 squid 在帳號密碼認證這方面的應用,可以使用獨立的一個檔案當成帳號密碼列表(這與 Apache 設定成存取某些網頁需要帳號密碼類似):也可以將帳號密碼丟給 LDAP Server 或 Windows AD Server 認證後存取網頁,用來實現單一登入(Single sign-on)企業環境。
欲開啟帳號密碼認證功能,需要設定一行 acl 列表,以 squid.conf 設定檔內建範例:「acl password proxy_auth REQUIRED」那一行將註解去掉即可。

接下來是設定『使用本機檔案的帳號密碼認證方式』,在設定檔案搜尋「auth_param」關鍵字,會找到一行註解「auth_param basic program /usr/libexec/ncsa_auth /usr/etc/passwd」意思是使用 ncsa_auth 程式讀取 /usr/etc/passwd 這個密碼檔案來作認證。
我們模仿上述設定加上稍做修改的一行「auth_param basic program /usr/lib/squid/ncsa_auth /usr/etc/passwd」至於密碼檔案 /usr/etc/passwd 預設值理應不存在的,待會要使用 httpd 套件內的 htpasswd 指令做出來即可。

上述設定檔內的註解範例將 ncsa_auth 的路徑寫成 /usr/libexec/ncsa_auth 但在 RHEL5 系統內並不在那邊,我們使用指令「locate ncsa_auth」或「find / -name "*ncsa_auth*」把正確的路徑找出來(我們加上去的設定,路徑名稱記得要寫對)。


為了安全起見,我們使用獨立的帳號密碼檔案「/usr/etc/passwd」就會用到指令「htpasswd」來製作這個檔案的內容,htpasswd 不屬於 squid 套件而是放在 httpd(Apache)套件內,安裝 httpd 套件只要使用指令「yum install httpd」即可安裝成功。這個 htpasswd 指令 -c 選項用於第一次建立檔案用的(意思是建立第二個帳號不用 -c 選項)
使用指令「htpasswd -c /usr/etc/passwd foo」建立檔案 /usr/etc/passwd 帳號 foo
使用指令「htpasswd /usr/etc/passwd foo2」建立下一個帳號 foo2 於 /usr/etc/passwd 檔案列表。

最後還是要到 http_access 那個段落,啟用 acl 名稱為 password 那個需要帳號密碼驗證的族群,例如:「http_access allow password」(再次提醒:這裡的『順序』很重要),當然最終免不了的需要重新啟動 squid 以及網頁瀏覽器測試。

稍具規模的中小企業有可能已經建置好 LDAP 伺服器,假設帳號密碼是由這台 LDAP Server 統一管理的話,我們在 squid 就可以將身份驗證的工作,轉交給 LDAP Server 來處理,如此只需管理一份帳號密碼就可以了。
在 squid 套件中有個 squid_ldap_auth 程式主要就是用來跟 LDAP Server 身份驗證用的;在他的說明文件「man squid_ldap_auth」範例(example)那一段落,有簡介著如何與 LDAP Server 銜接的相關設定。

筆者大致上是模仿中間的那個範例,測試出來執行成功的設定如下:
「auth_param basic program /usr/lib/squid/squid_ldap_auth -b "dc=aaa,dc=com" -h ibm5500 -f "uid=%s"」
-b 選項:連接使用「dc=aaa,dc=com」這個 baseDN
-h 選項:連接到「ibm5500」這台 LDAP Server 驗證(也可以用 IP 代替主機名稱)
-f 選項:針對「uid」這個 attribute 的 value 做驗證

筆者於 LDAP Server 上建有帳號 geeko 在瀏覽器身份驗證成功後,會在 squid log 留下 geeko 相關訊息。(下圖為身份驗證畫面)


相關 log 如下圖所示,此為執行指令「grep -w geeko /var/log/squid/access.log」結果(因為登入帳號為 geeko)。

功能強大的 AD Server 說穿了也是以 LDAP 為基礎,只是他跟 openldap 對於資料存取的預設值有些不太一樣,比較明顯的是 AD 需要先行認證才能存取 LDAP 資料,而 openladp 預設卻是允許匿名存取的。為了要設定 Proxy 去找 AD 做身份認證,我們就先在 AD Server 上新增一個 squid 帳號、密碼 test 待會要用來給 squid Proxy 存取 AD Server 身份驗證用的。
在先前 man page 範例(example)後半段,有介紹到如何調整 squid 去找 AD Server 做身份認證的設定。

至於筆者設定的範例介紹如下:
「auth_param basic program /usr/lib/squid/squid_ldap_auth -P -R -b "dc=synage,dc=com,dc=tw" -D "cn=squid,cn=Users,dc=synage,dc=com,dc=tw" -w "test" -f "(&(userPrincipalName=%s)(objectClass=Person))" -h 172.18.0.54」
-b 選項:連接使用「dc=synage,dc=com,dc=tw」這個 baseDN
-D 選項:使用 DN 為「cn=squid,cn=Users,dc=synage,dc=com,dc=tw」這個帳號先行登入
-w 選項:使用 DN 為「cn=squid,cn=Users,dc=synage,dc=com,dc=tw」這個帳號先行登入時,所用的密碼為 test

-h 選項:連線到「172.18.0.54」這個 IP 的 AD Server
-f 選項:這裡的 userPrincipalName 使用 LDAP 指令查出來格式是類似 e-mail 格式(暨 user@domainname)

在重新啟動 squid 後,瀏覽器登入時的畫面,帳號需使用「user@domainname」的方式。

在成功登入後,一樣的在 squid log 裡面有著 user@domainname 瀏覽哪些網頁資料。
