上面我們已經創建了一個規則集,使ipfw能夠允許對發出的互聯網請求進行響應,並能進行DNS名字解析。下面我們將仔細調節已經創建的規則集的性能,並通過內置的登錄工具對它進行測試。
創建的規則集已經可以起作用了,因此可以在DHCP規定的時間用完之前使用互聯網連接了。時間用完後,互聯網連接就不能再使用了。要搞清楚是哪條規則實現互聯網連接的,對DHCP的基本工作原理有一定的了解是很有必要的。
DHCP使用UDP數據包,意味著動態規則和狀態表在這裡是不起作用的。因此必須允許在我的計算機和ISP的DHCP服務器之間傳輸UDP數據包。DHCP需要二個端口:DHCP客戶端使用端口68,ISP的DHCP服務器使用端口67。
為了搞明白DHCP的工作原理,我們來看一下我的計算機的DHCP“租用”文件:
more /var/db/dhclient.leases
lease {
interface "ed0";
fixed-address 24.141.119.162;
option subnet-mask 255.255.252.0;
option time-offset -18000;
option routers 24.141.116.1;
option domain-name-servers 24.226.1.90,24.226.1.20,24.2.9.34;
option host-name "my_hostname";
option domain-name "my_domainname";
option broadcast-address 255.255.255.255;
option dhcp-lease-time 604800;
option dhcp-message-type 5;
option dhcp-server-identifier 24.226.1.41;
renew 2 2001/5/15 13:12:11;
rebind 5 2001/5/18 04:12:11;
eXPire 6 2001/5/19 01:12:11;
}
DHCP服務器提供了一個IP地址、子網掩碼、缺省的網關地址、三個DNS服務器的IP地址、我的主機名和提供服務的DHCP服務器的IP地址。由於DHCP“租用”契約是一種真正的“契約”,這意味著我必須保存好這些信息,最後三行內容與我的DHCP客戶端如何重新修改“租用”契約有關。
以renew開頭的這一行向我的DHCP客戶端表明它何時應該結束,並更新其“租用”契約,這一時間要早於expire行中列出的時間。在2001年5月15日13時12分11秒,我的計算機將會向IP地址為24.226.1.41的DHCP服務器上的端口67發送UDP數據包,因此需要添加一條規則允許向外發送UDP數據包。如果DHCP服務器收到了我的計算機發送的UDP數據包,它應該對要求更新“租用”契約的要求作出響應,並且以UDP數據包形式將此信息發回到我的計算機上的68端口。因此,我另外還需要在規則集中添加一規則,允許ipfw對此信息作出反應。
如果不在規則集中添加這些規則,或者由於其他原因DCHP服務器沒有對我的計算機發出的更新“租用”契約的要求作出響應,rebind行將在2001年5月18日4時12分11秒啟動,這時,我的DCHP客戶端就會開始擔心“租用”期滿,將會向DHCP服務器發出更多的UDP數據包,只是這次將不再向特定的DHCP服務器發送數據包,而是會向255.255.255.255發送數據包,任何服務器都可以響應發出的請求。
如果沒有DHCP服務器進行響應,我的計算機的契約會在2001年5月19日1時12分11秒結束,這意味著我的DCHP客戶端不能保證還可以繼續使用這些租用信息。這時,會有幾種情況出現。客戶端將繼續試圖與DHCP服務器聯系,向端口67發送UDP數據包。它將繼續試圖用ping與缺省的網關聯系,檢查其IP地址是否仍然有效。在最壞的情況下,我的客戶端的IP地址已經無效,DHCP服務器的應答將作為廣播被IP地址為255.255.255.255的機器的68端口接收。
既然已經明白了其工作原理,我們就清楚應該在規則集中添加什麼樣的規則了。在添加規則前,應該對規則進行仔細的檢查,因為規則的順序已經越來越重要了。規則集中的規則越多,前面的規則覆蓋後面新添加的規則的可能性也就越大。設計一個好的規則集的訣竅是讓你希望的數據包使用盡可能少的規則,如果添加的規則過多,盡管防火牆仍然會起作用,但這樣會加重ipfw不必要的負擔,因為在找出一個數據包適應的規則前它需要讀取更多的規則。此外,在你希望搞清楚到底是哪一條規則使系統不能按你的意願運行時,規則太多了會相當的麻煩。
我將以超級用戶的身份運行ipfw show命令檢查當前的規則:
su
PassWord:
ipfw show
00100 0 0 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 check-state
00301 0 0 deny tcp from any to any in established
00302 0 0 allow tcp from any to any keep-state setup
00400 0 0 allow udp from 24.226.1.90 53 to any in recv ed0
00401 0 0 allow udp from 24.226.1.20 53 to any in recv ed0
00402 0 0 allow udp from 24.2.9.34 53 to any in recv ed0
00403 0 0 allow udp from any to any out
65535 0 0 deny ip from any to any
由於我需要向外發送UDP數據包,因此需要指明DHCP端口號和DHCP服務器的IP地址,作為超級用戶,我將考慮在/etc/ipfw.rules文件中添加下面的內容:
#allow DHCP
add 00500 allow udp from any 68 to 24.226.1.41 67 out via ed0
add 00501 allow udp from 24.226.1.41 67 to any 68 in via ed0
這些規則可以說是使DHCP客戶端更新其“租用”契約所需要的最少的規則了,是否需要添加更多的規則會因DHCP服務器可靠性的不同而有所不同。如果DHCP服務器總是能夠響應我的更新請求,我也就無需采用發送UDP廣播、ping缺省的網關或者接收UDP廣播這些方式了。如果DHCP服務器的可靠性不高,那就還需要添加下面的規則:
add 00502 allow udp from any 68 to 255.255.255.255 67 out via ed0
add 00503 allow udp from any 67 to 255.255.255.255 68 in via ed0
由於我使用的DHCP服務器是相當可靠的,因此不需要立即添加00502和00503這二條規則。我只是反復提醒自己,在ISP的DHCP服務器出了問題或其IP地址有變化的時候就需要考慮這二條規則了。
在保存修改之前,我將把00500和00501二條規則與其余的規則進行比較,以確保它們之間沒有任何沖突和重復之處,結果00403和00500之間確實存在著部分重復:
add 00403 allow udp from any to any out
add 00500 allow udp from any 68 to 24.226.1.41 67 out via ed0
因為規則00403允許我的計算機發出任何的UDP數據包,ipfw就不會讀取其他的只從端口68發送UDP數據包的規則,在這裡,就需要在使用數量最少的規則還是使用把各種可能都考慮在內的數量最多的規則之間進行選擇了。
規則00403是在創建允許DNS解析時添加的,如果刪除了它,就需要添加三條規則才能實現向三個DNS服務器發送UDP數據包的功能。另外,如果還需要向其他的服務器發送UDP數據包,我就必須再添加規則。因此,如果不使用這樣一條“通用”的規則,ipfw規則集中就會包含一些多余的規則,使系統負擔不必要的負荷。
這樣作也不符合使用最少數量規則的原則,但我們必須仔細審查一下“通用”規則帶來的潛在後果。如果我限制系統接受UDP數據包,向外發送UDP數據包是不會有什麼危險的。例如,規則00403允許我的計算機向外發送任何數據包,但規則00400、00401、0402和00501保證我的計算機只能接受我的ISP的3台DNS和一台DHCP服務器發送的UDP數據包。因此,對於我的單獨運行的FreeBSD計算機而言,這個規則集還是比較合理的。
如果我在FreeBSD防火牆後面添加新的客戶端機器,就需要重新考慮這個規則集。例如,微軟的客戶端會發送數量不等的UDP數據包通報其共享資源,讓這些數據包通過防火牆發送出去,對我而言是不負責任並具有一定安全風險的。在本例中,我將使用只能發出我需要發出的UDP數據包的規則,而刪除可以發出任意UDP數據包的規則。
由於我現在保護的只是一台單獨的FreeBSD計算機,因此我將保留規則00403,刪除規則00500,因為系統永遠都不會讀取到它。我將對規則進行如下的改變:
#允許DHCP 操作
add 00501 allow udp from 24.226.1.41 67 to any 68 in via ed0
保存所作的改變,並通過使用killall init命令進行測試,以超級用戶身份重新登錄,看看所作改變的效果。
su
Password:
ipfw show
00100 0 0 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 check-state
00301 0 0 deny tcp from any to any in established
00302 0 0 allow tcp from any to any keep-state setup
00400 8 1322 allow udp from 24.226.1.90 53 to any in recv ed0
00401 0 0 allow udp from 24.226.1.20 53 to any in recv ed0
00402 0 0 allow udp from 24.2.9.34 53 to any in recv ed0
00403 8 469 allow udp from any to any out
00501 4 1592 allow udp from 24.226.1.41 67 to any 68 in recv ed0
65535 29 8591 deny ip from any to any
我好象從IP地址為24.226.1.90的DNS服務器收到了8個UDP數據包,從IP地址為24.226.1.41的DHCP服務器收到了4個UDP數據包。現在,我們再來看看DHCP的“租用”時間問題。
more /var/db/dhclient.leases
renew 3 2001/5/16 07:46:25;
rebind 5 2001/5/18 08:50:46;
expire 6 2001/5/19 01:12:14;