路由器和防火墻
路由器是一種廣泛運用在IP網(wǎng)段之間的設備,市場(chǎng)上有許多現成的產(chǎn)品。在應用中,我們經(jīng)常將路由器跨接在廣域網(wǎng)和局域網(wǎng)之間,大多數的路由器產(chǎn)品也就是基于這種需要來(lái)設計的。但是隨著(zhù)用戶(hù)IP網(wǎng)絡(luò )的擴展,我們需要一種能夠在多個(gè)以太網(wǎng)絡(luò )之間進(jìn)行尋址的路由器,傳統的路由器產(chǎn)品中偶爾有幾款雙以太網(wǎng)絡(luò )接口的,但是這樣的產(chǎn)品價(jià)格尤其昂貴,而且要是支持快速以太網(wǎng)絡(luò )應用的話(huà)價(jià)格將是天文數字;第三層交換機可以實(shí)現這樣的功能,但是第三層交換機也不是便宜的家伙。
路由器工作的時(shí)候,根據它的某個(gè)端口收到的數據包的目的IP地址,查詢(xún)路由器自己的路由表,然后決定將數據包轉發(fā)到相應的端口。路由器的路由表有幾種:一種是根據路由器自己的每個(gè)端口IP地址和子網(wǎng)掩碼計算出來(lái)的路由,這種路由叫做“固定路由”;第二種是有系統管理員種設置的到某個(gè)子網(wǎng)需要通過(guò)某個(gè)下一級路由器的路由,這種叫“靜態(tài)路由”;還有就是在網(wǎng)絡(luò )環(huán)境中讓每個(gè)路由器都把自己的路由信息廣播出去,讓路由器之間進(jìn)行互相學(xué)習,這樣學(xué)到的路由就叫做“動(dòng)態(tài)路由”。路由器還會(huì )把目的地址不在自己路由表中的數據包固定轉發(fā)給一個(gè)預先設定IP地址,這樣的路由設置又叫“默認路由”。在路由匹配的過(guò)程中,一般有這樣的優(yōu)先級:固定路由>靜態(tài)路由>動(dòng)態(tài)路由>默認路由。
路由器只會(huì )查看IP數據包的目的地址,也就是說(shuō)原則上它是“照單全收”,而且全部轉發(fā),除非真的發(fā)不出去了。如果讓路由器在轉發(fā)數據包的時(shí)候,加一項檢查,檢查數據包的來(lái)源和數據包要求的應用層服務(wù)類(lèi)型,根據預先設計的規則來(lái)判定這個(gè)數據包是應該轉發(fā)還是作別的處理,這樣這個(gè)路由器就不再是一個(gè)單純意義上的路由器,而是一種類(lèi)型的防火墻——包過(guò)濾防火墻。
包過(guò)濾防火墻可以檢查數據包的來(lái)源、源端口、目的地址、目的端口,使用的傳輸層協(xié)議類(lèi)型等項目,根據檢查的項目的內容來(lái)匹配一個(gè)規則表,當符合規則表中的定義的時(shí)候,就執行規則表事先定義的操作。一般來(lái)說(shuō),規則表可以定義這樣的操作:ACCEPT(通過(guò))、NAT(MASQ地址轉換)、DENY(丟棄)、REJECT(拒絕,同時(shí)回送‘不可用’消息給源端)。
當然目前市場(chǎng)上也能買(mǎi)到支持包過(guò)濾防火墻的現成產(chǎn)品,但是價(jià)格問(wèn)題還是我們不得不考慮的重要因素。尤其大多數產(chǎn)品都有許多許可證、性能等方面的限制。
Linux操作系統應運IP網(wǎng)絡(luò )而生,除了Linux價(jià)格上的優(yōu)勢之外,更吸引人的是它內建的強大的網(wǎng)絡(luò )功能,除了做各種Internet上的應用服務(wù)之外,Linux還提供了完整的路由器功能和防火墻功能。而它所帶來(lái)的系統造價(jià)和功能的比例是相當誘人的,為什么不一試呢?
Linux系統的準備
相對于現成的路由器產(chǎn)品,我們把這樣的路由器稱(chēng)為“軟路由器”,當然這樣做出來(lái)的路由器性能絕對不會(huì )比“硬件路由器”的性能差,我們只要明白比如很多“25××”系列的路由器才只是采用25M主頻的摩托羅拉68030CPU(性能相當于Intel 80386)我們就知道了。
用來(lái)做“軟件路由器”的Linux系統主機硬件配置要求并不是太高,用作三五個(gè)局域網(wǎng)之間的路由選擇,數百臺計算機的話(huà),選用奔騰133以上的主機就足夠了,當然現在的市場(chǎng)上賽楊2或者奔騰4或者其他的CPU也不是很貴;配置64M內存,有條件的話(huà)可以配置到128M也無(wú)所謂;硬盤(pán)就不要太大了,否則也是浪費.
關(guān)鍵在于網(wǎng)絡(luò )適配器的配置,Linux系統支持大多數市場(chǎng)上能見(jiàn)到的以太網(wǎng)絡(luò )適配器,PCI卡的安裝比較簡(jiǎn)單,只要內核支持,在開(kāi)機的時(shí)候有多少卡都會(huì )被系統正確的識別出來(lái)。下面是我在實(shí)際使用過(guò)的能夠正常工作的網(wǎng)卡:
★Intel EtherExpress Pro PCI100M
★RealTek 8029/8139 PCI 10M/100M
★D-link 系列 (使用Tulip 2114X驅動(dòng)) PCI 10M
★ACCTON EN1207 (使用Tulip 2114X驅動(dòng)) PCI 100M
★3COM全系列 (PCI/ISA 10M/100M)
★AMD PC-NET 32 PCI 10M
★大部分NE2000兼容網(wǎng)卡,Topstar、Dlink、ACCTON、SN2000等等
★HardLink PCMCIA 筆記本專(zhuān)用網(wǎng)卡 10M
當然Linux能支持的網(wǎng)卡遠遠不止這些。
將網(wǎng)卡驅動(dòng)加掛到Linux中有幾種方法,最常用的是用modprobe系統工具加掛一個(gè)內核模塊,比如加載一個(gè)NE2000兼容網(wǎng)卡的驅動(dòng)可以這樣:
#modprobe ne io=0x300
其實(shí)大多數的PCI網(wǎng)卡并不需要指定IO地址范圍,就像加載一個(gè)ACCTON的EN1207c網(wǎng)卡可以這樣:
#modprobe tulip
將網(wǎng)卡驅動(dòng)編譯到Linux內核中是一種最高效的做法,在編譯Linux內核的時(shí)候,使用
#make menuconfig
代替很多老資料上提到的“#make config”,這樣就會(huì )得到一個(gè)菜單,在菜單中“Network Device”選項下選定指定的網(wǎng)絡(luò )適配器的驅動(dòng)程序,編譯完成以后就會(huì )得到一個(gè)完整的支持相應網(wǎng)卡的Linux內核。
對于很多系統只能識別一個(gè)的網(wǎng)卡,將第二個(gè)以后的網(wǎng)卡參數寫(xiě)在/etc/lilo.conf中是最佳做法,這里有一個(gè)系統中安裝呢4塊網(wǎng)卡,一個(gè)是PCI的RealTek8139,另外3個(gè)是NE2000,這樣的話(huà)系統就識別8139網(wǎng)卡以后就不會(huì )自動(dòng)識別后面的三個(gè)ISA卡,我們需要在/etc/lilo.conf中加上這樣一句:
append=-ether=3,0x240,eth1 ether=11,0x300,eth2 ether=4,0x260,eth3-
在編譯內核的過(guò)程中,我們可以在Network option中選擇“optimizeas router not host”,這樣系統就會(huì )按照路由器而不是主機的方式進(jìn)行優(yōu)化,同時(shí),還可以根據具體的需要選擇上“ Fastswitching”和“ Forwarding between high speed interfaces”以及“ advancedrouter”。如果我們還計劃在這個(gè)機器上實(shí)現包過(guò)濾防火墻,那么選擇上“ firewalling”和“ IP:masquerading”以及與“IP MASQ”相關(guān)的選擇項。
注意查看開(kāi)機的系統提示或者使用dmesg命令可以看到系統是不是正常識別并且啟動(dòng)相應的網(wǎng)卡的驅動(dòng)程序,在上面例子中提到的具有一個(gè)Realtek8139網(wǎng)卡,三個(gè)NE2000網(wǎng)卡的機器上我們能夠看到這樣的情況:
rtl8139.c:v1.07 5/6/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/r tl8139.html eth0: RealTek RTL8139 Fast Ethernet at 0x6000, IRQ 9, 00:e0:4c:dd:5f:85. ne.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov) NE*000 ethercard probe at 0x240: 00 40 05 1f 60 9a eth1: NE2000 found at 0x240, using IRQ 3. NE*000 ethercard probe at 0x300: 00 40 05 22 08 65 eth2: NE2000 found at 0x300, using IRQ 11. NE*000 ethercard probe at 0x260: 00 40 05 23 59 0f eth3: NE2000 found at 0x260, using IRQ 4.
然后是配置每個(gè)網(wǎng)絡(luò )端口的IP地址,當然我們可以使用操作系統的一些對話(huà)框來(lái)配置第一個(gè)網(wǎng)卡的參數,但是一個(gè)有經(jīng)驗的網(wǎng)絡(luò )管理員一般是不這樣做的,因為這樣不能配置其他的網(wǎng)卡,我們必須學(xué)會(huì )用這個(gè)命令來(lái)配置第一塊網(wǎng)卡:
#ifconfig eth0 10.3.3.3 netmask 255.255.255.0 broadcast 10.3.3.255
第二塊網(wǎng)卡的名字就是eth1,其他依次是eth2,eth3等等。由于計算機體系結構的限制,在一個(gè)普通PC主板上只有一個(gè)PCI控制器,而一個(gè)PCI控制器最多只能同時(shí)支持4個(gè)PCI設備,當然某些專(zhuān)用服務(wù)器上可能有支持兩個(gè)以上的PCI控制器。ISA網(wǎng)卡的安裝受到系統中斷號的限制,單CPU的系統中只有16個(gè)可用的IRQ號,扣除硬盤(pán)、內存、鍵盤(pán)、顯示卡等硬件已經(jīng)所剩無(wú)幾,所以一般也是安裝4個(gè)卡,當然,雙CPU的系統可以有256個(gè)中斷號可用,這樣就寬裕了許多。另外,我們還需要打開(kāi)Linux系統的IP轉發(fā)開(kāi)關(guān),這一點(diǎn)非常容易,執行這一條指令:
echo 1 > /proc/sys/net/ipv4/ip_forward
當然這些配置命令最好是放到/etc/rc.d/rc.local中,這樣就不用每次開(kāi)機以后重新配置了。
Linux實(shí)現路由器
正確配置IP地址等參數以后,系統就自動(dòng)計算出了每個(gè)端口所接的子網(wǎng)的固定路由,在這樣的一個(gè)例子中我們可以看到:
我們可以用命令“route -n”或者“netstat -r -n”來(lái)查看系統目前的路由表,在右邊圖二所示的例子中,我們可以得到這樣的路由表:
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.3.2.4 0.0.0.0 255.255.255.252 U 0 0 0 eth0
10.3.2.128 0.0.0.0 255.255.255.128 U 0 0 0 eth3
10.3.253.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
其中Destination項表示目的網(wǎng)絡(luò ),其大小可以通過(guò)子網(wǎng)掩碼(Genmask)計算出來(lái),Flags項表示這個(gè)網(wǎng)段是否直接連接的,“U”就是直接可用的意思,Metric是級跳,Ref是優(yōu)先級參考,UseInterface是連接的端口,Gateway欄目在需要其他路由器轉發(fā)的時(shí)候指明下一級路由器的地址。
使用命令route同時(shí)還可以建立或者刪除一個(gè)靜態(tài)路由,使用這樣的格式:
#route add -net 目標子網(wǎng)地址 netmask 目標子網(wǎng)掩碼 gw 下一級路由器的地址
同理,使用:
#route del -net 目標子網(wǎng)地址 netmask 目標子網(wǎng)掩碼 gw 下一級路由器的地址
可以設置靜態(tài)路由,使用:
#route add default gw 網(wǎng)關(guān)地址
或者:
# route add -net 0.0.0.0 netmask 0.0.0.0 gw 網(wǎng)關(guān)地址
我們把路由設置命令加到/etc/rc.d/rc.local中,以便其能夠在下次啟動(dòng)的時(shí)候自動(dòng)的運行所有路由設置命令。 如下是上面例子中提到的4個(gè)網(wǎng)絡(luò )出口的Linux路由器中的靜態(tài)路由設置命令,這就是在/etc/rc.d/rc.local文件中的片斷:
route add -net 202.102.247.0 netmask 255.255.255.192 gw 172.16.80.82
route add -net 10.56.0.0 netmask 255.255.0.0 gw 172.16.80.10
route add -net 192.168.100.0 netmask 255.255.255.0 gw 172.16.80.86
route add -net 192.168.101.0 netmask 255.255.255.0 gw 172.16.80.88
route add -net 10.68.0.0 netmask 255.255.0.0 gw 10.3.2.129
route add -net 172.28.0.0 netmask 255.255.0.0 gw 172.16.80.82
route add default gw 10.3.2.5 (這一條加的是默認路由)
由這些命令創(chuàng )建的靜態(tài)路由加上原來(lái)由IP地址計算出來(lái)的固定路由以后,路由表就變成了這樣:
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.3.2.4 0.0.0.0 255.255.255.252 U 0 0 0 eth0
202.102.247.0 172.16.80.82 255.255.255.192 UG 0 0 0 eth1
10.3.2.128 0.0.0.0 255.255.255.128 U 0 0 0 eth3
192.168.100.0 172.16.80.86 255.255.255.0 UG 0 0 0 eth1
192.168.101.0 172.16.80.88 255.255.255.0 UG 0 0 0 eth1
10.3.253.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
10.68.0.0 10.3.2.129 255.255.0.0 UG 0 0 0 eth3
172.28.0.0 172.16.80.82 255.255.0.0 UG 0 0 0 eth1
172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
10.56.0.0 172.16.80.10 255.255.0.0 UG 0 0 0 eth1
0.0.0.0 10.3.2.5 0.0.0.0 UG 0 0 0 eth0
做防火墻的系統準備
包過(guò)濾防火墻比起路由器來(lái)說(shuō)就是在轉發(fā)數據包的時(shí)候多了一個(gè)規則表的檢測,按照規則表的定義決定數據包的命運??梢哉f(shuō),路由器其實(shí)就是一個(gè)允許所有數據包正常通過(guò)的“防火墻”。
防火墻還有一個(gè)很重要的功能就是保護一個(gè)內部的子網(wǎng),以及將內部的私有地址轉換成外部的IP地址,這個(gè)功能不但可以對內部網(wǎng)絡(luò )起到保護作用,還可以節省IP地址資源,或者用來(lái)使一個(gè)本來(lái)不能被某設備識別的某網(wǎng)段IP能夠實(shí)現對它的訪(fǎng)問(wèn)。這樣的技術(shù)叫做NAT(網(wǎng)絡(luò )地址翻譯),實(shí)現的方式很多,直接在路由層次上實(shí)現是效率最高的。CISCO的PIX就是這樣技術(shù)的商用產(chǎn)品的代表。Linux的IP-MASQ(IP偽裝)就是這樣技術(shù)在Linux上的一個(gè)實(shí)現。
當一個(gè)主機發(fā)起一個(gè)對其他主機的TCP/IP訪(fǎng)問(wèn),它必須在數據包的報頭中指明對方的IP地址,以及對方提供連接的TCP/UDP端口,同時(shí)它會(huì )打開(kāi)一個(gè)臨時(shí)的端口準備接受返回的數據,然后把它自己的IP地址以及這個(gè)臨時(shí)端口寫(xiě)到IP數據報的報頭中。當一個(gè)數據包被NAT處理的時(shí)候,它的源地址將被替換成防火墻的出端口上的IP(有些防火墻產(chǎn)品使用地址池),同時(shí)NAT防火墻上也會(huì )在出端口上開(kāi)放一個(gè)臨時(shí)端口,將這個(gè)端口號替換數據包中的源端口號。當回應數據到來(lái)的時(shí)候,由于外部的主機只能看到NAT防火墻的IP和端口號,它發(fā)出的數據的目的地址和端口將是防火墻上的,而數據回來(lái)到防火墻以后,防火墻就把原來(lái)的內部主機的地址和端口號替換回來(lái),將數據包轉到內部網(wǎng)絡(luò )上傳送。
而在NAT防火墻上,還需要建立一個(gè)此次地址轉換的對應關(guān)系表。以便知道隨后到來(lái)的源、回應數據包應該被怎樣的替換回來(lái)。
由于包過(guò)濾防火墻的所有操作都是根據規則表來(lái)的,所以規則表就顯得格外的重要。我們使用一個(gè)叫ipchains的工具來(lái)維護系統規則表,ipchains把規則表叫做防火鏈。當一個(gè)數據包進(jìn)入Linux機器時(shí),要通過(guò)進(jìn)入鏈(input)的檢查,當一個(gè)Linux機器準備發(fā)送一個(gè)數據包時(shí),這個(gè)包又要通過(guò)輸出鏈(output)的檢查,當作為路由器使用的時(shí)候,還要點(diǎn)所有中轉的數據包增加一道中轉鏈(forward)的檢查,每個(gè)鏈都可以配置自己的規則表。所以,其實(shí)一個(gè)通過(guò)Linux防火墻的數據包需要經(jīng)過(guò)input、forward、output三個(gè)規則的檢查,當這個(gè)Linux作為普通路由器使用的時(shí)候,三個(gè)鏈的規則都是ACCEPT(允許通過(guò))。
這是一個(gè)需要中轉的數據包通過(guò)ipchains的過(guò)程:
在規則表中,數據包總是先和第一條規則進(jìn)行匹配,如果不匹配在比較下一條規則,一旦某條規則適應了,就不再比較,直接按此規則執行,所以排列在前面的規則總是優(yōu)先與排列在后面的規則。
用ipchains建立規則表
使用命令:
ipchains -P 鏈名 動(dòng)作
可以改變一個(gè)鏈的默認規則,其中可以使用的鏈名有“input”、“forward”、和“output”??梢允褂玫膭?dòng)作有“ACCEPT”、“DENY”、“REJECT”。一般來(lái)說(shuō),默認規則是當一個(gè)數據包不能匹配所有的規則的時(shí)候的最后動(dòng)作,當然這是優(yōu)先級最低的一條規則了。系統默認的三個(gè)鏈的規則都是允許。也就是“ACCEPT”。一般來(lái)說(shuō),我們做防火墻的話(huà),主要是控制通過(guò)防火墻的數據包,所以我們一般在中轉鏈上設置規則,而把進(jìn)入鏈和外出鏈設置為“ACCEPT”。通常我們需要把所有不匹配規則的數據包禁止,所以我們可以用這樣的命令把中轉鏈的默認規則改成“丟棄”:
#ipchains -P forward DENY
增加一條規則使用這樣的語(yǔ)法:
ipchains -A 鏈名 -s 源網(wǎng)絡(luò )/掩碼 -d 目的網(wǎng)絡(luò )/掩碼 -p 傳輸層協(xié)議 端口 -j 動(dòng)作
源網(wǎng)絡(luò )和目的網(wǎng)絡(luò )地址用子網(wǎng)的網(wǎng)絡(luò )地址來(lái)表示,掩碼可以使用點(diǎn)分十進(jìn)制,也可以使用一個(gè)表示“1”的個(gè)數的數字來(lái)代替,比如說(shuō)“255.255.255.0”可以表示為“24”,用“0.0.0.0/0”可以表示所有的地址,用“IP地址/32”表示一個(gè)主機。這個(gè)地方的動(dòng)作可以是“ACCEPT”、“DENY”、“REJECT”,在中轉鏈中要是使用IP偽裝的話(huà),動(dòng)作可以寫(xiě)成“MASQ”。如果不檢查傳輸層協(xié)議(tcp/udp/icmp)的話(huà),就不能再檢查端口號,這時(shí)可以這樣寫(xiě):
ipchains -A 鏈名 -s 源網(wǎng)絡(luò )/掩碼 -d 目的網(wǎng)絡(luò )/掩碼 -j 動(dòng)作
這樣的設置將對所有的符合源地址和目的地址的數據包生效。比如說(shuō)我們現在要設置允許子網(wǎng)10.3.2.0/255.255.255.128和子網(wǎng)202.102.247.0/255.255.255.192的互相訪(fǎng)問(wèn),可以這樣設置:
#ipchains -A forward -s 10.3.2.0/25 -d 202.102.247.0/26 -j ACCEPT
但是在實(shí)際的使用中這樣設置并不會(huì )讓兩個(gè)子網(wǎng)通起來(lái),因為網(wǎng)絡(luò )傳輸是雙向的,只有一個(gè)方向通了還不能算是通,由于forward的默認規則已經(jīng)是DENY,返回的數據包將會(huì )因為匹配不了規則而被丟棄,所以我們需要再設置一條反向的許可規則:
#ipchains -A forward -s 202.102.247.0/26 -d 10.3.2.0/25 -j ACCEPT
其實(shí)我們可以使用-b的選項來(lái)一次設置雙向的兩條規則:這樣的命令等價(jià)于剛才的兩條命令:
#ipchains -A forward -b -s 10.3.2.0/25 -d 202.102.247.0/26 -j ACCEPT
只有一種情況例外,由于IP偽裝回來(lái)的數據包不經(jīng)過(guò)中轉鏈,所以不需要再中轉鏈中只需要為IP偽裝設置一個(gè)單向的規則,比如說(shuō)把所有從10.3.2.0/25來(lái)訪(fǎng)問(wèn)172.16.0.0/16的數據包都做一個(gè)偽裝,那么就可以這樣設置:
#ipchains -A forward -s 10.3.2.0/25 -d 172.16.0.0/16 -j MASQ
而這樣的設置并不需要反向的規則。 這是一個(gè)禁止10.3.2.0/25的網(wǎng)絡(luò )的計算機訪(fǎng)問(wèn)202.102.247.50的telnet端口(TCP23)的設置:
#ipchains -A forward -s 10.3.2.0/25 -d 202.102.247.50/32 -p tcp 23 -j DENY
當然,在進(jìn)入鏈或者在外出鏈上做的規則對于中轉數據一樣有效,這樣的設置可以禁止10.3.2.0/25網(wǎng)段上的IP地址訪(fǎng)問(wèn)OICQ(UDP8000端口):
#ipchains -A input -s 10.3.2.0/25 -d 0.0.0.0/0 -p udp 8000 -j DENY
在進(jìn)入鏈上的規則要優(yōu)先于中轉鏈上的規則,而外出鏈上的規則優(yōu)先級是最低的。刪除規則有兩種做法,一個(gè)是先數出改規則在表中的位置,然后用命令:
#ipchains -D 鏈名 序號
來(lái)刪除它,比如說(shuō)刪除中轉鏈的第5條規則可以這樣寫(xiě):
#ipchains -D forward 5
還有一種辦法就是把建立規則中的“-A”直接改成“-D”來(lái)刪除由這條“-A”的命令創(chuàng )建的規則:
#ipchains -D input -s 10.3.2.0/25 -d 0.0.0.0/0 -p udp 8000 -j DENY
這樣的話(huà)這個(gè)子網(wǎng)的計算機又可以訪(fǎng)問(wèn)OICQ了。而用命令ipchains -F可以清除系統全部的規則表,但是不會(huì )改變鏈的默認規則。
用命令ipchains -L -n可以查看系統目前的規則表:這是前面所說(shuō)的4個(gè)網(wǎng)卡的防火墻實(shí)際的規則表,當然,看起來(lái)它是比較復雜的:
d# ipchains -L -n
Chain input (policy ACCEPT):
target prot opt source destination ports
DENY all ------ 202.102.247.0/25 10.3.2.4 n/a
DENY all ------ 172.16.0.0/16 10.3.2.4 n/a
DENY all ------ 172.16.0.0/16 10.3.253.3 n/a
DENY all ------ 202.102.247.0/25 10.3.253.3 n/a
Chain forward (policy DENY):
target prot opt source destination ports
MASQ all ------ 202.102.247.0/25 10.3.253.1 n/a
ACCEPT all ------ 10.3.2.0/24 10.3.253.0/24 n/a
ACCEPT all ------ 10.3.253.0/24 10.3.2.0/24 n/a
ACCEPT all ------ 10.3.2.0/24 202.102.247.0/25 n/a
ACCEPT all ------ 202.102.247.0/25 10.3.2.0/24 n/a
ACCEPT all ------ 10.3.2.0/24 172.16.0.0/16 n/a
ACCEPT all ------ 172.16.0.0/16 10.3.2.0/24 n/a
ACCEPT all ------ 10.3.253.0/24 172.16.0.0/16 n/a
ACCEPT all ------ 172.16.0.0/16 10.3.253.0/24 n/a
ACCEPT all ------ 10.3.253.0/24 202.102.247.0/25 n/a
ACCEPT all ------ 202.102.247.0/25 10.3.253.0/24 n/a
ACCEPT all ------ 10.3.253.0/24 10.56.0.0/16 n/a
ACCEPT all ------ 10.56.0.0/16 10.3.253.0/24 n/a
ACCEPT all ------ 172.16.0.0/16 202.102.247.0/25 n/a
ACCEPT all ------ 202.102.247.0/25 172.16.0.0/16 n/a
ACCEPT all ------ 10.56.32.0/25 202.102.247.0/25 n/a
ACCEPT all ------ 202.102.247.0/25 10.56.32.0/25 n/a
ACCEPT all ------ 202.102.247.0/25 10.68.0.0/16 n/a
ACCEPT all ------ 10.68.0.0/16 202.102.247.0/25 n/a
ACCEPT all ------ 172.16.0.0/16 10.68.0.0/16 n/a
ACCEPT all ------ 10.68.0.0/16 172.16.0.0/16 n/a
ACCEPT all ------ 10.3.253.0/24 10.68.0.0/16 n/a
ACCEPT all ------ 10.68.0.0/16 10.3.253.0/24 n/a
MASQ all ------ 202.102.247.0/25 10.3.253.1 n/a
MASQ all ------ 172.16.0.0/16 10.3.253.1 n/a
MASQ all ------ 192.168.0.0/16 10.3.253.1 n/a
MASQ all ------ 10.56.32.0/24 10.3.253.1 n/a
MASQ all ------ 202.102.247.0/25 202.102.247.128/25 n/a
MASQ all ------ 172.16.0.0/16 202.102.247.128/25 n/a
MASQ all ------ 192.168.0.0/16 202.102.247.128/25 n/a
MASQ all ------ 10.56.32.0/24 202.102.247.128/25 n/a
MASQ all ------ 172.16.0.0/16 0.0.0.0/0 n/a
MASQ all ------ 10.56.32.0/25 0.0.0.0/0 n/a
MASQ all ------ 192.168.0.0/16 0.0.0.0/0 n/a
ACCEPT all ------ 10.3.253.0/24 0.0.0.0/0 n/a
ACCEPT all ------ 0.0.0.0/0 10.3.253.0/24 n/a
Chain output (policy ACCEPT):
其中,我把對于某些主機的訪(fǎng)問(wèn)限制設置在了進(jìn)入鏈中,這樣優(yōu)先級高一些。同樣我們可以把建立規則的命令寫(xiě)入/etc/rc.d/rc.local中,但是一旦我們把一個(gè)防火墻系統調試成功以后,我們還需要把已經(jīng)建立的規則記下來(lái),重新寫(xiě)到rc.local中,這樣的操作是很容易出錯的。其實(shí)我們可以用命令ipchains-save 把規則表保存到一個(gè)文件,就像這樣:
#ipchains-save >/root/ipchains
把現在正在運行的規則表保存到了/root/ipchains文件當中去了,然后把恢復規則表的命令:
/sbin/ipchains-restore < /root/ipchains
寫(xiě)到/etc/rc.d/rc.local中。
用ipchains-save保存的文件有這樣的格式:
:input ACCEPT
:forward DENY
utput ACCEPT
-A forward -s 172.28.0.0/255.255.0.0 -d 202.102.247.0/255.255.255.128 -j ACCEPT
-A forward -s 172.28.0.0/255.255.0.0 -d 0.0.0.0/0.0.0.0 -j MASQ
要在規則表的中間插入一條規則的時(shí)候,我們可以很方便的編輯它,然后用“ipchains -F”清除運行中的規則表,再用“ipchains-restore < 文件名”來(lái)恢復規則。
設置防火墻中不應該被過(guò)濾的信息
我們設置防火墻的時(shí)候,總是要想辦法過(guò)濾我們所不能識別的東西,但有些信息對于網(wǎng)絡(luò )的運行來(lái)說(shuō)是必須的,一般正常情況下不能被過(guò)濾,否則將影響網(wǎng)絡(luò )的正常運行,而這一點(diǎn)又是初學(xué)的系統管理員經(jīng)常忽略的內容。
ICMP,很多系統管理員過(guò)濾ping,主要使因為可以用ping把一些網(wǎng)絡(luò )線(xiàn)路帶寬比較窄的地方堵塞,為了貪圖省事,就把整個(gè)ICMP過(guò)濾了。但是其實(shí) ICMP 包還被用來(lái)為其它協(xié)議(TCP, UDP)指示錯誤。 如:“destination-unreachable” 等等。這些信息被過(guò)濾的話(huà)意味這你將不會(huì )收到 “Host unreachable”或者“Noroute to host” 等報錯信息, 所有的連接將等待一個(gè)永不會(huì )來(lái)的回復。將會(huì )使客戶(hù)機花費很長(cháng)的一段時(shí)間等候TCP/IP協(xié)議的超時(shí)。這樣做雖然不好, 但還不致命。
一個(gè)更糟的問(wèn)題是 ICMP 包在“MTU(最大傳輸單元)測試”中擔任角色。 為良好的完成 TCP 連接,主機會(huì )使用“ MTU測試”去算出不被分解成片段就可以到達目的地的最大包。“MTU測試”是這樣工作的: 發(fā)送帶有“Don\‘t Fragment(不分解成片段)位”的包, 如果收到 “Fragmentationneeded but DF set(包需要分解成片段)”包,那么就發(fā)送較小的包;如果禁止了ICMP信息,本地主機將不會(huì )減小 MTU,測試就將永遠進(jìn)行或沒(méi)有意義。如果網(wǎng)絡(luò )上存在MTU不一致的網(wǎng)段,這樣將會(huì )極大的影響網(wǎng)絡(luò )性能。
正確過(guò)濾ping的做法是過(guò)濾ICMP的0號和8號端口:
#ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -p icmp 0 -j DENY
#ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -p icmp 8 -j DENY
TCP的53端口,我們知道,一般來(lái)說(shuō)DNS系統翻譯使用的UDP的53端口,但是DNS協(xié)議在UDP不能正常響應的時(shí)候會(huì )自動(dòng)該用TCP協(xié)議來(lái)進(jìn)行連接,如果在一個(gè)全部過(guò)濾TCP所有協(xié)議的網(wǎng)絡(luò )上工作,會(huì )導致所有UDP協(xié)議也得不到正確的域名解析。
有些時(shí)候,FTP協(xié)議會(huì )使用21之外其他的端口來(lái)傳送一些輔助的信息,所以在處理FTP協(xié)議的時(shí)候,我們需要更多的了解FTP的實(shí)現機制。
應用實(shí)例
設置一個(gè)辦公子網(wǎng)能夠訪(fǎng)問(wèn)信息服務(wù)子網(wǎng),但是訪(fǎng)問(wèn)外部需要地址翻譯:
辦公子網(wǎng):192.168.0.0-->192.168.0.255
信息子網(wǎng):202.102.247.0-->202.102.247.63
其中信息子網(wǎng)和Internet互聯(lián),出口網(wǎng)關(guān)地址是202.102.247.33
首先需要在防火墻上設置出口路由:
route add default gw 202.102.247.33
防火鏈的設置如下:
ipchains -P forwar DENY
ipchains -A forward -b -s 192.168.0.0/24 -d 202.102.247.0/26 -j ACCEPT
ipchains -A forward -s 192.168.0.0/24 -d 0.0.0.0/0 -j MASQ
在湖南省xxx高等專(zhuān)科學(xué)校的校園網(wǎng)絡(luò )上,我們一共有9個(gè)子網(wǎng),5個(gè)互聯(lián)出口,中間就使用了Linux+ipchians的防火墻來(lái)進(jìn)行互聯(lián)和訪(fǎng)問(wèn)控制,使用了4臺這樣的主機,有些機器上的路由表和規則表已經(jīng)配置得比較復雜。但系統的投資很小,實(shí)際使用的效果也很好。