Freebsd系統之——防火牆IPFW


   PACKET FLOW(包的流程) 
   ipfw可以從協議堆裏的很多地方被調用,在個別系統參數的控制下,最重要的要明白,何時爲了設計固有的規則表才發生。ipfw被調用的如下表示,一起的還有 
控制它的sysctl 變量 

^ to upper layers V 
| | 
+----------->-----------+ 
^ V 
[ip_input] [ip_output] net.inet.ip.fw.enable=1 
| | 
^ V 
[ether_demux] [ether_output_frame] et.link.ether.ipfw=1 
| | 
+-->--[bdg_forward]-->--+ net.link.ether.bridge_ipfw=1 
^ V 
| to devices | 



  有圖所示,數據包穿過防火牆的次數可以在0-4之間變化,這依賴於數據包的源,目的地和系統配置。在每一個位置裏,包只被屬於自己所在層區域的配置檢驗。也就是說,來訪的數據包包含MAC頭,當ipfw在 
規則表總是在執行的,無論是ipfw的調用的地方,還是包來源的地方。如果一個規則包含一些匹配模式或對調用地方無效的行爲(例如當ipfw在 ip_input處被調用,去匹配一個MAC頭)匹配模式將不匹配。無論如何,一個沒有操作數的模式將導致,此模式永遠匹配那些有歹意的數據包。這是程序 員的責任,如果需要,寫一個恰當的規則表,以區分有可能涉及到的地方,skipto(跳轉)可以被使用,例如: 

# packets from ether_demux or bdg_forward 
ipfw add 10 skipto 1000 all from any to any layer2 in 
# packets from ip_input 
ipfw add 10 skipto 2000 all from any to any not layer2 in 
# packets from ip_output 
ipfw add 10 skipto 3000 all from any to any not layer2 out 
# packets from ether_output_frame 
ipfw add 10 skipto 4000 all from any to any layer2 out 

此時在ether_demu and bdg_forward 之間沒有任何區別。 

規則格式: 
 ipfw規則的格式如下: 
  [rule_number] [set set_number] [prob match_probability] 
  action [log [logamount number]] body 
body部分的設置是爲了過濾信息包的,有以下幾種: 

Layer-2 header fields 當用到的時候 
IPv4 Protocol TCP, UDP, ICMP, etc. 
Source and dest. addresses and ports 
Direction See Section PACKET FLOW 
Transmit and receive interface 由名字或地址決定 
Misc. IP header fields 版本,服務器種類,數據包長, 度 鑑定,片斷標記(非零 IP 抵消),存活時間 
IP options: 
Misc. TCP header fields TCP flags (SYN, FIN, ACK, RST, 
etc.), 序號, 確認號, 窗口 
TCP options: 
ICMP types 對於ICMP的數據包 
User/group ID 當數據包能被聯繫到本地的計算機上 
  注意上面的信息,舉例來說,源MAC或者是IP地址和TCP/UDP端口,容易受到欺騙,所以當過濾這些領域的數據包時,不能保證可以得到預期的效果。 
   rule_number 
  每一條規則都有一個規則號,範圍是1..65535,還有一些近來被保留的默認規則。規則是按規則號有序的被察看。多種規則可以有同樣的號碼,在這種情況 下,被察看,或列出,也是依照他們在設置中的順序。如果一條加入的規則,沒有特殊的號碼,內核將自動分配一個號碼,排在除默認規則的所有規則的最後面,這 個自動的號碼是由最後一個非默認的規則號給於賦值的如果這個號碼與最後一個衝突,則最後一個號碼的規則獎被取代(因爲自動的序列號可能會超過最大範 圍)。 
   set set_number 
  每一條規則都有一個設置號,範圍是0..31,和一些最近爲默認規則所保留。這個設置號可以個別的激活或段掉,所以對於子規則的操作,這個是最基本也是最 重要的了。他也可以用在單一的規則的刪除裏,如果一個輸入的規則沒有設置號,那麼將自動賦值0給它! 
   prob match_probability 
  一個匹配只是被公開的和一個指定的概率(浮動點在0-1)。這個可以用在一個應用的數字上,例如像任意包的丟失,或模擬多路經引導無序的包傳輸的效果。 
   log [logamount number]當一個數據包用關鍵字匹配一個規則的時候,工具LOG_SECURITY 將這個信息保存到syslogd( 裏。記錄信息只在變量net.inet.ip.fw.verbose設置爲1的情況下出現(這個是被默認的當內核被命令 IPFIREWALL_VERBOSE 編譯的時候)並且迄今爲止被記錄的包的號碼,他們的那些規則沒有超出他們記錄的變量。如果沒有變量被指定,那麼這個限定的從變量   net.inet.ip.fw.verbose_limit中提取。 
一旦限定被延伸,記錄將由清除的計算器或那個進入的包的計算器重新激活。看resetlog 命令。 
RULE ACTIONS 
  一個規則可以用以下的某一種行爲設置,就是要執行的那部分當數據包匹配規則軀幹的時候。 
   allow | accept | pass | permit 
  允許包去匹配規則。停止搜索。 
   check-state 
  檢查包所依靠的規則。如果一個匹配被發現,則執行規則裏聯帶的行爲,另外移動倒下一個規則。Check-state 規則沒有軀幹。如果一個非Check-state 的規則被發現,則動態的規則將在第一或限定的規則裏找。 
count 更新計算,爲了所有的數據包去匹配規則。尋找下一個規則。 
   deny | drop 
  匹配這個規則的要丟棄數據包。搜索結束。 
   divert port 
  匹配這個規則的要將數據包轉向到此規則提到的端口去,搜索停止。 
   fwd | forward ipaddr[,port] 
  改變下一跳在被匹配的數據包到一個ip地址去,這個可以是ip也可以是主機名。 
  如果ip是本地地址,則被匹配的數據包將被轉移到一個本地計算記的端口(或是包上的端口數,如果那個沒有被說明在規則裏) 
  如果ip地址是外部的,則端口號(如果被指出)被忽略 ,並且發送到遠端的地址,用路由器在本地路由表裏尋找那個ip。 
  一個fwd規則不匹配2層包(那些在ether_input, ether_output, or bridged上的包) 
fwd行爲不根本改變包的內容。詳細說,不更改目的地址,所以數據包被髮送到另一個系統通常是被系統拒絕的,除非有一個匹配規則在那個系統上來捕捉他們! 至於數據包傳送到本地,socket上的本地地址將被放置到數據包的最初的目的地址上,這個使進入的netstat看上去更怪異,但是制定成使用透明的代 理服務器了。 
   pipe pipe_nr 
  通過的包到虛擬pipe(爲了寬帶限制的延遲)。看TRAFFIC SHAPER CONFIGURATION。搜索結束,不管出口是從管道並且如果  net.inet.ip.fw.one_pass 值沒有被設置,數據包仍被傳遞到下一個防火牆規則。 
   queue queue_nr 
傳遞包到虛擬queue(爲了寬帶限制的使用WF2Q)。 
rejec 被拒絕,跟無法找到主機一樣。 
reset 被丟棄的包若是一個tcp包,就試圖發送一個tcp重組信息。搜索結束。 
skipto number 
跳讀所有後來的規則號,繼續搜索第一個號碼和更高的那個。 
tee port 
發送一個匹配這個規則的拷貝到divert socket邦定的端口。搜索結束,最初的包被接受。 
unreach code 
  按規則丟棄的數據包,發送一個ICMP的帶編碼的不能得到的提示,這個編碼是0-255的一個數字,或者以下列的其中一個:網名,主機名,協議,端口,碎 片,失敗,網絡未知,主機未知,獨立的,網絡禁用的,主機禁用的,到子網,到子機,過濾禁止,主機優先權或者優先權終止。搜索結束。 
RULE BODY 
  規則的軀幹包含0或更多的參數(例如,明確的來源和目的地址或端口,協議選項,進出的接口等等。)那些數據包必須匹配除了別的規則。通常,連接模式都是由 操作項固定的。也就是所有的匹配都是按順序的進行匹配,個別的模式可以由非操作項給於相反的匹配結果。例如 : 
   ipfw add 100 allow ip from not 1.2.3.4 to any 
  再有,可供選擇的匹配模式能由擴號內輸入的模式進行建造,例如: 
   ipfw add 100 allow ip from { x or not y or z } to any 
只有擴號內一種模式被允許。要小心,有一些內核對擴號有特殊的含義,所以明智的辦法就是放一個斜槓“”在他們前面來杜絕這種情況。 
  一個規則的軀幹通常必須有來源和目的地址,關鍵字"any"可用在不同的地方標示,滿足的條件是任意的。 
  規則的軀幹有下列格式: 
   [proto from src to dst] [options] 
  第一部分(protocol from src(源) to dst(目的))是用ipfw1兼容的。在ipfw2,任何匹配模式(包括MAC地址,IPv4 protocols,,地址和端口)可以在選項部分被指定。 
  規則部分有以下含義: 
   proto: protocol | { protocol or ... } 
  一個IPv4 協議(或一個,或多個)由號碼或名字指定(察看/etc/protocols)。ip或所有的關鍵字意味着將匹配所有的協議。 
   src and dst: ip-address | { ip-address or ... } [ports] 
  一個單獨的ip地址,一個或包含多個的,由端口設置決定他們的走向。 
   ip-address: 
一個指定的地址(或地址設置)在下列方法的其中一個裏由非操作項控制。 
any 匹配任何ip。 
me 匹配系統接口的任何ip。在數據包被分析的時候,會查詢ip列表的。 
numeric-ip | hostname 
匹配一個單獨的ip地址或主機名,主機名也可以添加防火牆列表的。 
addr/masklen 
匹配所有的ip地址或主機名(帶掩瑪的ip段)例如,1.2.3.4/25 ,將匹配所有的ip從1.2.3.0到1.2.3.127。 
addr/masklen{num,num,...} 
還有一種如下例:1.2.3.4/24{128,35,55,89},此規則則匹配以下ip地址: 
1.2.3.128 1.2.3.35 1.2.3.55 1.2.3.89 . 
這種格式是特殊用於處理單獨規則裏面少量的地址。 
ports: [not] {port | port-port} [,...] 
支持端口號的協議(例如:TCP and UDP),隨意的端口號可以被指定,一個,多個,胡哦這是一個範圍,用“,”隔開(不能有空格),並且一個隨意的沒有具體的項。“-”符號指定帶邊界的範圍。 
服務器(from /etc/services)的名字可以用數字的端口值代替。端口的長度被限制到30,或一個範圍內,儘管這個範圍在規則裏很大。 
""可以劈開用"-"在shell裏的衝突(有的服務器有自己的定義)。 
ipfw add count tcp from any ftp-data-ftp to any 
一個非零的包的碎片(也就是不是第一段的)將不匹配規則規則。看關於碎片設置的詳細資料。 
RULE OPTIONS (匹配模式) 
附加的匹配模式可以被用在規則裏面。0或者其他所謂的設置都可以出現在規則裏,前置由非操作數和可能的區域裏的組決定。 
以下匹配模式可以使用: 
bridged 
  指匹配過渡的數據包。 
   dst-ip ip address 
  匹配ip包,看誰的目的地址是清單裏的其中一個。 
   dst-port source ports 
  匹配ip包,看誰的目的端口是清單裏的其中一個。 
   established 
  匹配那些有RST or ACK bits設置的TCP包。 
frag 匹配那些片斷或者不是第一段的ip數據包,注意,這些包不具備下一個協議頭(e.g. TCP, UDP),所以這些玄想不能被匹配。 
   gid group 
  匹配所有被組(組可以是指定的名字或數字)承認的TCP or UDP包。 
   icmptypes types 
  匹配所有的列在ICMP類表裏的ICMP包。列表可以是一個指定的範圍,或者是逗號隔開的個別類型。這裏支持的ICMP類型有: 
   echo reply (0), destination unreachable (3), source quench (4), 
   redirect (5), echo request (, router advertisement (9), router 
   solicitation (10), time-to-live exceeded (11), IP header bad 
   (12), timestamp request (13), timestamp reply (14), information 
   request (15), information reply (16), address mask request (17) 
   and address mask reply (1. 
   in | out 

  分別的匹配進出的包,進和出是互斥的(實際上,出就是執行不進)。 
   ipid id 
  匹配IP包裏的Id值。 
   iplen len 
  匹配ip包的總長度,包括頭和數據。 
   ipoptions spec 
  匹配誰的ip頭包含用逗號隔開的設置,支持以下幾種: 
   ***r (strict source route), lsrr (loose source route), rr (record 
   packet route) and ts (timestamp). 沒有詳細說明則用"!"表示。 
   ipprecedence precedence 

  匹配有優先權的IP。 
   iptos spec 
  匹配帶有被逗號隔開的服務類型表的ip,支持以下幾種: 
   lowdelay (IPTOS_LOWDELAY), throughput (IPTOS_THROUGHPUT), 
   reliability (IPTOS_RELIABILITY), mincost (IPTOS_MINCOST), 
   congestion (IPTOS_CE). 沒有詳細說明則用"!"表示。 
   ipttl ttl 

  匹配ip的存活時間 
   ipversion ver 
  匹配ip的版本號 
   keep-state 
  在匹配時,防火牆將創建一個動態規則,它的默認的行爲就是去匹配雙向的通信,在源和IP/port使用同樣協議的的目的地之間。這個規則有一定壽命,這個存活時間在每次要匹配的包被找到後重新更新。 
layer2 僅匹配2層的包,例如通過ipfw的從ether_demux() and ether_output_frame(). 
    limit {src-addr | src-port | dst-addr | dst-port} N 
  防火牆只允許像設置裏的那個數N連接,一個或多個的源和目的地址都會被定義。 
   { MAC | mac } dst-mac src-mac 
  匹配帶有MAC的源和目的地址,詳細的就像一些關鍵字,或者是6個被逗號隔開的數字,例如下: 
   MAC 10:20:30:40:50:60/33 any 
注意MAC地址的規則(目的地第一,源第二)他們同樣也在信息裏,只是對應的習慣用IP地址罷 了。 
mac-type mac-type 
匹配跟內網類型一樣的數據包。mac類型也用同樣的方法被定義就像端口號。你可用象徵的名字爲你知道的含義,像vlan, ipv4, ipv6.這個值也可以被直接輸入,像10近制,16近制,他們輸出總是按16近制,除非-N設置啓用,那麼那些符號將被試圖啓用。 
proto protocol 
匹配ipv4的通用協議。 
recv | xmit | via {ifX | if* | ipno | any} 
匹配接受的包,分別的轉輸或是通過,接口被將由精確的名字(ifX)和設備名字(if*)所定義,還可以由ip或一些其它的接口定義。 
via這個關鍵字就是說,所有的接口總是要被檢查的。如果是recv or xmit取代了via則表示只接受,或只轉發,這就有可能匹配包是基於接受和轉發的接口上的。例如: 
ipfw add deny ip from any to any out recv ed0 xmit ed1 
recv接口可以測試在通過他們所進出的包,所以只要xmit在使用中,出就會被請求(沒有進)。 

一個包可以沒有接受或轉發接口:數據包從本地主機出來,是沒有接受接口的,一會兒就回到達沒有轉發接口的本地主機。 
setup 匹配只帶SYN字節不帶ACK字節的TCP包, 
src-ip ip-address 
匹配ip包裏有源ip在地址列表裏的 
src-port ports 
匹配ip包裏有源端口在端口列表裏的 
tcpack ack 
僅TCP包,匹配TCP頭帶有ack字樣的包。 
tcpflags spec 
僅TCP包,匹配TCP頭帶有逗號隔開的字樣的包,支持以下幾種: 

fin, syn, rst, psh, ack and urg. The absence of a particular 
flag may be denoted with a `!'. A rule which contains a tcpflags 
specification can never match a fragmented packet which has a 
non-zero offset. See the frag option for details on matching 
fragmented packets. 

tcpseq seq 
僅TCP包,匹配TCP頭帶號碼區有seq字樣的包。 
tcpwin win 
僅TCP包,匹配TCP頭帶window區有win字樣的包。 
tcpoptions spec 
僅TCP包,匹配TCP頭包含逗號隔開的選想說明,支持以下幾種: 

mss (maximum segment size), window (tcp window advertisement), 
sack (selective ack), ts (rfc1323 timestamp) and cc (rfc1644 
t/tcp connection count). 空缺用`!'表示。 
uid user 
匹配所有用戶收發數據包,用戶可以由名字或認證數字來匹配。 
SETS OF RULES 
每一條規則都是32不同條例中的其中一個,0-31,31爲保留的默認規則。 
默認的情況下,,規則將被設置爲0,除非你輸入新規則是,在N上有所改動,設置可以被個別激活或者停止,所以這種辦法允許一個很簡單的方法去貯存防火牆的多種配置,很快的可以在它們之間互相轉換。激活/停止的命令爲: 
ipfw set disable number ... [enable number ...] 

各種各樣的激活或者停止,可以分別指定。命令的執行在所有指定的設置中很微小,默認情況下。所有設置爲激活的。 
當你停止一個設置,他的規則則表現爲在防火牆上沒有任何配置,只有一種情況例外: 
由源規則(父規則)創建一個動態的規則,在他被停止之前,一直運行,直到他們中斷爲止。爲了刪除動態規則,你不得不將他們倆個規則全都刪除; 
規則的號碼可以用命令更改 
ipfw set move {rule rule-number | old-set} to new-set 
同樣你也可以交換兩個規則 
ipfw set swap first-set second-set 
( See the EXAMPLES Section on some possible uses of sets of rules.) 

STATEFUL FIREWALL 
Stateful的作用是讓防火牆能動態的創建一個規則,爲了描述當匹配包所給出的模式的流程。這個的實現是通過規則的check-state, keep-state and limit得設置得到的。 
當一個數據包匹配keep-state or limit規則時,動態規則將被創建,這個動態規則將匹配所有的包所給出的src-ip/src-port dst-ip/dst-port之間的協議(這裏所使用的源地址和目的地地址都指最初的地址,但是後來他們將完全一樣)動態規則在第一次的check- state,keep-state or limit將被選中,並執行匹配,此匹配跟父規則一樣。 
注意,這些不是附加的屬性,除了動態規則檢查的協議,ip地址和端口。 
動態規則典型的應用是保持一個關閉的防火牆設置,但是讓第一個從內網來的TCP SYN包將安裝一個爲流程動態規則,所以那些包允許通過防火牆: 

   ipfw add check-state 
   ipfw add allow tcp from my-subnet to any setup 
   ipfw add deny tcp from any to any 

類似的途徑可以爲UDP使用,一個從內網來的UDP包,將安裝一個動態規則去允許防火牆作應答: 

   ipfw add check-state 
   ipfw add allow udp from my-subnet to any 
   ipfw add deny udp from any to any 
   (See Section EXAMPLES for more examples on how to use dynamic rules.) 



TRAFFIC SHAPER CONFIGURATION 
ipfw也同樣是塑造通信的用戶接口。這個塑造器由劃分的包進到流程中按照用戶指定的在ip頭不同區域的掩碼,包同樣屬於流程,也通向2個不同的目標,(named pipe or queue)名字管道和列隊。 
一個管道就像一個給定的寬帶, 傳播延遲,列隊大小和包丟是的比率。包是按照自身的參數通過管道的 

一個列隊,就是一個提取過程,執行WF2Q+方針()列隊使沒一個流程跟weight和reference管道發生聯繫。 然後,所有的流程按照管道WF2Q+方針按預定的比率指向預定的同樣的管道。 
  ipfw管道的配置格式如下: 

   pipe number config pipe-configuration 

  ipfw列隊的配置格式如下 

   queue number config queue-configuration 

  管道配置的參數如下: 

   bw (bandwidth) | (device) 
   Bandwidth, 標準[K|M]{bit/s|Byte/s}. 


默認值0意味着無限帶寬。這個單位必須跟數字,例如: 

   ipfw pipe 1 config bw 300Kbit/s 

  如果一個設備的名字是數字代替定義的,則發送時間由被定義的設備給出。在這個時候只有通道設備支持此函數,以建立端對端協議的連接。 

   delay ms-delay 
  傳播延遲是用毫秒爲標準。此值爲輪到下一次時間啓動的值(例如,10ms,它是最習慣去運行配置爲HZ=1000內核的值,去減少間隔時間到1ms或更少),默認爲0時,表示沒有延遲。 

  以下設置參數可以用在queue(列隊等待)上: 

   pipe pipe_nr 
  連接一個列隊到指定的通道。多樣的類對(通常是不同的大小)可以被聯接到同一個通道。 

   weight weight 
  指定的大小用來作匹配這個列隊的流程。這個大小必須是一個範圍1..100, 和默認值1. 

  以下參數可以對雙通道,和多列隊進行配置。 

   buckets hash-table-size 
  指定哈西表大小,是爲了儲存不同的列隊。由net.inet.ip.dummynet.hash_size默認爲64,允許範圍是16到1024。 

   mask mask-specifier 
dummynet可使你建立單一流程的列隊。一個可識別的流程,是由ip地址的演化而成的,端口和協議類型和管道設置裏一樣。帶有同樣標示的包在演化後,進到同樣的列隊。可用的掩碼定義爲以下幾種: 

   dst-ip mask, src-ip mask, dst-port mask, src-port mask, proto 
mask or all, 後面的這個表示所有有意義的所有領域的所有字節。當用在管道的配置裏時,每一個流程被指派一個和管道速度一樣的速度。當用在列隊配置的時候,每一個流程被 指派一個和列隊大小一樣的大小,並且所有流程按他們大小比例分享在同樣的管道的帶寬 

noerror 
當一個包從管道或列隊中丟失,這個錯誤將報給呼叫路由得知,同樣的方法,當一個列隊裝置填滿後也會發生。設置這個選項,報告數據包被成功接收,這個使需要一些試驗的設備,在你想模擬丟失或堵塞在源端的路由器地方。 

   plr packet-loss-rate 
包的丟失機率,packet-loss-rate是一個0-1之間的浮點數,0就是沒丟失,1是完全丟失,丟失機率內在表現爲31bits. 
queue {slots | sizeKbytes} 
列隊大小,用slots or KBytes表示。默認值爲50 slots,這個是典型的局域網設備的Queue大小。注意,那個是適用比較慢的連接,你應該保持你的queue大小短一些,或者你的通信會受到由 queue延遲的影響,例如:最大值爲50的局域網的數據包(1500 bytes),這就意味着600Kbit或queue20s在一個30Kbit/s的管道上。你如果從接口處得到一個帶有太大MTU的數據包,就會導致連 接失敗,例如:迴環接口有一個16kb的包。 

red | gred w_q/min_th/max_th/max_p 
使用RED (自動搜索)運算法則。w_q and max_p是0-1之間的浮點數(不包括0),當min_th and max_th是整數的時候指定了queue管理的極限(極限使用字節來計算,如果queue使用字節來定義的話,用slots是另外一種情況了)。網絡也 支持RED的變量(gred).這些系統控制變量常用於控制RED的行爲: 

net.inet.ip.dummynet.red_lookup_depth 
定義當連接空閒下來,計算queue平均值的精度(默認爲256,必須大於0) 

net.inet.ip.dummynet.red_avg_pkt_size 
定義期望的數據包的平均大小(默認爲512,必須大於0)。 

net.inet.ip.dummynet.red_max_pkt_size 
定義期望的數據包的最大值,僅當queue極限用字節表示的時候使用(默認爲1500,必須 大於0) 

CHECKLIST 
當計劃規則時候的一些注意事項: 
  1:記住你的過濾包的走向,一個出,一個進。更多的連接需要包在兩個方向進行 
  2:記住測試的時候非常小心。這是一個好建議當接近控制檯的時候。如果你不能使用控制檯,用一個自動生成的源文件  /usr/share/examples/ipfw/change_rules.sh. 
  3:不要忘記迴環接口(127.0.0.1) 

FINE POINTS 
  1:有一個環境使破碎的文件完全丟棄掉。如果TCp頭包含一個小於20字節的包,則丟棄,UDP頭必須包含一個完整的8個字節的包,否則丟棄,ICMP包 則丟棄那些ICMP頭不包含4個字節的包,充分的指定 ICMP類型,編碼,和檢查總數。這些包完全被記錄下來,例如:``pullup failed''因爲在包裏沒有足夠好的數據去產生有用的日誌文件。 

  2:其它類型的包則無條件的丟棄,一個帶碎片TCP包。這是一個有效的包,但是隻有一個有用,試圖繞過防火牆。當日志被激活,這些包被丟棄就像被規則-1丟棄一樣。 

  3:如果記錄整個網絡的日誌,裝載ipfw的kld版本,她不像你想象的那麼簡單。介紹以下命令行: 
   kldload /modules/ipfw.ko && 
   ipfw add 32000 allow ip from any to any 

   Along the same lines, doing an 

   ipfw flush 

   in similar surroundings is also a bad idea. 

  3:ipfw過濾器列表不可以被修改,如果系統的安全級別爲3或更高(see init( for information on system security levels). 

PACKET DIVERSION 
一個轉向插座躍向指定的端口將接收到的所有包轉到那個端口。如果沒有socket 被邦定到指定端口,或者內核不支持,包將被丟棄。 

SYSCTL VARIABLES 
內核變量的設置將控制防火牆的行爲和聯合模塊( dummynet, bridge )。這裏一起介紹他們,包括他們的默認值: 

   net.inet.ip.dummynet.expire: 1 
一旦如果沒有了沒完的通信,就刪除動態pipes/queue。你可以停止這個,將變量設置爲0,這個情況下,僅在極限到頭的時候刪除  pipes/queue。 

   net.inet.ip.dummynet.hash_size: 64 
動態pipes/queue的默認哈示表。這個默認值是當沒有buckets 被指定當配置pipe/queue時。 

   net.inet.ip.dummynet.max_chain_len: 16 
pipes/queues 在hash bucket裏最大的目標值。max_chain_len*hash_size習慣用於測試將被關閉的,甚至 net.inet.ip.dummynet.expire=0的空pipes/queues 的極限。 

   net.inet.ip.dummynet.red_lookup_depth: 256 

   net.inet.ip.dummynet.red_avg_pkt_size: 512 

   net.inet.ip.dummynet.red_max_pkt_size: 1500 
此參數是估算在使用RED法則的時候包丟失的機率。 

   net.inet.ip.fw.autoinc_step: 100 
是在兩個規則號之間隨機產生的,次數值在範圍1..1000之間。 

   net.inet.ip.fw.curr_dyn_buckets: net.inet.ip.fw.dyn_buckets 
動態規則的哈希表裏的buckets當前值(只讀的) 

   net.inet.ip.fw.debug: 1 
由ipfw控制的調試信息。 

   net.inet.ip.fw.dyn_buckets: 256 
動態規則的哈希表裏的buckets值,必須是2的冪數,最大到65536。他僅在所有的動態的規則停止的時候起作用,所以你仔細考慮是否使用Flush命令,來確定調整哈希表的大小。 

   net.inet.ip.fw.dyn_count: 3 
動態規則的當前號。 

   net.inet.ip.fw.dyn_keepalive: 1 

   Enables generation of keepalive packets for keep-state rules on 
   TCP sessions. A keepalive is generated to both sides of the con- 
   nection every 5 seconds for the last 20 seconds of the lifetime 
   of the rule. 
   net.inet.ip.fw.dyn_max: 8192 
動態規則的最大數值。當你遇到這個限制的話,不會再產生動態規則了,直到哪一個規則被終止 了。 

   net.inet.ip.fw.dyn_ack_lifetime: 300 

   net.inet.ip.fw.dyn_syn_lifetime: 20 

   net.inet.ip.fw.dyn_fin_lifetime: 1 

   net.inet.ip.fw.dyn_rst_lifetime: 1 

   net.inet.ip.fw.dyn_udp_lifetime: 5 

   net.inet.ip.fw.dyn_short_lifetime: 30 

這些變量控制着動態規則的存活時間,用秒。在初始的SYN上交換的存活時間一直是很短的,之後,當雙SYN出現以後開始遞增,然後在最後FIN交換期間或 者是RST被接收時開始遞減dyn_fin_lifetime和dyn_rst_lifetime必須嚴格控制在5秒之內,keepalives的重複周 期。防火牆會強制執行這個的. 

   net.inet.ip.fw.enable: 1 
激活防火牆,如果設置爲0,則關閉防火牆,即使編譯也沒用。 

   net.inet.ip.fw.one_pass: 1 
設置時,從dummynet(man dummynet)管道出來的包不再通過防火牆,另外,包會被放到防火牆的下一條規則裏去。 
注意:bridged and layer 2管道出來的包不管設置如何,將不會被放到防火牆裏面了。 

   net.inet.ip.fw.verbose: 1 
激活詳細信息。 

   net.inet.ip.fw.verbose_limit: 0 
限制由詳細的防火牆產生的信息號。 

   net.link.ether.ipfw: 0 
控制layer-2的包是否允許ipfw,默認爲"不是"。 

   net.link.ether.bridge_ipfw: 0 
控制bridged的包是否允許ipfw,默認爲"不是"。 

IPFW2 ENHANCEMENTS 
這部分介紹在ipfw1裏沒涉及到的一些重要的特性。列舉的是對你設置規則有一定影響的內容。你可以考慮使用這些特性,以便你設置規則的時候有更多的有效途徑。 

   Handling of non-IPv4 packets 
ipfw1將依照規則接受所有非IPv4 的包(僅當net.link.ether.bridge_ipfw=1的時候)像ipfw1一樣完成同樣的行爲,你可以使用以下條例,可以當作你規則欄裏的第一條: 

   ipfw add 1 allow layer2 not mac-type ip 

layer2選項可能被看作多餘的,但是由是必需的,從layer3到防火牆的包沒有了MAC頭,則MAC類型的ip模式總要捨去,並且非操作數將使這個規則變成全部通過。 

Address sets 
ipfw1不支持地址設置 (看addr/masklen{num,num,...} ). 

ipfw1 and ipfw2較小的區別就是,以前指定的允許的地址,像ipno:mask,這裏的mask可以是代替bit設置的任意的bitmask 。ipfw2不再支持此語法。 

Port specifications 
ipfw1 僅允許一個端口範圍,當指定TCP and UDP端口時,ipfw2將限制由15個變爲10個。同樣在ipfw1裏,你只能定義端口,在規則被請求tcp or udp包的時候,用ipfw2你可以提出一個端口的詳細說明在匹配所有包的規則裏,並且匹配將被嘗試僅僅在那些包所帶的協議裏包括端口的標識符。 

ipfw1裏要求第一個端口的進入,是被指定的,就像port:mask ,mask可以是任意的16-bit mask.這個語法也是在ipfw2裏不用的。 

Or-blocks 
ipfw1 不支持 Or-blocks. 

keepalives 
ipfw1 不產生keepalives爲數據。像一個因果關係,它可以導致一個空閒區域的停止,因爲 
動態規則的存活時間終止了。 

Sets of rules 
ipfw1 不執行規則的設置。 

MAC header filtering and Layer-2 firewalling. 
ipfw1 不在MAC頭區域進行過濾,也不被調用當包從ether_demux()和ether_output_frame()過來。sysctl變量net.link.ether.ipfw在這裏也不起作用。 

Options 
以下設置在ipfw1不支持: 

dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port. 

還有ipfw1規則裏不支持的: 

ipid, iplen, ipprecedence, iptos, ipttl, ipversion, .Cm tcpack, 
tcpseq, tcpwin. 

Dummynet options 
以下設置爲dummynet pipes/queues不支持: 
The following option for dummynet pipes/queues is not supported: 

noerror. 

EXAMPLES 
這裏僅僅給出很小的一個例子的設置。 

BASIC PACKET FILTERING 
這個命令加進一個條目,拒絕所有來自cracker.evil.org telnet wolf.tambov.su的端口的tcp包: 

   ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet 

這個是拒絕所有的來自此網的用戶訪問我的主機: 

   ipfw add deny ip from 123.45.67.0/24 to my.host.org 

第一個有效限制訪問的辦法是使用以下規則: 

   ipfw add allow tcp from any to any established 
   ipfw add allow tcp from net1 portlist1 to net2 portlist2 setup 
   ipfw add allow tcp from net3 portlist3 to net3 portlist3 setup 
   ... 
   ipfw add deny tcp from any to any 


第一條規則會馬上匹配普通的TCP包,但是不匹配最開始的SYN包,這些包只由setup規則匹配,也僅僅對source/destination有選擇性的。所有其它的SYN包將由最後的拒絕規則丟棄掉。 

如果你管理一個或更多的子網,你可以用ipfw2語法的優勢去指定地址。如下: 

   goodguys="{ 10.1.2.0/24{20,35,66,18} or 10.2.3.0/28{6,3,11} }" 
   badguys="10.1.2.0/24{8,38,60}" 

   ipfw add allow ip from ${goodguys} to any 
   ipfw add deny ip from ${badguys} to any 
   ... normal policies ... 


ipfw1 語法只能爲沒一個ip獨立設置要求,不能像上面那樣。 

DYNAMIC RULES 
爲了保護TCP包的溢出***,安全的使用此動態規則: 

   ipfw add check-state 
   ipfw add deny tcp from any to any established 
   ipfw add allow tcp from my-net to any setup keep-state 

這裏讓防火牆建立一個動態規則,爲了那些來自網絡內部的帶有有序的SYN的包的啓動連接。當遇到第一個check-state 或keep-state 規則,動態規則將被檢查。一個check-state 規則通常是放置在規則表 裏的開始的部分到工作掃描規則表的最少的幾個,你的長度可能會不一樣。 

一個用戶可以開通的最大連接數,可以使用下列規則類型: 

   ipfw add allow tcp from my-net/24 to any setup limit src-addr 10 
   ipfw add allow tcp from any to me setup limit src-addr 4 


前者是允許沒一個在那個網絡上的主機可以開10個tcp連接。後面的將被放到服務器上,去證實單一的客戶端沒有同時使用4個以上的tcp連接。 

BEWARE:數據規則可能會被 SYN-flood ***,還有其他一些的***手段可以在設置sysctl的變量的時候限制他們。 


這裏有一些好辦法,去察看那些賬戶紀錄和時間段的信息: 

   ipfw -at list 

不帶時間段的: 

   ipfw -a list 

同意義的: 

   ipfw show 

下一個規則將所有來自192.168.2.0/24的包轉到爲5000端口去: 

   ipfw divert 5000 ip from 192.168.2.0/24 to any in 

TRAFFIC SHAPING 
下列規則顯示ipfw and dummynet的一些應用。 

這個規則5%的機率隨機丟掉引入的包: 

   ipfw add prob 0.05 deny ip from any to any in 

作一個dummynet pipes也可以達到同樣的效果: 

   ipfw add pipe 10 ip from any to any 
   ipfw pipe 10 config plr 0.05 


我們可以使用管道,手工限制寬帶,例如,在一個當路由器的及其上,如果我們想限制從本地192.168.2.0/24客戶端通信,做法如下: 

   ipfw add pipe 1 ip from 192.168.2.0/24 to any out 
   ipfw pipe 1 config bw 300Kbit/s queue 50KBytes 


注意我們用非修改的,所以,那個規則只能用一次。記住實際上,ipfw規則在進和出的包都要檢查。 

我們應該模擬一個帶有限帶寬的雙向的連接,以下是正確的做法: 

   ipfw add pipe 1 ip from any to any out 
   ipfw add pipe 2 ip from any to any in 
   ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes 
   ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes 


上述的很重要,例如,如果你想看你的網頁將怎樣尋找你那個連接很慢的用戶。你應該不僅僅使用一個 通道爲雙向連接,除非你想模擬一個半雙工的方法(例如:AppleTalk, Ethernet, IRDA),雙通道有同樣的 設置是不可取的,所以我們也模擬不均衡的連接。 

我們應該用RED queue運算法則測試網絡: 

   ipfw add pipe 1 ip from any to any 
   ipfw pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1 


另一個典型的應用是介紹一些通訊中的延遲。這個可以影響非常多的關於遠端程序調用的應用。 

   ipfw add pipe 1 ip from any to any out 
   ipfw add pipe 2 ip from any to any in 
   ipfw pipe 1 config delay 250ms bw 1Mbit/s 
   ipfw pipe 2 config delay 250ms bw 1Mbit/s 


每一流程的可以用在多種意圖裏,一個簡單的例子就是計算流量: 

   ipfw add pipe 1 tcp from any to any 
   ipfw add pipe 1 udp from any to any 
   ipfw add pipe 1 ip from any to any 
   ipfw pipe 1 config mask all 


上面的規則設置將建立一個列隊(並收集統計表)爲所有的通信。因爲管道沒有侷限性,僅受統計表的影響。注意我們需要3個規則,不只是最後一個,因爲當 ipfw試圖匹配ip包,他將不考慮端口,所以我們不關心在單獨端口上的連接。 

一個經典的例子是限制有主機限制的網絡的通信的外出,要比網絡限制的好: 

   ipfw add pipe 1 ip from 192.168.2.0/24 to any out 
   ipfw add pipe 2 ip from any to 192.168.2.0/24 in 
   ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 
   20Kbytes 
   ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 
   20Kbytes

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章