1 頁 (共 1 頁)

簡易 Proxy Server 設定與 NAT 的整合

發表於 : 2010-05-10 09:48:24
yehlu
http://kevingt.wordpress.com/2009/08/24 ... %E5%90%88/



[ Server 端環境:CentOS 5.3 ]

[ Client 端環境:Fedora Core 10、Windows Server 2003 R2、Windows XP ]

[ Switch:D-Link DES-1005D 5-port switch ]



應用代理伺服器 ( Application Proxy Server ) 簡稱 Proxy Server,它的原理就是以類似代理人的角度去取得使用者所需要的資料。也就是介於 client 端瀏灠器以及 web site 之間的伺服器,提供資料暫存以及與其他 Proxy Server 交換資訊的服務。也可以透過代理伺服器來額外的達成防火牆的功能。此外,也可以藉由 Proxy 來達成節省頻寬的目的,以及加快內部網路的 WWW 存取速度。Proxy 對於大型企業來說,實在是一個很不錯用的伺服器。


Proxy 運作原理

Proxy Server 的 client (用戶端)發 出 request 時, 會 先 連 到 Proxy Server,Proxy Server 在接 到 client 端 的 要 求 時,會去連接遠端的機器,把那邊的資料抓回來存在自己的硬碟上,再把這份資料傳給 client。 如下所示:



fig5

乍看之下好像多了一道手續,即要在 proxy 上存一份,又要再把它送給 Client 端?其實若是這份資料在很遠的地方需要極長的時間才能傳回來的話,那麼這多存一份的 overhead 就可以忽略。當其他的 Client 或許也想要這份資料,那麼這個 Client 第一步當然是向 Proxy 要求了。Proxy Server 接到要求,首先會檢查一下看看自己的 Cache 中有沒有這份資料,而不必急著將這個要求往外送。若是所要求的資料剛好有別人要求取得過,而且有存在硬碟上,那就不必再大老遠地 向遠端請求,只要把這份資料回給 Client 端就好了。要是這個 request 的資料不在 Cache 之中,Proxy 則會去遠方取回資料後,自己留一份,再送給 Client 端一 份,如下圖:

fig6



代理伺服器的用途

1. 資料的暫存與交換:Proxy 最主要的用途當然就是做為網頁資料取得代理人,也就是說, Proxy 可以幫我們取得 Internet 上面的 WWW 資料。那麼能不能取得其他非 WWW 的資料呢?那就不一定了,要看 Proxy 主機是否有設定該服務。一般來說, Proxy 主要還是針對 WWW 網頁的代理取得。

2. 權限控管與封包過濾:以 squid 而言,所能做的限制是來源與目的起的位址。因此,它對於封包過濾的功能雖不算強大,但已經夠用,且其方便的設定,可讓管理者便於管理。

基本上,我們可以透過 Proxy Server 控制來源與目的地的位址。換句話說,對內,我們可以限制哪些機器可以連到外部。對外,我們口以限制哪些網站可以被讀取。



squid server 使用的埠號

TCP 3128



伺服器位址

本次示範的 squid server 位址為:192.168.100.1



設定檔說明

在 squid.conf 設定檔內最常看到的就是 acl 這個設定項目。他是整個 squid.conf 最重要的部份!很多的來源與目的管制都是靠他來設定完成的。語法為:

<acl> <acl 名稱> <acl 類型> <設定的內容>



<acl名稱> 可以想成是一個暱稱,就只是一個代名詞而已。

<acl 類型> 可分為:

以來源端來控制:

* src  ip-address/netmask:主要控制『來源的 IP 位址』,例如『acl nckuip src 140.116.0.0/16』,這表示未來在 squid.conf 裡面,任何使用到 nckuip 這個代名詞時,就表示他是『來源為 140.116.0.0/16 的位址』。
* src addr1-addr2/netmask:主要控制『一段範圍來源的 IP 位址』,例如『acl nckuevoffice src 140.116.44.120-140.116.44.130/24』就表示 nckuevoffice 這個代名詞為來自 140.116.44.120 到 140.116.44.130 之間這 11 個 IP 的要求!』請注意,是『來源』喔!
* srcdomain .foo.com:主要控制『來源為一某個網域的電腦』的意思,例如:『acl vbirdhome srcdomain .vbird.org』,與 src 很類似,都是控制來源的用戶端,只不過 src 控制的是 IP 而 srcdomain 則是控制 domain name。

 
以目的端來控制:

* dst ip-address/netmask:主要控制『目的端的 IP 位址』,與 src 類似,只不過是用來控制『目的端』的位址。
* dstdomain .foo.com:用來控制『目的端的網域』,與 srcdomain 類似。

 
以正規表示法的方式來控制:

* url_regex [-i] ^http:// :除了上面兩種基本的方法之外,我們也可以使用正規表示法的方式來控制『網域』的設定值。例如『 acl urlname url_regex ^http://linux\.vbird\.org.* 』這表示 urlname 代表的就是來自 http://linux.vbird.org 這個網站的『任何資料』,因為『 .* 』代表任意字元的意思。如果僅只是一些檔名,例如 gif 這一類的檔名時,就可以底下的說明方式設定。
* urlpath_regex [-i] \.gif$:上面提到的是關於整個網址的名稱,這裡則是只要『URL 部分相同』就可以了。例如『acl gifname urlpath_regex \.gif$ 』則是代表 gifname 代表的是 url 後面是 .gif 的網址,那就是 gif 的圖檔附檔名。



編輯 /etc/squid/squid.conf 設定檔

#Recommended minimum configuration per scheme:
#auth_param negotiate program <uncomment and complete this line to activate>
#auth_param negotiate children 5
#auth_param negotiate keep_alive on
#auth_param ntlm program <uncomment and complete this line to activate>
#auth_param ntlm children 5
#auth_param ntlm keep_alive on
#auth_param digest program <uncomment and complete this line>
#auth_param digest children 5
#auth_param digest realm Squid proxy-caching web server
#auth_param digest nonce_garbage_interval 5 minutes
#auth_param digest nonce_max_duration 30 minutes
#auth_param digest nonce_max_count 50
#auth_param basic program <uncomment and complete this line>
#auth_param basic children 5
#auth_param basic realm Squid proxy-caching web server
#auth_param basic credentialsttl 2 hours
#auth_param basic casesensitive off <== 在此行之後新增底下 new added 裏的設定:


#############new added###############
# 此為提供密碼認証功能的設定值,能避免主機成為跳板
auth_param basic program /usr/lib/squid/ncsa_auth /etc/squid/passwd
###################################

#Recommended minimum configuration:
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT <== 在此行之後新增底下 new added 裏的設定:

######################new added#######################
# 此為提供密碼認証功能的設定值,能避免主機成為跳板
acl password proxy_auth REQUIRED
####################################################

######################new added#######################
# 此為應用層防火牆功能,可增加對網站瀏灠的控管設定,如要啟用相關的限制,前面的 # 號要拿掉
#sexip 乃控管色情 ip
#sexdn 乃控管色情 domain name
#sexurl 乃控管特殊網址
#sextag 乃控管特殊不當字眼
#acl sexip src 『/etc/squid/sexip』 <== ip 位址的控管,此檔案的內容要自已新增
#acl sexdn dstdomain 『/etc/squid/sexdn』 <== 網域名稱的控管,此檔案的內容要自已新增
#acl sexurl url_regex 『/etc/squid/sexurl』 <== 特定網址、連結的控管,此檔案的內容要自已新增
#acl sextag urlpath_regex 『/etc/squid/sextag』 <== 特殊字眼控管,此檔案的內容要自已新增
#acl kevin src 122.117.92.8
#acl kevin02 src 122.117.92.169
#http_access deny sexdn <== 如要啟用此限制,前面的 # 要拿掉
#http_access deny sexip <== 如要啟用此限制,前面的 # 要拿掉
#http_access deny sexurl <== 如要啟用此限制,前面的 # 要拿掉
#http_access allow sextag <== 如要啟用此限制,前面的 # 要拿掉

#http_access allow kevin
#http_access deny kevin02
####################################################



##########new added#############
# 此為提供密碼認証功能的設定值,能避免主機成為跳板
http_access allow password
##############################




『/etc/squid/sexurl』 檔設定範例

假設我們要限制瀏灠 google 的網站及一些特定的連結時,只要在 sexurl 檔內新增以下幾行即可:

^http://www\.google\.com*
/adv/.*\gif$
/[Aa] ds/.*\.gif$

這是限制瀏灠特定的網址及連結的意思。




『/etc/squid/sextag』 檔設定範例

如果要限制 client 端下載 mp3 及 mpeg 檔,在 sextag 檔內新增以下幾行即可達成:

\.[Mm] [Pp] 3$
\.[Mm] [Pp] [Ee] [Gg]

這邊是以控管瀏灠的檔案為主。[Mm]的意思是 M 或是 m,換言之,[Mm] [Pp] 3 會過瀘 mp3、Mp3、mP3、MP3。





基本上只要依照以上的設定, 簡易的 squid server 認証功能就算設定完成了,當然這裏面的參數還是要依您的環境去設定。如果要啟用某些限制功能的話,只要將前面的 # 號拿掉再去設定規則即可。





重新啟動 squid 服務

因為有動過設定檔,所以記得一定要重新啟動 squid server

[root@linus ~]# service squid restart



再來就是在 /etc/squid/passwd 內新增信任的使用者及密碼,如下:

[root@linus ~]# htpasswd -c /etc/squid/passwd kevin
New password: <=== 輸入密碼
Re-type new password: <=== 再次輸入密碼
Adding password for user kevin

這樣就新增了 kevin 這位使用者了。



測試畫面

squid1



為何會出現無法顯示網頁的畫面呢?那是因為我們已啟動 squid server,並且設定上網必須經過認証才能瀏灠網頁,所以必須先到瀏灠器裏的:工具–>網際網路選項–>連線–>區域網路設定,在 Proxy 伺服器欄位輸入伺服器的 IP 及連接埠之後才能正常瀏灠網頁,如下:

4



設定以上的資料後,client 端要連線上網時,就會出現認証的對話框,如下:

1



輸入正確的使用者名稱及密碼後,即可正常上網,如下:



squid4





以下再介紹 『增加對使用時間的控管』 方式:

系統對 weekday 的定義如下:

S:Sunday M:Monday T:Tuesday W:Wednesday H:Thursday F:Friday A:Saturday

假設要讓使用者只能在星期一二三四五的早上九點到下午五點透過 proxy 連外,其它時間不能連線,請在 /etc/squid/squid.conf 當中新增一行:

acl restricted_weekdays time MTWHF 9:00-17:00

如下所示:

acl testhost src 10.13.16.0/255.255.255.0
acl restricted_weekdays time MTWHF 9:00-17:00
http_access allow testhost restricted_days




NAT 與 Proxy 整合

有了 NAT 伺服器,就可以讓使用連線到外部,那又為何要增加 Proxy Server 呢?主要是避免資料重複取得、以為權限的控管、與記錄的查詢。

在連線的管控上,我們可以透過 iptables 來做完善的控制,但 iptables 的封包過瀘功能無法限制 web server 上較細部的管控,如檔名的控制、或是網址上特定的字元,這在 proxy 上都可以輕鬆的設定。如上面設定檔的方式。

以下所提到的是如何在不影響使用者的狀態下,將連線到 port 80 的封包轉到 proxy ( port 3128 ) 上。也就是說,我們會讓使用者連線到網址時,會自動的透過 proxy,而使用者本身沒有任何的感覺。



增加對網站瀏灠的控管,整合 NAT

首先,必須要開啟 NAT 與 proxy,並且在 /etc/squid/squid.conf 設定檔裏新增以下四行:

http_accel_host test.com.tw <=== 依您的主機名稱設定,不要照抄

http_accel_port 80

http_accel_with_proxy on

http_accel_uses_host_header on


設定 iptables 的轉向

在 iptables 內新增以下規則之後,再重新啟動 iptables 即可:

iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.100.0/24 –dport 80 -j REDIRECT –to-ports 3128



上列指令說明:

-i eth0:網路介面為 eth0

-p tcp:通訊協定為 TCP

-s 192.168.100.0/24:來源為 192.168.100.0/24,也就是 192.168.100.0-192.168.100.255

–dport 80:目的地為 port 80

-j REDIRECT:重新導向

–to-ports 3128:新的目地的為 3128



設定以上資料就可以整合 NAT 與 Proxy 來管控 client 端的上網了。





後記:

CentOS 5.3 的squid 的版本為 SQUID 2.6.STABLE21 版,在啟動 squid server 時會出現以下的啟動失敗的錯誤訊息:

正在啟動 squid: /etc/init.d/squid: line 42: 8378 已經終止 $SQUID $SQUID_OPTS >> /var/log/squid/squid.out 2>&1 [失敗]



經查詢 /var/log/squid/squid.out 記錄檔,裏面有出現 FATAL: Could not determine fully qualified hostname. Please set ‘visible_hostname’ 這行的說明,是因為 squid 常遇到沒有 FQDN 的主機,請在 squid.conf 新增如下的參數:

# TAG: visible_hostname
# If you want to present a special hostname in error messages, etc,
# define this. Otherwise, the return value of gethostname()
# will be used. If you have multiple caches in a cluster and
# get errors about IP-forwarding you must set them to have individual
# names with this setting.
#
#Default:
# none <=== 在這個地方, 依環境改成適合您的設定,如下所示:

visible_hostname FQDN <== 用在伺服器
或者是
visible_hostname localhost <== 用在 IP 及 Domain Name 不固定的個人電腦

像我是改成 visible_hostname localhost,這樣就可以正常啟動了。



參考資料:鳥哥的linux私房菜