簡易 Proxy Server 設定與 NAT 的整合

Published 24 八月, 2009 by kevingt

[ 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私房菜

發表留言