Squid中文權威指南 第九章(Cache攔截)

第9章 Cache攔截



Cache攔截是讓傳輸流向Squid的流行技術,它不用配置任何客戶端。你可以配置路由器或交換機將HTTP連接轉發到squid運行的主機。squid運行的操作系統被配置成接受外部數據包,並將其遞交給squid進程。爲了讓HTTP攔截生效,你必須配置3個獨立的因素:網絡設備,squid運行的操作系統,和squid自身。

(譯者注:Cache攔截實際上指的是Squid的透明代理)



9.1它如何工作?

Cache攔截包含了某些網絡欺騙,它對理解在客戶端和Squid之間的會話有用。我使用圖9-1和如下的tcpdump示例輸出,來解釋當數據包通過網絡時,如何被攔截。


Figure 9-1. How HTTP interception works



1.用戶代理(user-agent)想請求某個資源,它對原始服務器發起index.html請求,例如:www.oreilly.com。它需要原始服務器的IP地址,所以先發起一個DNS請求:

Packet 1
    
TIME:   19:54:41.317310
    
UDP:    206.168.0.3.2459 -> 206.168.0.2.53

DATA:   .d...........www.oreilly.com.....

---------------------------------------------------------------------------
    

Packet 2

TIME:   19:54:41.317707 (0.000397)

UDP:    206.168.0.2.53 -> 206.168.0.3.2459

DATA:   .d...........www.oreilly.com.............PR.....%........PR.

....$........PR...ns1.sonic.net.........PR...ns2.Q........PR

...ns...M...............h.............!.z.......b......

2.現在有了IP地址,用戶代理初始化到原始服務器80端口的TCP連接:

Packet 3
    TIME:   19:54:41.320652 (0.002945)
    TCP:    206.168.0.3.3897 -> 208.201.239.37.80 Syn
    DATA:   <No data>

3.路由器或交換機注意到目的地址是80端口的TCP SYN包。下一步會發生什麼依賴於特定的攔截技術。在4層交換和路由策略上,網絡設備簡單的將TCP包轉發到Squid的數據鏈路地址。當squid直接掛在網絡設備上時,就這樣工作。對WCCP來說,路由器封裝TCP包爲GRE包。因爲GRE包有它自己的IP地址,它可能被通過多個子網進行路由。換句話說,WCCP不要求squid直接掛在路由器上。



4.Squid主機的操作系統接受到攔截包。對4層交換來說,TCP/IP包並沒有改變。假如包使用了GRE封裝,主機會剝離外部的IP和GRE頭部,並將原始的TCP/IP包放在輸入隊列裏。注意squid主機接受到的包是針對外部地址的(原始服務器的)。正常情況下,這個包不匹配任何本地地址,它會被丟棄。爲了讓主機接受外部數據包,你必須在大多數操作系統上激活IP轉發。



5.客戶端的TCP/IP包被包過濾代碼處理。數據包必須匹配某個規則,該規則指示內核轉交這個包給squid。如果沒有這樣的規則,內核簡單的將包按照它自己的方式轉發給原始服務器,這不是你想要的。

注意SYN包的目的端口是80,但squid可能偵聽在不同的端口,例如3128。包過濾規則允許你改變端口號。你不必讓squid偵聽在80端口。通過tcpdump,你能見到這步,因爲轉發的包不會再次通過網絡接口代碼。

即使squid偵聽在80端口,包過濾器的重定向規則仍是必要的。可以讓squid不在這些端口上接受攔截包。重定向規則有點神奇,它轉交外部數據包給squid。



6.Squid接受到新連接的通知,它接受這個連接。內核發送SYN/ACK包返回給客戶端:

Packet 4

TIME:   19:54:41.320735 (0.000083)

TCP:    208.201.239.37.80 -> 206.168.0.3.3897 SynAck

DATA:   <No data>

就象你見到的一樣,源地址是原始服務器,儘管這個包不會抵達原始服務器。操作系統只是簡單的將源地址和目的地址交換一下,並將它放進響應數據包裏。



7.用戶代理接受到SYN/ACK包,建立起完整的TCP連接。用戶代理現在相信它是連接到原始服務器,所以它發送HTTP請求:

Packet 5

TIME:   19:54:41.323080 (0.002345)

TCP:    206.168.0.3.3897 -> 208.201.239.37.80 Ack

DATA:   <No data>

---------------------------------------------------------------------------

Packet 6

TIME:   19:54:41.323482 (0.000402)

TCP:    206.168.0.3.3897 -> 208.201.239.37.80 AckPsh

DATA:   GET / HTTP/1.0

        User-Agent: Wget/1.8.2
            
        Host: www.oreilly.com
         
        Accept: */*
         
        Connection: Keep-Alive

8.Squid接受HTTP請求。它使用HTTP Host頭部來轉換局部URL爲完整的URL。在這種情形下,可在access.log文件裏見到http://www.oreilly.com。



9.從這點開始,squid正常的處理請求。一般cache命中會立刻返回。cache丟失會轉發到原始服務器。



10.最後,是squid從原始服務器接受到的響應:

Packet 8

TIME:   19:54:41.448391 (0.030030)

TCP:    208.201.239.37.80 -> 206.168.0.3.3897 AckPsh

DATA:   HTTP/1.0 200 OK
            
        Date: Mon, 29 Sep 2003 01:54:41 GMT
        
        Server: Apache/1.3.26 (Unix) PHP/4.2.1 mod_gzip/1.3.19.1a mo
        
        d_perl/1.27
        
        P3P: policyref="http://www.oreillynet.com/w3c/p3p.xml",CP="C
        
        AO DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONo OUR
        
        DELa PUBi OTRa IND PHY ONL UNI PUR COM NAV INT DEM CNT STA P
        
        RE"
        
        Last-Modified: Sun, 28 Sep 2003 23:54:44 GMT
        
        ETag: "1b76bf-b910-3ede86c4"
        
        Accept-Ranges: bytes
        
        Content-Length: 47376
        
        Content-Type: text/html
        
        X-Cache: MISS from www.oreilly.com
        
        X-Cache: MISS from 10.0.0.1
        
        Connection: keep-alive

不應該讓交換機或路由器來攔截squid到原始服務器的連接。假如這種情況發生,squid結束與自己的會話,並且不能滿足任何cache丟失。防止這類轉發死循環的最好方法是,確認用戶和squid連接到交換機或路由器的獨立接口。無論何時,應該在指定接口上應用攔截規則。最明顯的,不該在squid使用的接口上激活攔截。



9.2爲何要(或不要)攔截?

許多單位發現,cache攔截很有用,因爲他們不能,或不願意配置所有用戶的web瀏覽器。相對於配置成百上千臺工作站來說,在單個交換機或路由器上做一點網絡欺騙更容易。從我們面臨的許多選擇來看,cache攔截確實有好也有壞。它可能讓你的生活更容易,但也許會更難。

Cache攔截的最明顯的貢獻是,所有HTTP請求通過squid自動離開你的網絡。你不必擔心配置任何瀏覽器,用戶可能在瀏覽器上禁止他們的代理設置。cache攔截讓網絡管理員完全控制HTTP會話。你可以改變,增加,或刪除squid的緩存,而不會顯著影響你的用戶上網衝浪。

關於HTTP攔截的主要不利點就是該技術違背了TCP/IP的標準。這些協議要求路由器或交換機轉發TCP/IP包到目的IP地址裏指定的主機。然而轉發包到cache代理破壞了這些規則。代理僞裝身份接受轉交過來的連接。用戶代理被欺騙了,以爲它們在與真正的web服務器會話。

這樣的混亂導致在老版本的Microsoft IE瀏覽器中產生嚴重問題。瀏覽器的Reload按鈕是刷新HTML頁面的最容易的方法。當瀏覽器被配置成使用cache代理時,reload請求包含了一個Cache-Control:no-cache頭部,它強迫產生cache丟失(或cache確認),並確保響應是最近更新的。假如沒有明確配置使用代理,瀏覽器會忽略該頭部。當使用cache攔截時,瀏覽器認爲它在連接到原始服務器,因此沒必要發送該頭部。在這種情形下,squid不會告知用戶的Reload按鈕,也許不會驗證cache響應。squid的ie_refresh提供瞭解決此bug的局部解決方法(見附錄A)。Microsoft已經在其IE 5.5 SP1中解決了這個問題。

因爲類似的理由,你不能結合cache攔截使用HTTP代理驗證。因爲客戶端不知道這個代理,它不會發送必要的Proxy-Authorization頭部。另外,407(代理驗證請求)響應代碼也不恰當,因爲響應看起來象來自原始服務器,原始服務器從來不會發送如此響應。

也不能在cache攔截中使用RFC 1413 ident查詢(見6.1.2.11章節)。Squid不能對必要的IP地址建立新的TCP Socket連接。操作系統在轉發攔截連接到squid時,它執行欺騙。然後,當squid希望bind新的TCP Socket到外部IP地址時,它不能執行欺騙。它想bind的地址實際上並非真正本地的,所以bind系統調用失敗。

cache攔截也與設計成阻止地址欺騙的IP過濾衝突(見RFC 2267:Network Ingress Filtering: Defeating Denial of Service Attacks Which Employ IP Source AddressSpoofing)。考慮如圖9-2顯示的網絡。路由器有2個LAN接口:lan0和lan1。網絡管理員在路由器上使用包過濾器,以確保沒有內部主機傳送假冒源地址的數據包。路由器只會轉發源地址對應相連網絡的數據包。包過濾規則也許看起來如下:

# lan0

allow ip from 172.16.1.0/24 to any via lan0

deny ip from any to any via lan0


# lan1

allow ip from 10.0.0.0/16 to any via lan1

deny ip from any to any via lan1

Figure 9-2. Interception caching breaks address spoofing filters



現在看看,當路由器和lan1中的squid主機配置成攔截來自lan0中的HTTP連接後,會發生什麼。Squid裝扮成原始服務器,這意味着從squid到用戶的響應TCP包欺騙了源地址。lan0過濾規則導致路由器拒絕這些包。爲了讓cache攔截生效,網絡管理員須移除lan0規則。這樣就讓網絡有漏洞,從而易遭拒絕服務攻擊。

我在先前的章節裏描述過,客戶端在打開連接之前必須先進行DNS查詢。在某些防火牆環境中,這樣做可能有問題。你想進行HTTP攔截的主機必須能夠查詢DNS。如果客戶端了解自己正使用代理(因爲手工配置或代理自動配置),它通常就不去解析主機名。代替的,它簡單的將完整URL轉發給squid,由squid來查詢原始服務器的IP地址。

另一個小問題是,squid接受任意目的IP地址的連接。例如,某個web站點當機了,但它仍然有DNS記錄存在。squid僞裝這個站點接受TCP連接。客戶端會認爲該站點仍然在運行,因爲連接有效。當squid連接到原始服務器失敗時,它強迫返回錯誤消息。

萬一形勢不清,HTTP攔截在初次使用時有些棘手或困難。許多不同的組件必須組合工作,並且要配置正確。甚至,從內存中恢復整個配置也很困難。我強烈建議你在將其應用於生產環境之前,先建立測試環境。一旦你讓它正常運行,請記錄每一步細節。



9.3 網絡設備

現在你瞭解了cache攔截的相關細節,讓我們看看如何實際讓它工作。我們先配置網絡設備,它們用來攔截HTTP連接。


9.3.1 內置Squid

在該配置中,你無需交換或網絡路由設備來攔截HTTP連接。代替的,squid運行的Unix系統,也就是路由器(或網橋),請見圖9-2。


Figure 9-3. A system that combines routing and caching can easily intercept HTTP traffic



該配置本質上跳過了9.1章的頭三步。squid主機充當網絡路由器,它接受HTTP連接包。假如你採用此方法,請直接跳到9.4章。


9.3.2 四層交換

許多單位使用四層交換機來支持HTTP攔截。這些產品提供更多的功能,例如健壯性檢測和負載均衡。我在這裏僅僅講講攔截。關於健壯性檢測和負載均衡的信息,請見O'Reilly's Server Load Balancing and Load Balancing Servers, Firewalls, and Caches (John Wiley & Sons). 下面的章節包含了許多產品和技術的示例配置。

9.3.2.1 Alteon/Nortel

下面的配置來自ACEswitch 180和Alteon's WebOS 8.0.21。網絡設置請見圖9-4。


Figure 9-4. Sample network for layer four switch interception, for Alteon and Foundry examples



客戶端連接到端口1,通過端口2連接到因特網,squid運行在端口3。下面的行是交換機的/cfg/dump命令的輸出。你無須敲入所有這些行。甚至,在Alteon的新版軟件裏,某些命令可能改變了。注意Alteon把這個功能叫做Web Cache重定向(WCR)。如下是處理步驟:

  • 1. 首先,你必須分配給Alteon交換機一個IP地址。這是必要的,以便交換機能檢查squid的存活狀態。
    /cfg/ip/if 1
            ena
        
            addr 172.16.102.1
        
            mask 255.255.255.0
        
            broad 172.16.102.255
  • 2. Alteon的WCR屬於服務負載均衡(SLB)配置。所以,必須使用如下命令在交換機上激活SLB功能:
    /cfg/slb
            
            on
  • 3. 現在,用squid的IP地址定義real server:
    /cfg/slb/real 1
            
            ena
            
            rip 172.16.102.66
  • 4. 必須定義一個組,並分配給real server一個組號:
    /cfg/slb/group 1
            
            health tcp
            
            add 1
  • 5. 下一步定義2個過濾規則。第1條規則匹配HTTP連接(目的端口是80的TCP包),並重定向它們到組1裏的server。第2條規則匹配所有其他數據包,並正常轉發它們。
    /cfg/slb/filt 1
            
            ena
            
            action redir
            
            sip any
            
            smask 0.0.0.0
            
            dip any
            
            dmask 0.0.0.0
            
            proto tcp
            
            sport any
            
            dport http
            
            group 1
            
            rport 0
    
    
    /cfg/slb/filt 224
    
            ena
            
            action allow
            
            sip any
            
            smask 0.0.0.0
            
            dip any
            
            dmask 0.0.0.0
            
            proto any
  • 6. 最後一步是給SLB配置指定的交換端口。在端口1上,處理客戶端連接(這也是客戶端連接的端口),並增加2條過濾規則。在端口2上,僅須配置它正常服務(例如,向上連接到Internet):
    cfg/slb/port 1
            
            client ena
            
            filt ena
            
            add 1
            
            add 224
    
    /cfg/slb/port 2
            
            server ena

爲了驗證HTTP攔截配置正確並工作良好,你可以使用/stats/slb和/info/slb菜單裏的命令。/info/slb/dump是快速有效的查看整個SLB配置的方法:

>> Main# /info/slb/dump


Real server state:
  
  1: 172.16.102.66, 00:c0:4f:23:d7:05, vlan 1, port 3, health 3, up


Virtual server state:


Redirect filter state:
  
  1: dport http, rport 0, group 1, health tcp, backup none
    
    real servers:
      
      1: 172.16.102.66, backup none, up


Port state:
  
  1: 0.0.0.0, client
     
     filt  enabled, filters: 1 224
  
  2: 0.0.0.0, server
     
     filt disabled, filters: empty
  
  3: 0.0.0.0
     
        filt disabled, filters: empty

在該輸出裏,注意到交換機顯示Squid在端口3上可到達,並且運行正常。你也能見到過濾規則1應用到端口1。在端口狀態節裏,端口1定義爲客戶端連接端口,端口2簡單的標記爲服務端口。

/stats/slb/real命令顯示real server(squid)的有用統計:

>> Main# /stats/slb/real 1

------------------------------------------------------------------


Real server 1 stats:

Health check failures:                0

Current sessions:                    41

Total sessions:                     760

Highest sessions:                    55

Octets:                               0

大部分統計與任務(例如TCP連接)數量相關。假如再次運行該命令,總共的任務計數會增加。最後,/stats/slb/group命令顯示幾乎同樣的信息:

>> Main# /stats/slb/group 1

------------------------------------------------------------------


Real server group 1 stats:


                      Current      Total  Highest

Real IP address      Sessions   Sessions Sessions           Octets

---- --------------- -------- ---------- --------  ---------------
   
   1 172.16.102.66         65       2004       90                0

---- --------------- -------- ---------- --------  ---------------
                           
                           65       2004       90                0

假如不止1個real server在組裏,該輸出會更有趣。

9.3.2.2 Foundry

下面的配置示例來自ServerIron XL,運行的軟件版本是07.0.07T12。跟前面一樣,客戶端在端口1,Internet連接在端口2,squid運行在端口3。然而,這樣的配置少了點東西,因爲這裏可以激活HTTP全局攔截。Foundry的cache攔截的名字叫做Transparent Cache Switching(TCS)。請參考圖9-4。首先請給交換機分配1個IP地址,以便執行健壯性檢測:

ip address 172.16.102.1 255.255.255.0

Foundry允許你在特定端口上激活或禁用TCS。然而簡單起見,這裏全局激活它:

ip policy 1 cache tcp http global

在該行裏,cache是針對TCS功能的關鍵字。下1行定義web cache,我定義其名字爲squid1,並且告訴交換機它的IP地址:

server cache-name squid1 172.16.102.66

最後的步驟是將web cache加進cache組裏:

server cache-group 1
 
 cache-name squid1

假如在轉發連接時有問題,請參閱show cache-group命令的輸出:

ServerIron#show cache-group


Cache-group 1 has 1 members Admin-status = Enabled Active = 0


Hash_info: Dest_mask = 255.255.255.0 Src_mask = 0.0.0.0


Cache Server Name                Admin-status Hash-distribution

squid1                           6            3


HTTP Traffic  From <-> to  Web-Caches


Name: squid1          IP: 172.16.102.66    State: 6   Groups =   1


                         Host->Web-cache       Web-cache->Host

           State   CurConn TotConn Packets    Octets     Packets    Octets

Client     active  441     12390   188871     15976623   156962     154750098

Web-Server active  193     11664   150722     151828731  175796     15853612

Total              634     24054   339593     167805354  332758     170603710

某些輸出有些模糊,但通過重複該命令,並且觀察計數器的增長,你能瞭解攔截是否在進行。

show server real提供幾乎同樣的信息:

ServerIron#show server real squid1

Real Servers Info


Name : squid1                                       Mac-addr: 00c0.4f23.d705

IP:172.16.102.66   Range:1    State:Active          Wt:1     Max-conn:1000000

Src-nat (cfg:op):(off:off)    Dest-nat (cfg:op):(off:off)

squid1 is a TRANSPARENT CACHE in groups   1

Remote server   : No          Dynamic : No      Server-resets:0

Mem:server: 02009eae Mem:mac: 045a3714


Port    State    Ms CurConn TotConn Rx-pkts  Tx-pkts  Rx-octet   Tx-octet   Reas

----    -----    -- ------- ------- -------  -------  --------   --------   ----
http    active   0  855     29557   379793   471713   373508204  39425322   0

default active   0  627     28335   425106   366016   38408994   368496301  0


Server  Total       1482    57892   804899   837729   411917198  407921623  0

最後,使用show logging命令來觀察交換機是否顯示squid正常或異常:

ServerIron#show logging

...

00d00h11m51s:N:L4 server 172.16.102.66 squid1 port 80 is up

00d00h11m49s:N:L4 server 172.16.102.66 squid1 port 80 is down

00d00h10m21s:N:L4 server 172.16.102.66 squid1 port 80 is up

00d00h10m21s:N:L4 server 172.16.102.66 squid1 is up

注意ServerIron認爲服務運行在80端口。以後你會見到squid運行在3128端口的示例。包過濾規則實際上將包的目的地址從80改變爲3128。這導致一些與狀態檢測有關的有趣結果,我在9.3.2.5節裏會講到。

9.3.2.3 Extreme Networks

在該示例裏,硬件是Summit1i,軟件版本是6.1.3b11。再次將客戶端分配在端口1,Internet在端口2,squid在端口3。網絡配置見圖9-5。


Figure 9-5. Sample network for intercepting with a router, for the Extreme and Cisco policy routing examples



Extreme交換機僅僅對在不同子網間進行路由的數據包進行HTTP連接的攔截。換句話說,如果你配置Extreme交換機使用二層模式(單一VLAN裏),就不能將包轉發給squid。爲了讓HTTP攔截正常工作,必須給用戶,Squid,和Internet配置不同的VLAN。

configure Default delete port 1-8


create vlan Users

configure Users ip 172.16.102.1 255.255.255.192

configure Users add port 1


create vlan Internet

configure Internet ip 172.16.102.129 255.255.255.192

configure Internet add port 2


create vlan Squid

configure Squid ip 172.16.102.65 255.255.255.192

configure Squid add port 3

下一步是激活和配置交換機的路由:

enable ipforwarding
configure iproute add default 172.16.102.130

最後,配置交換機重定向HTTP連接到Squid:

create flow-redirect http tcp destination any ip-port 80 source any
configure http add next-hop 172.16.102.66
9.3.2.4 Cisco Arrowpoint

下類配置基於我以前的測試筆記。然而,最近我沒有使用這類型的交換機,不能確保如下命令仍然正確:

circuit VLAN1
  
  ip address 172.16.102.1 255.255.255.0


service pxy1
  
  type transparent-cache
  
  ip address 172.16.102.66
  
  port 80
  
  protocol tcp
  
  active


owner foo
  
  content bar
    
    add service pxy1
    
    protocol tcp
    
    port 80
    
    active
9.3.2.5 關於HTTP服務和健壯性檢測的評論

在上面的示例裏,路由器/交換機都直接轉發包,不會改變目的TCP端口。在9.4章裏用到的包過濾規則改變了目的端口。如果試圖在同一主機上運行HTTP服務和squid,那麼就產生了一個有趣的問題。

爲了在3128端口運行Squid的同時,還要在80端口運行HTTP,包過濾配置必須有1條特殊的規則,它接受到本機HTTP服務的TCP連接。否則,連接會直接轉交給Squid。該規則易於建立。假如目的端口是80,並且目的地址是服務器的,那麼主機正常接受這個包。然而所有的攔截包有外部目的地址,所以它們不會匹配該規則。

然而,當路由器/交換機進行HTTP健壯性檢測時,它連接到服務器的IP地址。這樣,健壯性檢測的數據包匹配了上述規則,它不會轉交給Squid。路由器/交換機檢測了錯誤的服務。假如HTTP服務down掉了,而squid還在運行,那健壯性檢測就產生錯誤結果。

解決這個問題的一些選擇是:

  • 1.不要在Squid主機上運行HTTP服務;

  • 2.增加1條特殊的包過濾規則,將來自路由器/交換機的狀態檢測的包轉交給squid;

  • 3.配置路由器/交換機,改變目的端口爲3128;

  • 4.禁止4層狀態檢測。

9.3.3 Cisco策略路由

策略路由與4層交換並非不同。它在Cisco和其他公司的路由產品上執行。主要的區別是策略路由不包括任何健壯性檢測。這樣,假如squid超載或完全不可響應,路由器還會繼續轉發包到squid,而不是將包路由到原始服務器。策略路由要求squid位於路由器直接相連的子網中。

在本示例裏,使用了Cisco 7204路由器,運行IOS Version 12.0(5)T。網絡配置與前面的一樣,見圖9-5。

首先的配置步驟是定義訪問列表,匹配來自客戶端的到80端口的數據包。必須確保Squid發起的到80端口的數據包不會被再次攔截。做到這點的方法之一是,定義1個特殊規則,拒絕來自squid的數據包,緊跟1條規則允許所有其他的數據包:

access-list 110 deny tcp host 172.16.102.66 any eq www

access-list 110 permit tcp any any eq www


另外,如果Squid和用戶位於不同的子網,你可以僅僅允許來自用戶所在網絡的數據包:

access-list 110 permit tcp 10.102.0.0 0.0.255.255 any eq www

下一步是定義路由映射。在這裏你告訴路由器轉發攔截包到何處去:

route-map proxy-redirect permit 10
 
 match ip address 110
 
 set ip next-hop 172.16.102.66

這些命令表明,“假如IP地址匹配訪問列表110,就轉發該包到172.16.102.66”。在route-map行的數字10是一個序列號,假如你有多個路由映射的話。最後一步是應用路由映射到客戶端連接的接口:

interface Ethernet0/0

ip policy route-map proxy-redirect

IOS不對策略路由提供很多調試方法。然而,show route-map命令足夠可用:

router#show route-map proxy-redirect

route-map proxy-redirect, permit, sequence 10


  Match clauses:
    
    ip address (access-lists): 110
  
  Set clauses:
    
    ip next-hop 172.16.102.66
  
                                Policy routing matches: 730 packets, 64649 bytes

9.3.4 Web Cache Coordination協議

Cisco對4層交換技術的響應叫做Web Cache Coordination Protocol(WCCP).WCCP在許多方面與典型的4層攔截不同。

首先,攔截包被封裝在GRE(路由封裝類)裏。這點允許數據包跨子網傳輸,也就意味着squid不必直接連在路由器上。因爲數據包是封裝的,squid主機必須對其進行解包。並非所有的Unix系統有解開GRE包的代碼。

第二個不同是,路由器如何決定將負載分攤到多個cache上。事實上,路由器不做這個決定,由cache來做。當路由器有一組支持WCCP的cache時,其中一個cache主動成爲組的領導。由領導cache來決定如何分攤負載和通知路由器。在路由器重定向然任何連接之前,這是一個額外的必要步驟。

因爲WCCP使用GRE,路由器可能強迫要求將來自HTTP請求的大TCP包分割成片斷。幸運的是,這點不會經常發生,因爲大部分HTTP請求比以太網MTU size(1500字節)要小。默認的TCP和IP包頭部是20字節,這意味着以太網幀能實際攜帶1460字節的數據。GRE封裝在GRE頭部增加了20字節,另外在第二個IP頭部增加了20字節。這樣來自客戶端的正常的1500字節的TCP/IP包,在封裝後變成了1540字節。這樣數據包就太大而不能在單個以太網幀裏傳輸,所以路由器將原始包分割成兩個片斷。

9.3.4.1 WCCPv1

該節的配置示例在運行IOS Version 12.0(5)T的Cisco 7204路由器上測試。網絡配置跟圖9-5同。

首先,在IOS配置中輸入如下兩行,激活路由器的WCCP:

ip wccp version 1

ip wccp web-cache

接着,必須在單獨的路由器接口上激活WCCP。在HTTP包離開路由器的接口上激活WCCP,也就是路由器連接到外部原始服務器或Internet網關的接口:

interface Ethernet0/1
 
 ip address 172.16.102.129 255.255.255.192
 
 ip wccp web-cache redirect out

請確認保存了配置改變。

你也許想使用訪問列表來阻止某些web站點的攔截。可以使用訪問列表來防止循環轉發。例如:

! don't re-intercept connections coming from Squid:

access-list 112 deny   tcp host 172.16.102.66 any eq www


! don't intercept this broken web site

access-list 112 deny   tcp any 192.16.8.7 255.255.255.255 eq www


! allow other HTTP traffic

access-list 110 permit tcp any any eq www


ip wccp web-cache redirect-list 112

路由器不發送任何數據到squid,直到squid宣稱它自己是路由器。我在9.5.1節裏解釋如何配置squid的WCCP。

9.3.4.2 WCCPv2

當前標準的Squid發佈僅支持WCCPv1。然而,可在http://devel.squid-cache.org/找到WCCPv2的補丁。該代碼仍是實驗性的。注意從路由器發送到Squid的GRE包,包含了額外的4個字節。WCCPv2在GRE頭部和封裝的IP包之間,插入了一個重定向頭部。也許需要修改內核代碼來計算這個額外的頭部。

9.3.4.3 調試

IOS提供許多命令來監視和調試WCCP。show ip wccp web-cache命令提供一些基本的信息:

router#show ip wccp web-cache

Global WCCP information:
    
    Router information:
        
        Router Identifier:                   172.16.102.129
        
        Protocol Version:                    1.0
    
    
    Service Identifier: web-cache
        
        Number of Cache Engines:             1
        
        Number of routers:                   1
        
        Total Packets Redirected:            1424
        
        Redirect access-list:                -none-
        
        Total Packets Denied Redirect:       0
        
        Total Packets Unassigned:            0
        
        Group access-list:                   -none-
        
        Total Messages Denied to Group:      0
        
        Total Authentication failures:       0

欲瞭解更多細節,在前敘命令後加一個detail單詞:

router#show ip wccp web-cache detail

WCCP Cache-Engine information:

        IP Address:            172.16.102.66
        
        Protocol Version:      0.4
        
        State:                 Usable
        
        Initial Hash Info:     00000000000000000000000000000000
                               
                               00000000000000000000000000000000
        
        Assigned Hash Info:    FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                               
                               FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
        Hash Allotment:        256 (100.00%)
        
        Packets Redirected:    1424
        
        Connect Time:          00:17:40

這裏可以看到squid的IP地址和狀態。假如不止一個cache與路由器會話,那麼hash分配信息看起來不同。大多數情況下,每個cache接受到相等的hash值。

注意第二條命令輸出的協議版本值,與第一條命令的不一樣。不幸的是,賦予了版本號太多的意義。show ip wccp web-cache命令看起來報告WCCP協議的主版本號(例如1或2),然而show ip wccp web-cache detail的版本號看起來匹配Squid的wccp_version指令的值。



9.4 操作系統配置

爲了讓cache攔截正常工作,必須在操作系統中激活某些網絡功能。首先,必須激活IP包轉發。這就允許操作系統接受目的地址是外部IP的數據包。接着,必須激活和配置內核中的相關代碼,以重定向外部包到Squid。


9.4.1 Linux

本節的指導適合2.4系列Linux內核。我使用RedHat Linux7.2(內核是2.4.7-10)。假如你使用的版本不同,那可能不能運行。建議搜索下Squid的FAQ或其他地方,找到關於內核的更新的或歷史的信息。

在我測試iptables過程中,不必激活IP轉發。然而,你也可以試試在一開始就激活它,並在一切運行良好後,看看能否禁掉它。激活包轉發的最好的方法是在/etc/sysctl.conf文件裏增加如下行:

net.ipv4.ip_forward = 1

一般來說,在HTTP攔截生效前,不必編譯新內核。假如你不知道如何配置和創建新Linux內核,請參閱O'Reilly's Running Linux by Matt Welsh, Matthias Kalle Dalheimer, and Lar Kaufman。當你配置內核時,請確認如下選項被激活:

o  General setup
     
     Networking support (CONFIG_NET=y)
     
     Sysctl support (CONFIG_SYSCTL=y)


o  Networking options
     
     Network packet filtering (CONFIG_NETFILTER=y)
     
     TCP/IP networking (CONFIG_INET=y)
     
     Netfilter Configuration
       
       Connection tracking (CONFIG_IP_NF_CONNTRACK=y)
       
       IP tables support (CONFIG_IP_NF_IPTABLES=y)
       
       Full NAT (CONFIG_IP_NF_NAT=y)
       
       REDIRECT target support (CONFIG_IP_NF_TARGET_REDIRECT=y)


o  File systems
     
     /proc filesystem support (CONFIG_PROC_FS=y)

另外,請確認該選項沒被激活:

o Networking options

    
     Fast switching (CONFIG_NET_FASTROUTE=n)

重定向外部數據包到squid的代碼是Netfilter軟件的一部分。如下是發送HTTP攔截連接到squid的規則:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

Linux內核維護許多不同的tables。-t nat選項表明我們正在修改NAT(網絡地址轉換)表。本質上,我們使用iptables將原始服務器的TCP/IP地址轉換爲squid的本地TCP/IP地址。

每個iptables表有許多鏈。-A PREROUTING表明我們增加了一條規則到內建的鏈叫做PREROUTING。PREROUTING鏈僅對從外部網絡進入系統的數據包有效。

接下來的三個選項決定哪個包匹配該規則。-i eth0選項限制規則僅對eth0接口上接受的數據包有效。-p tcp選項指定TCP包,--dport 80指定包的目的端口是80。假如這三個條件都是true,那麼包匹配該規則。

-j REDIRECT選項表明對匹配規則的包,採取何種動作。REDIRECT是內建的動作名,它導致iptables改變包的目的地址爲127.0.0.1。--to-port 3128選項也指示iptables改變目的TCP端口爲3128。

假如你在squid主機上運行HTTP服務(例如Apache),就必須增加另外的iptables規則。該必要規則允許連接到HTTP服務。否則,REDIRECT規則導致iptables轉發連接到squid的3128端口。可以使用-I選項在列表頂部插入一條新規則:

iptables -t nat -I PREROUTING -i eth0 -p tcp -d 172.16.102.66 --dport 80 -j ACCEPT

一旦確認所有iptables規則工作正確,記得運行如下命令來保存配置:

/sbin/service iptables save

將當前規則保存到/etc/sysconfig/iptables,當系統重啓時,這些規則自動載入。

9.4.1.1 Linux和WCCP

2.4版本的Linux內核自帶1個GRE僞裝接口。然而,它不能解碼WCCP任務裏封裝的GRE包。問題看起來在於路由器設置了WCCP/GRE包的協議類型域爲0x883E。Linux的GRE驅動不知道如何處理這類型包,因爲它不瞭解0x883E類型的協議。

可以試試給Linux打GRE模塊的補丁,以便它能在WCCP下工作。Squid FAQ包含了對這個補丁的鏈接。然而,假如使用WCCP指定的Linux模塊,事情會容易些。可以在這裏找到它:http://www.squid-cache.org/WCCP-support/Linux/ip_wccp.c

必須編譯ip_wccp.c文件爲可裝載內核模塊。有點棘手的是,依賴於內核版本的不同,編譯選項可能不同。你可以進入內核源代碼目錄,敲入make modules並觀察編譯器命令的滾動。然後拷貝這些命令中的一個,然後改變最後一個參數爲ip_wccp.c。如下是我在2.4.7-10 Linux內核中使用的命令:

% gcc -Wall -D_ _KERNEL_ _ -I/usr/src/linux-2.4.7-10/include  /
  
  -DMODULE -DMODVERSIONS -DEXPORT_SYMBAB /
  
  -include /usr/src/linux-2.4.7-10/include/linux/modversions.h /
  
  -O2 -c ip_wccp.c

gcc命令在當前目錄會生成ip_wccp.o文件。下一步使用insmod命令,裝載模塊到內核中:

# insmod ip_wccp.o

注意ip_wccp模塊接受來自任何源地址的GRE/WCCP包。換句話說,惡意用戶可能發送數據到squid cache。假如使用該模塊,應該安裝一條iptables規則,拒絕外部的GRE包。例如:

# iptables -A INPUT -p gre -s 172.16.102.65 -j ACCEPT

# iptables -A INPUT -p gre -j DROP

不要忘記敲入/sbin/service iptables save命令來保存配置。


9.4.2 FreeBSD

本節的例子基於FreeBSD-4.8,並可以在任何FreeBSD-4和5系列的後續版本上運行。要激活IP包轉發,在/etc/sysctl.conf中增加如下行:

net.inet.ip.forwarding=1

需要在內核中激活2個特殊選項。假如你不知道如何編譯內核,參見FreeBSD Handbook第9章(http://www.freebsd.org/handbook/index.html). 編輯內核配置文件,確保有如下行:

options          IPFIREWALL

options          IPFIREWALL_FORWARD

假如squid主機位於無人照看的機房中,我也推薦使用IPFIREWALL_DEFAULT_TO_ACCEPT選項。假如你被防火牆的規則困擾,仍然可以登陸系統中。ipfw命令告訴內核重定向攔截連接到squid:

/sbin/ipfw add allow tcp from 172.16.102.66 to any out

/sbin/ipfw add allow tcp from any 80 to any out

/sbin/ipfw add fwd 127.0.0.1,3128 tcp from any to any 80 in

/sbin/ipfw add allow tcp from any 80 to 172.16.102.66 in

第一條規則匹配squid主機發起的數據包。它確保外出的TCP連接不會被重新定向回squid。第二條規則匹配squid響應客戶端的數據包。我在這裏列出它,因爲隨後會有另外的ipfw規則,這些規則會拒絕這些包。第三條規則實際重定向進來的連接到squid。第四條規則匹配從原始服務器返回squid的數據包。這裏又一次假設隨後會有相應的拒絕規則。

假如在squid主機上運行HTTP服務,就必須增加另外的規則,它放過,而不是重定向,目的地址是原始服務器的TCP包。下列規則在fwd規則之前:

/sbin/ipfw add allow tcp from any to 172.16.102.66 80 in

FreeBSD典型的將ipfw規則存儲在/etc/rc.firewall裏。一旦你確認規則設置正確,記得保存它們。將如下行加入/etc/rc.local文件,讓FreeBSD在啓動時自動運行/etc/rc.firewall腳本。

firewall_enable="YES"
9.4.2.1 FreeBSD和WCCP

FreeBSD版本4.8和後續版本內建了對GRE和WCCP的支持。早期的版本需要補丁,你可以在這裏找到: http://www.squid-cache.org/WCCP-support/FreeBSD/ . 內建代碼的性能非常好,它是真正的內核組織編寫的。可能也需要編譯支持GRE的新內核。將如下行加入內核配置文件裏:

pseudo-device   gre

對Freebsd-5,使用device代替了pseudo-device。當然,你也需要前面章節裏提到的FIREWALL選項。

在安裝和重啓了新內核後,必須配置GRE通道來接受來自路由器的GRE包。例如:

# ifconfig gre0 create

# ifconfig gre0 172.16.102.66 172.16.102.65 netmask 255.255.255.255 up

# ifconfig gre0 tunnel 172.16.102.66 172.16.102.65

# route delete 172.16.102.65

ifconfig命令在gre0接口上,增加了一個到路由器(172.16.102.65)的路由表入口。我發現必須刪除該路由,以便squid能與其他路由器會話。

你也許想或必須對來自路由器的GRE包,增加一條ipfw規則:

/sbin/ipfw add allow gre from 172.16.102.65 to 172.16.102.66

9.4.3 OpenBSD

本節的示例基於OpenBSD 3.3。

爲了激活包轉發,在/etc/sysctl.conf文件裏增加該行:

net.inet.ip.forwarding=1
現在,在/etc/pf.conf文件裏增加如下類似行,配置包過濾規則:
rdr inet proto tcp from any to any port = www -> 127.0.0.1 port 3128

pass out proto tcp from 172.16.102.66 to any

pass out proto tcp from any port = 80 to any

pass in proto tcp from any port = 80 to 172.16.102.66

假如你沒有使用OpenBSD的包過濾器,需要在/etc/rc.conf.local文件裏增加一行來激活它:

pf=YES
9.4.3.1 OpenBSD和WCCP

首先,增加如下行到/etc/sysctl.conf文件,告訴系統接受和處理GRE和WCCP包:

net.inet.gre.allow=1

net.inet.gre.wccp=1

然後,用如下命令配置GRE接口:

# ifconfig gre0 172.16.102.66 172.16.102.65 netmask 255.255.255.255 up

# ifconfig gre0 tunnel 172.16.102.66 172.16.102.65

# route delete 172.16.102.65

跟Freebsd一樣,我發現必須刪除ifconfig自動產生的路由。最後,依賴於包過濾器的配置,必須增加一條規則以允許GRE包:

pass in proto gre from 172.16.102.65 to 172.16.102.66

9.4.4 在NetBSD和其他系統上的IPFilter

本節的示例基於NetBSD 1.6.1。它們也能運行在Solaris,HP-UX,IRIX,和Tru64上,既然這些系統本身就配備了IPFilter.

激活NetBSD的包轉發,將如下行加進/etc/sysctl.conf:

net.inet.ip.forwarding=1

然後,將如下行插入NAT配置文件/etc/ipnat.conf中:

rdr fxp0 0/0 port 80 -> 172.16.102.66 port 3128 tcp

你的接口名可能與本例的fxp0不同。

9.4.4.1 NetBSD和WCCP

我不能在NetBSD上運行WCCP,即使打了GRE補丁來接受WCCP包。該問題看起來根源在IPFilter rdr規則阻塞了特定的端口。來自路由器的包通過NetBSD的gre0接口(在這裏它們被解包)。然而,包回到路由器時,走另一條通道,未被封裝並且不走同一網絡接口。這樣,IPFilter代碼沒有將squid的本地IP地址轉換回原始服務器的地址。



9.5 配置Squid

假如你使用Linux 2.4和iptables,在運行./configure時,可使用--enable-linux-netfilter選項。它激活某些Linux的特殊代碼,以發現發起請求的原始服務器的IP地址。Squid正常情況下從Host頭部,得到原始服務器的名字(和/或地址)。--enable-linux-netfilter功能僅對沒有Host頭部的請求來說是必要的。統計顯示幾乎所有的請求有Host頭部,所以實際中可以不使用--enable-linux-netfilter選項。

假如正在使用IPFilter包(NetBSD,Solaris,或其他),因爲同樣的理由,你應該使用--enable-ipf-transparent選項。在OpenBSD上,請使用--enable-pf-transparent選項。每次運行./configure時,必須重編譯squid,見3.8章的描述。

在運行了./configure和重編譯了squid後,可以編輯squid.conf文件。作爲起點,請確認下列指令定義了給定的值:

httpd_accel_host virtual

httpd_accel_port 80

httpd_accel_uses_host_header on

httpd_accel_with_proxy on

httpd_accel_single_host off

http_accel_host指令是關鍵。它指示squid接受包含局部URI的HTTP請求。httpd_accel_uses_host_header被激活,允許squid使用Host頭部來重新構建完整URI。virtual關鍵字指示squid在缺乏Host頭部時,將原始服務器的IP地址放進URL裏。

httpd_accel_with_proxy指令控制squid是否既接受HTTP服務(部分URI)請求,又接受代理(完整URI)請求。在cache攔截裏,它應該被激活。如果沒有用戶明確的配置使用squid做代理,那即使httpd_accel_with_proxy沒被激活,squid也能工作。

httpd_acces_single_host指令正常情況下被禁止,在早期版本的squid裏,它可能被默認激活。在cache攔截裏,它應明確被禁止。

假如攔截不止針對80端口,你也許該將httpd_accel_port設爲0。見附錄A的更多信息。

假如你沒有使用WCCP,就該準備開始發起攔截會話到squid了。通過使用瀏覽器來上網衝浪,或者使用squidclient發起測試請求,就可以放手一試。假如你使用WCCP,那麼還有許多步驟要完成。


9.5.1 配置WCCPv1

路由器不發送任何會話到squid,直到squid宣稱它自己是路由器。爲了讓squid那樣做,在squid.conf中增加如下行:

wccp_router 172.16.102.65

wccp_version 4

路由器有多個接口。請確認使用與squid相連的接口的IP地址。這點是必要的,因爲來自路由器的WCCP消息,將源IP地址設置爲外出接口的地址。假如源地址不匹配wccp_router值,squid會拒絕WCCP消息。

WCCPv1文檔規定4作爲協議版本號。然而,某些用戶報告,Cisco IOS 11.2僅支持協議版本3。假如你使用該版本的IOS,請在squid.conf裏改變版本號:

wccp_version 3


9.6 調試問題

HTTP攔截比較複雜,因爲許多不同設備必須組合正確工作。爲了幫助你跟蹤問題,如下是一個問題解答檢查列表:

  • * 客戶端數據包正在通過路由器/交換機嗎?

  • 在簡單網絡裏,這點顯而易見。你可以trace線纜並觀察指示燈的活動閃爍。然而在大而複雜的網絡,數據包可能走不同的路線。假如你的組織夠大,並有網絡sniffer設備,就可以觀察線路中web客戶端的請求數據包。低技術的方法是,斷開有問題的線路,並觀察是否影響客戶端的web瀏覽。


  • * 路由器/交換機配置是否正確?

  • 你也許要再次檢查路由器/交換機配置。假如你已配置了某個接口,那能否確保它正確呢?是否新的配置真正在設備上運行?也許在你保存配置之前,路由器/交換機已重啓了。在改變生效前,你或許需要reboot設備。


  • * 交換機/路由器能與squid主機會話嗎?

  • 能從路由器/交換機上ping通squid嗎?大部分4層攔截配置要求網絡設備和squid在同一子網裏。登陸路由器/交換機,確認能ping通squid的IP地址。


  • * 交換機/路由器相信squid在運行嗎?

  • 許多傳輸攔截設備不會發送會話到squid,除非它們知道squid是健壯的。使用調試命令來預覽squid的健壯性狀態。也許會發現三層健壯性檢測(例如ICMP ping)比四層檢測(例如HTTP)更容易,它使網絡設備更容易將squid標記爲存活狀態。


  • * Squid實際在運行嗎?

  • 請再次確認squid真正在運行,特別是在系統近期重啓過的情況下。


  • * 數據包正在抵達squid主機嗎?

  • 使用tcpdump能見到攔截的TCP連接。如下是示例:
    # tcpdump -n -i eth0 port 80
    假如使用WCCP,請檢查來自路由器的GRE包:
    # tcpdump -n -i eth0 ip proto gre
    假如沒有看到tcpdump的任何輸出,則路由器/交換機可能沒有發送任何數據。在這種情況下,返回到以前的建議。 注意,假如設備正使用四層健壯性檢測,你可以在tcpdump的輸出裏見到這些。健壯性檢測來自路由器/交換機的IP地址,所以它們容易被認出。假如你見到健壯性檢測,但沒有其他數據,那可能意味着路由器/交換機正把squid的響應理解爲不健壯。例如,設備可能想見到200(OK)響應,但squid返回一個錯誤,例如401(未授權)或404(未發現)。請對access.log運行tail -f命令。


  • * 激活了IP轉發嗎?

  • 請再次確認squid運行的操作系統配置了IP包轉發。假如沒有,主機可能會丟棄攔截數據包,因爲目的IP地址並非本地。


  • * 配置包過濾了嗎?

  • 請確認包過濾器(例如ipfw,iptables,pf等)配置正確。當每件事都運行良好時,你能定期運行命令來顯示過濾規則,並觀察計數器增長。例如:
    # ipfw show 300 ; sleep 3; ipfw show 300
    
    00300  86216 8480458 fwd 127.0.0.1,3128 tcp from any to any 80 in
    
    00300  86241 8482240 fwd 127.0.0.1,3128 tcp from any to any 80 in
    注意該示例在FreeBSD上,包和字節計數器(第二和第三列)正在增長。


  • * 環路接口起來和配置了嗎?

  • 假如有一條規則轉發/重定向包到127.0.0.1,請確認環路接口(例如lo0,lo等)起來了,並配置過它。假如沒有,內核簡單的跳過這條轉發/重定向規則。


  • * WCCP/GRE包被正確解開了嗎?

  • 假如使用WCCP,請確認GRE包被正確解開。假如因爲某些理由,系統不知道該如何處理GRE包,那就在netstat -s的輸出裏會見到"unknown/unsupported protocol"計數器在增長。
    # netstat -s | grep unknown
    
                46 packets for unknown/unsupported protocol
    假如OS有GRE接口,請頻繁運行netstat -i命令,觀察不斷增長的包數量:
    # netstat -in | grep ^gre0
    
    Name    Mtu Network       Address              Ipkts Ierrs    Opkts Oerrs  Coll
    
    gre0   1476 <Link#4>
    
    304452     0        0     4     0
    另外,在GRE接口上運行tcpdump:
    # tcpdump -n -i gre0
  • * Squid能響應客戶端嗎?

  • 有可能路由器/交換機能發送包到squid,但squid不能將包發送回客戶端。這種情況可能發生在:防火牆過濾規則拒絕外出數據包,或squid沒有到客戶端IP地址的路由。爲了檢查這種情況,請運行netstat -n並觀察SYN_RCVD狀態的sockets:
    % netstat -n
    
    
    Active Internet connections
    
    
    Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
    
    
    tcp4       0      0  10.102.129.246.80      10.102.0.1.36260       SYN_RCVD
    
    tcp4       0      0  10.102.129.226.80      10.102.0.1.36259       SYN_RCVD
    
    tcp4       0      0  10.102.128.147.80      10.102.0.1.36258       SYN_RCVD
    
    tcp4       0      0  10.102.129.26.80       10.102.0.2.36257       SYN_RCVD
    
    tcp4       0      0  10.102.129.29.80       10.102.0.2.36255       SYN_RCVD
    
    tcp4       0      0  10.102.129.226.80      10.102.0.1.36254       SYN_RCVD
    
    tcp4       0      0  10.102.128.117.80      10.102.0.1.36253       SYN_RCVD
    
    tcp4       0      0  10.102.128.149.80      10.102.0.1.36252       SYN_RCVD
    假如你看到這些,請使用ping和traceroute來確認squid能與客戶端雙向通信。

  • * Squid能與原始服務器會話嗎?

  • 假如squid不能連接到原始服務器,攔截HTTP連接會無法進行。如果這點發生,netstat會顯示許多連接在SYN_SENT狀態:
    % netstat -n
    
    
    Active Internet connections
    
    
    Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
    
    
    tcp4       0      0  172.16.102.66.5217     10.102.129.145.80      SYN_SENT
    
    tcp4       0      0  172.16.102.66.5216     10.102.129.224.80      SYN_SENT
    
    tcp4       0      0  172.16.102.66.5215     10.102.128.71.80       SYN_SENT
    
    tcp4       0      0  172.16.102.66.5214     10.102.129.209.80      SYN_SENT
    
    tcp4       0      0  172.16.102.66.5213     10.102.129.62.80       SYN_SENT
    
    tcp4       0      0  172.16.102.66.5212     10.102.129.160.80      SYN_SENT
    
    tcp4       0      0  172.16.102.66.5211     10.102.128.129.80      SYN_SENT
    
    tcp4       0      0  172.16.102.66.5210     10.102.129.44.80       SYN_SENT
    
    tcp4       0      0  172.16.102.66.5209     10.102.128.73.80       SYN_SENT
    
    tcp4       0      0  172.16.102.66.5208     10.102.128.43.80       SYN_SENT
    再次用ping和traceroute來確認squid能與原始服務器會話。

  • * 外出連接正被攔截嗎?

  • 假如squid能ping通原始服務器,並且仍然見到大量的連接在SYN_SENT狀態,那麼路由器/交換機可能正在攔截squid的外出TCP連接。在某些情況下,squid能檢測到這種轉發循環,並寫警告日誌到cache.log。如此的轉發死循環能迅速耗光squid的所有文件描述符,這樣也會在cache.log裏產生警告。

假如你懷疑這個問題,請使用squidclient程序來發起一些簡單的HTTP請求。例如,該命令發起一條直接到原始服務器的HTTP請求:

% /usr/local/squid/bin/squidclient -p 80 -h slashdot.org /

假如該命令成功,你可以在屏幕上見到來自Slashdot站點的許多難看的HTML。然後通過squid來試試同樣的請求:

% /usr/local/squid/bin/squidclient -r -p 3128 -h 127.0.0.1 http://slashdot.org/

假如沒有在cache.log裏看到錯誤消息,就可以再次在屏幕上看到一些HTML。假如看到轉發循環錯誤,就必須重新配置交換機/路由器,以便它允許squid的外出連接正常通過,而不被攔截。

 
發佈了12 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章