欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

第十四章 NAT 及防火墻

14.1 概論

這個部份我們將說明如何以 FreeBSD 做為防火墻,介紹 FreeBSD 內建的封包過濾功能。欲建立一臺防火墻,就是要將一臺機器放在二個網域的中間,并經由它來做封包過濾的工作。 因此我們必須先確定網絡封包能通過這臺防火墻,再來設定要阻文件的規(guī)則。以 FreeBSD 作為二個網域中間的連接器,可以用路由器 (router)、網關、或是橋接器的方式來實作,再在該機器上設定防火墻的規(guī)則。當然,我們也可以只在一臺單機上設定防火墻規(guī)則,以取代原本只能監(jiān)控 inetd 服務的 TCP Wrapper。

我們舉二種最常被應用結合防火墻設定來保護整個網絡的方法,一個是 NAT,另一個是具封包過濾的橋接器。

14.1.1 NAT

所謂的 NAT 就是 (Network Address Translation),它可以讓你在只有一個 IP 的情形下讓多臺計算機一起連上網絡。舉個實例而言,一個公司有三十臺計算機,而 ISP 所提供的 ADSL 卻只有八個實體 IP,這種情況下,我們可以將每臺計算機的 IP 設定為 private IP,再讓它們經由一臺有實體 IP 的 NAT 服務器連上網絡即可。

Private IP 是 RFC 所定義的私人 IP,這些 IP 不能夠直接在因特網中出現,所以必需經由 NAT 的轉換,將它們偽裝成是由 NAT 服務器連向外部網絡。這些可以用的私人 IP 如下:

Class 范圍 子網掩碼
Class A 10.0.0.0 ~ 10.255.255.255 255.0.0.0
Class B 172.16.0.0 ~ 172.31.255.255 255.255.0.0
Class C 192.168.0.0 ~ 192.168.255.255 255.255.255.0

我們只需在 NAT 服務器中做好設定,再將其它使用 private IP 的計算機設定 gateway 為該服務器的 IP 即可。另外,我們也可以在服務器中設定一些防火墻的規(guī)則,來保全內部網絡。

14.1.2 具封包過濾的橋接器

如果我們的網絡中有多臺不同網域的計算機,這些計算機都有它們的 IP 及網絡設定,我們可以將 FreeBSD 設定成為橋接器 (bridge),讓這臺橋接器作封包過濾的工作。這種做法對于網域內其它計算機原本的網絡設定不會有影響,如果沒有設定任何防火墻規(guī)則,對它們而言幾乎不會發(fā)現橋接器的存在。我們可以使用橋接器來過濾同一個網域內的網絡交通,如果您有一個很大的網域,想要降低同一網域內彼此網絡封包的交互影響,卻又不想將這個大網域分割成數個小網域,您可以使用具封包過濾功能的橋接器來達成網絡封包分割的功能。
我們也可以使用路由器來取代橋接器,但是路由器只能遶送二個不同網域,而且設定比較復雜,因此,我會使用橋接器來做為防火墻。
FreeBSD 內建有 ipfw 這個程序可以讓我們輕易的設定一個簡單的防火墻,我們只要在 kernel 中加上一些設定就可以打開它。在這里我們也將簡單的介紹一些防火墻的語法,讓我們可以保護我們不想、不需要被外界使用的網絡服務。

在設定防火墻之前,有個觀念必須先厘清。防火墻并不能夠完全保護我們的網絡安全,防火墻只是限制我們不想公開的服務、限制已知的 IP。就算架了防火墻,沒有適當的管理也是枉然。

14.2 NAT

這里我們假設使用二張網絡卡,一張是對外的網卡,代號是 vr0;另一張是對內的網卡,代號 vr1。以下的設定中請依您的網卡代號來加以修改。當然,你也可以只使用一張網絡卡,將所有的計算機及對外網絡都接在一臺 HUB 上,再利用 alias 的功能將一張網卡設定二個 IP。

14.2.1 設定 kernel

請先在 kernel 中加入下列幾行,并重新編譯 kernel,如果您不知道如何修改 kernel,請參考第四章「編譯核心」。 假設我們要修改的 kernel 是 /usr/src/sys/i386/conf/GENERIC,先 cd /usr/src/sys/i386/conf/,再 ee GENERIC 加入下列幾行:

# 防火墻
options	IPFIREWALL
# 支援 nat
options	IPDIVERT
# 下面這一行是預設允許所有封包通過,如果沒有這一行,就必須在
# /etc/rc.firewall 中設定封包的規(guī)則。
options	IPFIREWALL_DEFAULT_TO_ACCEPT
# 下面這一行是讓你可以在 ipfw 中設定要記錄哪些封包,
# 如果沒有這一行,就算設定了要留下記錄也不會有作用。
options	IPFIREWALL_VERBOSE

存盤后,請重新編譯并安裝新的 kernel,重開機之后核心就己經支持防火墻及 NAT 了。

14.2.2 設定 rc.conf

接著要修改 /etc/rc.conf 加入下列幾行,我們假設網絡卡代號是 vr0 及 vr1,請自行變更成您的網絡卡代號:

# 對外網絡的設定,假設 IP 是 123.44.55.66
ifconfig_vr0="inet 123.44.55.66 netmask 255.255.255.0"

# NAT 的設定
ifconfig_vr1="inet 192.168.0.1  netmask 255.255.255.0"
# 如果只使用一張網絡卡的話,改用下面這一行
#ifconfig_vr0_alias0="inet 192.168.0.1 netmask 255.255.255.0"

gateway_enable="YES"
firewall_enable="YES"
firewall_type="OPEN"
natd_interface="vr0"
natd_enable="YES"

設定結束之后,重開機應該就可以設定其它計算機使用這臺 NAT 服務器來連上網絡了。如果不行,請先檢查 /etc/service 中是不是有下面這一行:

natd   8668/divert

還是不行的話,就是還要再修改 /etc/rc.firewall。我們在 /etc/rc.conf 中設定 firewall_type="OPEN",如果是使用原本 /etc/rc.firewall 的話,這樣就已經就已經驅動了 NAT 的功能,不然的話,請再看下列 firewall 的設定。

14.2.3 設定 rc.firewall

為了使 NAT 能運作,必須編輯 /etc/rc.firewall ,另外我們也可以在 rc.firewall 中加入一些防火墻的設定,來阻擋一些機器或服務。在我們進行修改之前,請先備份原本的 rc.firewall,再將 rc.firewall 的內容修改如下:

#!/bin/sh
# 清除所有的規(guī)則
/sbin/ipfw -f flush
# 在此加入拒絕的規(guī)則,以下二行為拒絕連的的范例
/sbin/ipfw deny log all from 61.55.121.1 to any
/sbin/ipfw deny log all from any to 61.55.121.1
# NAT
/sbin/ipfw add divert natd all from any to any via vr0
# 允許其它所有封包通過
/sbin/ipfw add pass all from any to any 

修改完后,執(zhí)行 sh /etc/rc.firewall 就可以更新防火墻的設定了。其它關于防火墻規(guī)則的詳細說明,請 man ipfw 或參考下一節(jié)的說明。

14.2.4 client 端的設定

接者是 client 端方面,除了上述的 NAT 設定外,在其它計算機還要再做一些設定。首先,你的網絡架構應該如圖 14-1 所示:

圖 14-1

其它的計算機設定方面,我們必須將其它計算機的 IP 設定為 192.168.0.X、子網掩碼是 255.255.255.0,gateway 設定為 FreeBSD 連到局域網絡的網絡卡 IP,在此范例中是 192.168.0.1。然后再設定你的 DNS 為你 ISP 的 DNS。

完成上述的設定后,我們就能享受以 FreeBSD 為NAT上網了。

14.2.5 NAT Port Forwarding

NAT 還有一個功能叫作 Port Forwarding,它的用途在于從連到本機的封包導向到別的計算機或本機其它連接埠。例如,我們對外有一臺防火墻,在 DNS 設定方面,我們設定了 ftp.mydomain.com 及 www.mydomain.com 都指向這臺防火墻。但我們希望所有 HTTP 聯機都重新導向到內部的 192.168.0.2 這臺機器上,而所有 FTP 聯機都交由 192.168.0.3 來處理。這時候我們就可以使用 port forwarding 的方式來達成。

首先,我們知道 HTTP 使用 TCP 協(xié)議 port 80,而 FTP 使用了 TCP 協(xié)議 port 20 及 port 21,接著我們就可以在 /etc 目錄下新增一個 NAT 的設定檔,名為 natd.conf,并編輯內容如下:

redirect_port tcp 192.168.0.2:80 80
redirect_port tcp 192.168.0.3:20 20
redirect_port tcp 192.168.0.3:21 21

第一行的目的就是將 port 80 的 tcp 聯機重新導向到 192.168.0.2 的 port 80,而二、三行是將 port 20 及 port 21 的聯機交由 192.168.0.3 來處理。在 192.168.0.2 及 192.168.0.3 這二臺機器上,我們只要設定它們的 gateway 為防火墻的 IP,例如 192.168.0.1 即可。

接下來我們必須在 /etc/rc.conf 中加入下列這一行,讓 natd 在啟動時能讀取 /etc/natd.conf 的設定:

natd_flags="-f /etc/natd.conf"

重新啟動后,您就可以進行測試了。假設防火墻的對外 IP 是 11.22.33.44,當我們從外部網絡使用 HTTP 聯機到該 IP 時,隨然該服務器并未架設 HTTP server,但你卻可以看到網頁,表示網絡封包有被重導至內部的另一臺服務器。

14.3 防火墻

ipfw 是 FreeBSD 內建的防火墻指令,我們可以用它來管理進出的網絡交通。如果防火墻服務器是扮演著路由器 (gateway 例如上一篇中的 NAT 服務器) 的角色,,則進出的封包會被 ipfw 處理二次,而如果防火墻扮演的是橋接器 (bridge) 的角色,則封包只會被處理一次。這個觀念關系著我們以下所要介紹的語法,有的語法并不適用于橋接器。

我們會將 firewall 的設定寫在 /etc/rc.firewall 中,每一條設定都是以先入為主 (first match wins) 的方式來呈現,也就是先符合的規(guī)則 (rules) 為優(yōu)先。所有進出的封包都會被這些規(guī)則過濾,因此我們會盡量減少規(guī)則的數量,以加速處理的速度。

在 kernel 中,關于防火墻的設定有下列幾條:

# 防火墻
options	IPFIREWALL

# 下面這一行是預設允許所有封包通過,如果沒有這一行,
# 就必須在 /etc/rc.firewall 中設定封包的規(guī)則。
# 這條規(guī)則內定編號是 65535,也就是所有規(guī)則的最后一條
# 如果沒有加這一條規(guī)則,內定就是拒絕所有封包,
# 只允許規(guī)則中允許的封包通過。
options	IPFIREWALL_DEFAULT_TO_ACCEPT

# 這一行是讓你可以在 ipfw 中設定要記錄哪些封包,
# 如果沒有這一行,就算設定了要留下記錄也不會有作用。
options	IPFIREWALL_VERBOSE

# 這一行是限制每一條規(guī)則所要記錄的封包數量,
# 因為同樣的規(guī)則可能有許多記錄,加上這一條可以使
# 同樣的記錄重復數減少,以避免記錄文件爆增。
options IPFIREWALL_VERBOSE_LIMIT=10

# 下面這一行是用來支援封包轉向,
# 當你要使用 fwd 動作時必須要有這一項設定。
#options IPFIREWALL_FORWARD

# 如果要使用 pipe 來限制頻寬,必須加入下列選項以支持 dummynet。
 options DUMMYNET

ipfw 也支持狀態(tài)維持 (keep-state) 的功能,就是可以讓符合設定的規(guī)則以動態(tài)的方式來分配增加規(guī)則 (地址或連接端口) 來讓封包通過。也就是說防火墻可以記住一個外流的封包所使用的地址及連接端口,并在接下來的幾分鐘內允許外界響應。這種動態(tài)分配的規(guī)則有時間的限制,一段時間內會檢查聯機狀態(tài),并清除記錄。

所有的規(guī)則都有計數器記錄封包的數量、位數、記錄的數量及時間等。而這些記錄可以用 ipfw 指令來顯示或清除。

在說明 ipfw 規(guī)則的語法之前,我們先來看這個指令的用法。ipfw 可以使用參數:

指令 說明
ipfw add [rule] 新增一條規(guī)則。規(guī)則 (rule) 的語法請參考下一節(jié)的說明。
ipfw delete [number] 刪除一條編號為 number 的規(guī)則。
ipfw -f flush 清除所有的規(guī)則。
ipfw zero 將計數統(tǒng)計歸零。
ipfw list 列出現在所有規(guī)則,可以配合下列參數使用。
-a 使用 list 時,可以列出封包統(tǒng)計的數目。
-f 不要提出確認的詢問。
-q 當新增 (add)、歸零(zero)、或清除 (flush) 時,不要列出任何回應。當使用遠程登入,以 script (如 sh /etc/rc.firewall) 來修改防火墻規(guī)則時,內定會列出你修改的規(guī)則。但是當下了 flush 之后,會立即關掉所有聯機,這時候響應的訊息無法傳達終端機,而規(guī)則也將不被繼續(xù)執(zhí)行。此時唯一的方法就是回到該計算機前重新執(zhí)行了。在修改防火墻規(guī)則時,最好在計算機前修改,以免因為一個小錯誤而使網絡聯機中斷。
-t 當使用 list 時,列出最后一個符合的時間。
-N 在輸出時嘗試解析 IP 地址及服務的名稱。
-s [field] 當列出規(guī)則時,依哪一個計數器 (封包的數量、位數、記錄的數量及時間) 來排序。

14.3.1 ipfw 規(guī)則

我們在過濾封包時,可以依據下列的幾個封包所包含的信息來處理該封包:

使用 IP 地址或 TCP/UDP 的端口號來做為規(guī)則可能蠻危險的,因為這二種都有可能被以假的信息所蒙騙 (spoof)。但是這二種卻也是最常被使用的方法。

下列為 ipfw rules 的語法:

[number] action [log] proto from src to dist [interface_spec] [option]

使用 [ ] 包起來的表示可有可無,我們一一為大家說明它們的意義:

number:

number 是一個數字,用來定義規(guī)則的順序,因為規(guī)則是以先入為主的方式處理,如果你將規(guī)則設定放在一個檔案中 ( 如 /etc/rc.firewall ),規(guī)則會依每一行排列的順序自動分配編號。你也可以在規(guī)則中加上編號,這樣就不需要按順序排列了。如果是在命令列中下 ipfw 指令來新增規(guī)則的話,也要指定編號,這樣才能讓規(guī)則依我們的喜好排列,否則就會以指令的先后順序來排。這個編號不要重復,否則結果可能不是你想要的樣子。

action:

action 表示我們這條規(guī)則所要做的事,可以用的 action 有下列幾個:

命令 意義
allow 允許的規(guī)則,符合則通過。也可以使用 pass,permit, accept 等別名。
deny 拒絕通過的規(guī)則。
reject 拒絕通過的規(guī)則,符合規(guī)則的封包將被丟棄并傳回一個 host unreachable 的 ICMP。
count 更新所有符合規(guī)則的計數器。
check-state 檢查封包是否符合動態(tài)規(guī)則,如果符合則停止比對。若沒有 check-state 這條規(guī)則,動態(tài)規(guī)則將被第一個 keep-state 的規(guī)則所檢查。
divert port 將符合 divert sock 的封包轉向到指定的 port。
fwd ipaddr[,port] 將符合規(guī)則封包的去向轉向到 ipaddr,ipaddr 可以是 IP 地址或是 hostname。如果設定的 ipaddr 不是直接可以到達的地址,則會依本機即有的 routing table 來將封包送出。如果該地址是本地地址 (local address),則保留本地地址并將封包送原本指定的 IP 地址。這項設定通常用來和 transparent proxy 搭配使用。例如:
# ipfw add 50000 fwd 127.0.0.1,3128 tcp from \
  192.168.1.0/24 to any 80

如果沒有設定 port ,則會依來源封包的 port 將封包送到指定的 IP。使用這項規(guī)則時,必須在 kernel 中設定選項 IPFIREWALL_FORWARD。

pipe pipe_nr 傳遞封包給 dummynet(4) "pipe",用以限制頻寬。使用本語法必須先在核心中加入 option DUMMYNET。請 man ipfwman dummynet。
基本語法是先將要設定頻寬的規(guī)則加入:
ipfw add pipe pipe_nr ....

再設定該規(guī)則的頻寬:

ipfw pipe pipe_nr config bw B delay D queue Q plr P

這里的 pipe_nr 指的是 pipe 規(guī)則編號,從 1~65535;B 是指頻寬,可以表示為 bit/s、Kbit/s、Mbit/s、Bytes/s、KBytes/s、或 MBytes/s。D 是延遲多少 milliseconds (1/1000)。Q 是 queue size 的大小 (單位為 packages 或 Bytes)。P 是要隨機丟棄的封包數量。

例如我們要限制內部網域的計算機對外上傳的最大頻寬是 20 KBytes:

ipfw add pipe 1 ip from 192.168.0.1/24 to any in
ipfw pipe 1 config bw 20KBytes/s

log:

如果該規(guī)則有加上 log 這個關鍵詞,則會將符合規(guī)則的封包記錄在 /var/log/security 中。前提是在核心中有設定 IPFIREWALL_VERBOSE 的選項。有時因為同樣的封包太多,會使記錄文件保有大量相同的記錄,因此我們會在核心中再設定 IPFIREWALL_VERBOSE_LIMIT 這個選項,來限制要記錄多少相同的封包。

proto:

proto 表示 protocol,即網絡協(xié)議的名稱,如果使用 ip 或 all 表示所有協(xié)議??梢允褂玫倪x項有 ip,all,tcp,udp,icmp 等。

src 及 dist:

src 是封包來源;dist 是封包目的地。在這二個項目可以用的關鍵詞有 any, me, 或是以 <address/mask>[ports] 的方式明確指定地址及端口號。

若使用關鍵詞 any 表示使這條規(guī)則符合所有 ip 地址。若使用關鍵詞 me 則代表所有在本系統(tǒng)接口的 IP 地址。而使用明確指定地址的方式有下列三種:

子網掩碼 (/bits) 意義
/27 1/8th of a Class C 32 hosts
/26 1/4th of a Class C 64 hosts
/25 1/2 of a Class C 128 hosts
/24 1 Class C 256 hosts
/23 2 Class C 512 hosts
/22 4 Class C 1,024 hosts
/21 8 Class C 2,048 hosts
/20 16 Class C 4,096 hosts
/29 32 Class C 8,192 hosts
/18 64 Class C 16,384 hosts
/17 128 Class C 32,768 hosts
/16 256 Class C 65,536 hosts (= 1 Class B)
/15 512 Class C 131,072 hosts
/14 1,024 Class C 262,144 hosts
/13 2,048 Class C 524,288 hosts

而在 me, any 及 指定的 ip 之后還可以再加上連接埠編號 (ports),指定 port 的方法可以是直接寫出 port ,如 23;或給定一個范圍,如 23-80;或是指定數個 ports,如 23,21,80 以逗點隔開?;蛘呤菍懗鲈?/etc/services 中所定義的名稱,如 ftp,在 services 中定義是 21,因此寫 ftp 則代表 port 21。

interface-spec:

interface-spec 表示我們所要指定的網絡接口及流入或流出的網絡封包。我們可以使用下列幾個關鍵詞的結合:

關鍵詞 意義
in 只符合流入的封包。
out 只符合流出的封包。
via ifX 封包一定要經過接口 ifX,if 為接口的代號,X 為編號,如 vr0。
via if* 表示封包一定要經過接口 ifX,if 為接口的代號,而 * 則是任何編號,如 vr* 代表 vr0,vr1,...。
via any 表示經過任何界面的封包。
via ipno 表示經過 IP 為 ipno 界面的封包。

via 會使接口永遠都會被檢查,如果用另一個關鍵詞 recv ,則表示只檢查接收的封包,而 xmit 則是送出的封包。這二個選項有時也很有用,例如要限制進出的接口不同時:

ipfw add 100 deny ip from any to any out recv vr0 xmit ed1

recv 接口可以檢查流入或流出的封包,而 xmit 接口只能檢查流出的封包。所以在上面這里一定要用 out 而不能用 in,只要有使用 xmit 就一定要使用 out。另外,如果 via 和 recv 或 xmit 一起使用是沒有效的。

有的封包可能沒有接收或傳送的接口:例如原本就由本機所送出的封包沒有接收接口,而目的是本機的封包也沒有傳送界面。

options:

我們再列出一些常用的 option 選項 ,更多選項請 man ipfw

選項名稱 意義
keep-state 當符合規(guī)則時,ipfw 會建立一個動態(tài)規(guī)則,內定是讓符合規(guī)則的來源及目的地使用相同的協(xié)議時就讓封包通過。這個規(guī)則有一定的生存期限 (lift time,由 sysctl 中的變量所控制),每當有新的封包符合規(guī)則時,便用重設生存期限。
bridged 只符合 bridged 的封包。
established 只適用于 TCP 封包,當封包中有 RST 或 ACK bits 時就符合。
setup 只適用于 TCP 封包,當封包中有 SYN bits 時就符合。

以上的說明只是 man ipfw 中的一小部份。如果你想要對 ipfw 更了解,例如如何使用 ipfw 來限制頻寬等,建議你 man ipfw

不知道您看了這么多的規(guī)則是否覺得眼花撩亂,如果不了解 TCP/IP 的原理,徹底了解 ipfw 的設定還真不容易。沒關系,我們下面將舉幾個簡單、常用的設定,這些范例應該夠平常使用了。

14.3.2 范例

我將原本的 /etc/rc.firewall 備份成 rc.firewal.old,并將它改成下列內容,請注意,這里只是范例,只供參考:

# 設定我的 IP
myip="1.2.3.4"
# 設定對外的網絡卡代號
outif="vr0"
# 設定對內的網絡上代號
inif="vr1"
#清除所有的規(guī)則
/sbin/ipfw -f flush
# Throw away RFC 1918 networks
${ipfw} add deny ip from 10.0.0.0/8 to any in via ${oif}
${ipfw} add deny ip from 172.16.0.0/12 to any in via ${oif}
${ipfw} add deny ip from 192.168.0.0/16 to any in via ${oif}
# 只允許內部網絡對 192.168.0.1 使用 telnet 服務
/sbin/ipfw add 200 allow tcp from 192.168.0.1/24 to 192.168.0.1 telnet
# 拒絕其它人連到 port 23,并記錄嘗試聯機的機器
/sbin/ipfw add 300 deny log tcp from any to me 23
# 拒絕任何 ICMP 封包
/sbin/ipfw add 400 deny icmp from any to any

# 下面這臺機器是壞人,不讓它進來,并記錄下來
/sbin/ipfw add 1100 deny log all from 211.21.104.102 to any
# NAT 的設定
/sbin/ipfw add divert natd all from any to any via vr0
# 限制內部網域對外下載最大頻寬為 20KBytes/s,上傳最大頻寬為 5KBytes/s
ipfw pipe 20 config bw 20KBytes/s
ipfw add pipe 20 ip from any to 192.168.0.1/24 out
ipfw pipe 30 config bw 5KBytes/s
ipfw add pipe 30 ip from 192.168.0.1/24 to any in
# 允許本機對任何地方聯機
/sbin/ipfw add check-state
/sbin/ipfw add 2000 allow udp from ${myip} to any keep-state
/sbin/ipfw add 2100 pass ip from ${myip}  to any

# 允許外界使用郵件服務
/sbin/ipfw add 3000 pass tcp from any to ${myip} 25 in via ${outif}

# 不允許內部的 IP 從外部連進來
/sbin/ipfw add 1200 add deny ip from ${myip}/24 to any in via ${oif}

# 其它都拒絕,如果沒有在 kernel 中設定
# IPFIREWALL_DEFAULT_TO_ACCEPT 則內定就有下列這一條
/sbin/ipfw 65535 add deny all from any to any

存盤后就可以使用 sh rc.firewall 來執(zhí)行新的規(guī)則了。如果您將規(guī)則放在 /etc/rc.firewall 中,則開機時會自動執(zhí)行。

14.3.3 一些小建議

在建立一個封包過濾的防火墻時,應該盡可能阻擋一些不必要的服務。避免開放 port 1024 以下的 TCP 服務,例如只通過 SMTP 封包 (port 25) 給郵件服務器;拒絕所有 UDP 聯機 (只有少部份服務如 NFS 會用到);一些只有內部才會使用的服務,如數據庫等也不必對外開放。

另外,同樣的防火墻限制可以使用不同的語法來展現,應該要試著讓規(guī)則數量越少越好,以加快處理速度。

在更新 firewall 規(guī)則時,如果規(guī)則沒有寫好,而你又是以遠程登入的方式修改規(guī)則,很可能會因此無法繼續(xù)登入。因此建議更新規(guī)則時最好在 console 前執(zhí)行,若迫不得已一定要使用遠程登入,建議您執(zhí)行 /usr/share/examples/ipfw/change_rules.sh 這支程序來編輯規(guī)則:

# cd /usr/share/examples/ipfw
# sh change_rules.sh

接著會出現文書編輯軟件并最動加載 /etc/rc.firewall 讓你編輯,結束離開后,會詢問是否要執(zhí)行更新。如果執(zhí)行新的規(guī)則后造成斷線,它會自動加載舊的規(guī)則,讓我們可以再次聯機。

14.4 封包過濾橋接器

當我們的內部網絡有不同 class 的主機時,例如內部有 140.115.2.3 及 140.115.5.6 這二臺計算機時,就無法使用傳統(tǒng)的防火墻。如果要在這二臺機器連到因特網中途中使用防火墻,我們必須使用新的方式,就是這里要介紹的橋接器。

我們可以使用 FreeBSD 為橋接器,利用它來做封包過濾的動作,而絲毫不影響內部的主機原本的設定。為了達到這個功能,我們必需要有二張支持 promiscuous mode 的網絡卡,現在的網絡卡大部份都有支持。二張網絡卡當中,一張需要設定 IP,另一張不需要。至于您要將 IP 設定在哪一張卡都可以,建議是設在對外的網絡卡上。

首先,我們必須在核心中加入關于橋接器的設定:

# 支援橋接器
options BRIDGE
# 防火墻設定
options IPFIREWALL
options IPFIREWALL_VERBOSE
# 我們這里不將防火墻預設為接收所有封包
#options IPFIREWALL_DEFAULT_TO_ACCEPT

重新編譯核心后,在重開機前,我們先設定一下 /etc/rc.conf

firewall_enable="YES"
firewall_type="open"

還有一件事要做,當在以太網絡上跑 IP 協(xié)議時,事實上使用二種以太網絡協(xié)議,一個是 IP,另一個是 ARP。ARP 協(xié)定是當機器要找出給定 IP 地址所對應的以太網絡地址時使用的。ARP 并不是 IP 層的一部份,只是給 IP 應用在以太網絡上運作。標準的防火墻規(guī)則中并未加入對于 ARP 的支持,幸運的是,高手們的在 ipfirewall 程序代碼中加入了對封包過濾橋接器的支持。如果我們在 IP 地址 0.0.0.0 上建立一個特別的 UDP 規(guī)則,UDP 端口的號碼將被使用來搭配被橋接封包的以太網絡協(xié)議號碼,如此一來,我們的橋接器就可以被設定成傳遞或拒絕非 IP 的協(xié)議。請在 /etc/rc.firewall 中接近文件頂端處理 lo0 的那三行之下(就是有寫 Only in rare cases do you want to change these rules 的地方)加入下面一行:

${fwcmd} add allow udp from 0.0.0.0 2054 to 0.0.0.0

現在我們就可以重新開機了。重開機之后,先執(zhí)行下列指令來啟動橋接器:

如果您使用的是 FreeBSD 4.x:

# sysctl -w net.link.ether.bridge_ipfw=1
# sysctl -w net.link.ether.bridge=1

如果您使用的是 FreeBSD 5.x:

# sysctl -w net.link.ether.bridge.ipfw=1
# sysctl -w net.link.ether.bridge.enable=1

現在我們可以將機器放在內外二個網域之間了。因為我們之前在 /etc/rc.conf 中,設定防火墻完全打開,不阻擋任何封包,所以放在二個網域之間時,運作應該沒有問題。我們之前只設了一張網絡上的 IP,而在執(zhí)行了上述的指令之后,第二張網絡卡便開始運作。

下一步就是將我們啟動橋接器的指令放在 /etc/rc.local 中,讓系統(tǒng)在開機時自動執(zhí)行。或者,我們可以在 /etc/sysctl.conf 中加入下面二行:

# 如果您使用的是 FreeBSD 4.x
net.link.ether.bridge_ipfw=1
net.link.ether.bridge=1
# 如果您使用的是 FreeBSD 5.2 以后的版本
net.link.ether.bridge.enable=1
net.link.ether.bridge.ipfw=1

接下來我們就可以依自己的需求在 /etc/rc.firewall 文件的最后面加上我們自己想要的防火墻規(guī)則了。以下是一個簡單的設定規(guī)則,假設橋接器的 IP 是 140.115.75.137,內部有二臺主機,一臺提供網頁服務,一臺是 BBS:

us_ip=140.115.75.137
basrv_ip=140.115.3.4
bbs_ip=140.115.5.6
oif=fxp0
iif=fxp1
ipfw="/sbin/ipfw"
# Things that we've kept state on before get to go through in a hurry.
${ipfw} 1000 add check-state

# Throw away RFC 1918 networks
${ipfw} 1100 add deny ip from 10.0.0.0/8 to any in via ${oif}
${ipfw} 1200 add deny log ip from 172.16.0.0/12 to any in via ${oif}
${ipfw} 1300 add deny log ip from 192.68.0.0/16 to any in via ${oif}
# 允許橋接器本身所有想做的聯機 (keep state if UDP)
${ipfw} 1400 add pass udp from ${us_ip} to any keep-state
${ipfw} 1500 add pass ip from ${us_ip} to any

# 允許內部網絡任何想做的聯機 (keep state if UDP)
${ipfw} 1600 add pass udp from any to any in via ${iif} keep-state
${ipfw} 1700 add pass ip from any to any in via ${iif}

# 允許任何的 ICMP 聯機
${ipfw} 1800 add pass icmp from any to any

# 不允許使用 port 888 聯機
${ipfw} 2000 add deny log tcp from any to ${bbs_ip} 888

# TCP section
# 任何地方都可以建立 TCP 聯機
${ipfw} 3000 add pass tcp from any to any via ${oif}

# Pass the "quarantine" range.
${ipfw} 3100 add pass tcp from any to any 49152-65535 in via ${oif}
# Pass ident probes. It's better than waiting for them to timeout
${ipfw} 3200 add pass tcp from any to any 113 in via ${oif}
# Pass SSH.
${ipfw} 3300 add pass tcp from any to any 22 in via ${oif}
# Pass DNS. 當內部網絡有名稱服務器時才需要
#${ipfw} add pass tcp from any to any 53 in via ${oif}
# 只傳遞 SMTP 給郵件服務器
${ipfw} 3400 add pass tcp from any to ${bbs_ip} 25 in via ${oif}
${ipfw} 3500 add pass tcp from any to ${basrv_ip} 25 in via ${oif}
# UDP section
# Pass the "quarantine" range.
${ipfw} 4000 add pass udp from any to any 49152-65535 in via ${oif}
# Pass DNS. 當內部網絡有名稱服務器時才需要
#${ipfw} 4100 add pass udp from any to any 53 in via ${oif}

# 其它的都拒絕
${ipfw} 60000 add deny ip from any to any