對於Internet上的系統,不論是什麼狀況都要明確一點:網絡是不安全的。所以,雖然建立一 個防火牆並不能保證系統100%安全,但倒是絕對必要的。Linux提供了一個很是優秀的防火牆工具—netfilter/iptables。它徹底免 費、功能強大、使用靈活、能夠對流入和流出的信息進行細化控制,且能夠在一臺低配置機器上很好地運行。本文將簡單介紹使用 netfilter/iptables實現防火牆架設和Internet鏈接共享等應用。 安全
netfilter/iptabels應用程序,被認爲是Linux中實現包過濾功能的 第四代應用程序。netfilter/iptables包含在2.4之後的內核中,它能夠實現防火牆、NAT(網絡地址翻譯)和數據包的分割等功能。 netfilter工做在內核內部,而iptables則是讓用戶定義規則集的表結構。netfilter/iptables從ipchains和 ipwadfm(IP防火牆管理)演化而來,功能更增強大。下文將netfilter/iptabels統一稱爲iptables。 服務器
能夠用iptables爲Unix、Linux和BSD我的工做站建立一個防火牆,也可 覺得一個子網建立防火牆以保護其它的系統平臺。iptales只讀取數據包頭,不會給信息流增長負擔,也無需進行驗證。要想得到更好的安全性,能夠將其和 一個代理服務器(好比squid)相結合。 網絡
典型的防火牆設置有兩個網卡:一個流入,一個流出。iptables讀取流入和流出數據包的報頭,將它們與規則集(Ruleset)相比較,將可接受的數據包從一個網卡轉發至另外一個網卡,對被拒絕的數據包,能夠丟棄或按照所定義的方式來處理。 併發
經過向防火牆提供有關對來自某個源地址、到某個目的地或具備特定協議類型的信息包要作些 什麼的指令,規則控制信息包的過濾。經過使用iptables系統提供的特殊命令iptables創建這些規則,並將其添加到內核空間特定信息包過濾表內 的鏈中。關於添加、去除、編輯規則的命令,通常語法以下: ssh
iptables [-t table] command [match] [target] tcp
[-t table]選項容許使用標準表以外的任何表。表是包含僅處理特定類型信息包的規則和鏈的信息包過濾表。有三個可用的表選項:filter、nat和mangle。該選項不是必需的,若是未指定,則filter做爲缺省表。各表實現的功能如表1所示。 工具
表1 三種表實現的功能 oop
command部分是iptables命令最重要的部分。它告訴iptables命令要作什麼,例如插入規則、將規則添加到鏈的末尾或刪除規則。表2是最經常使用的一些命令及例子。 測試
表2 命令的功能和樣例 ui
iptables命令的可選match部分指定信息包與規則匹配所應具備的特徵(如源地址、目的地址、協議等)。匹配分爲通用匹配和特定於協議的匹配兩大類。這裏將介紹可用於採用任何協議的信息包的通用匹配。表3是一些重要且經常使用的通用匹配及示例說明。
表3 通用匹配及示例說明
目標是由規則指定的操做,對與那些規則匹配的信息包執行這些操做。除了容許用戶定義的目標以外,還有許多可用的目標選項。表4是經常使用的一些目標及示例說明。
除表4外,還有許多用於創建高級規則的其它目標,如LOG、REDIRECT、MARK、MIRROR和MASQUERADE等。
表4 目標及示例說明
與ipchains和ipfwadm不一樣的是,iptables能夠配置有狀態的防火牆。iptables能夠檢測到源地址和目的地址、源端口和目的端口 及流入數據包的順序,即iptables記住了在現有鏈接中,哪些數據包已經被容許接收。這使得暫時性的端口只有在須要時纔會被打開,而且會拒絕全部永久 性佔用端口的請求,大大地增強了安全性。同時,那些被更改了報頭的數據包,即便包含有一個被容許的目的地址和端口,也會被檢測到並被丟棄。此外,有狀態的 防火牆可以指定並記住爲發送或接收信息包所創建鏈接的狀態。防火牆能夠從信息包的鏈接跟蹤狀態得到該信息。在決定新的信息包過濾時,防火牆所使用的這些狀 態信息能夠增長其效率和速度。
下面將正式使用iptables來建立防火牆。啓動和中止iptables的方法取決於所使用的Linux發行版,能夠先查看所使用Linux版本的文檔。
通常狀況下,iptables已經包含在Linux發行版中,運行iptables --version來查看系統是否安裝了iptables。在Red Hat 9.0中,安裝的版本是iptables v1.2.7a。若是系統沒有安裝iptables,則能夠從http://www.netfilter.org下載。
上面僅對iptables的用法作了一個簡單介紹,使用中能夠運行man iptables來查看全部命令和選項的完整介紹,或者運行iptables -help來查看一個快速幫助。要查看系統中現有的iptables規劃集,能夠運行如下命令:
iptables --list |
下面是沒有定義規劃時iptables的樣子:
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination |
如上例所示,每個數據包都要經過三個內建的鏈(INPUT、OUTPUT和FORWARD)中的一個。
filter是最經常使用的表,在filter表中最經常使用的三個目標是ACCEPT、DROP和REJECT。DROP會丟棄數據包,再也不對其進行任何處理。REJECT會把出錯信息傳送至發送數據包的主機。
圖1 Red Hat 9.0中安全設置的GUI工具
在Red Hat 9.0中,提供一個GUI程序來讓用戶對系統的安裝級別進行簡單的配置。該工具的啓動方法是:主選單→系統設置→安全工具(如圖1所示)。在此將安全級別 設爲「高級」,並選擇使用默認的防火牆規則。點擊肯定後,再用iptables -list顯示,發現iptables與沒有定義規則前已經有很大不一樣,以下所示:
[root@workstation root]# iptables --list Chain INPUT (policy ACCEPT) target prot opt source destination RH-Lokkit-0-50-INPUT all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination RH-Lokkit-0-50-INPUT all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination ...... |
現實中通常不使用這個GUI工具,由於它的功能有限,也不夠透明。相比較而言,SuSE 9.0中相應的配置工具要好得多,它能夠在GUI下對防火牆進行更加細化的配置(好比增長了IP轉發和假裝等功能的配置)。儘管這樣,通常仍是本身來增長和刪除規則。
本例中的規則將會阻止來自某一特定IP範圍內的數據包,由於該IP地址範圍被管理員懷疑有大量惡意攻擊者在活動:
# iptables -t filter -A INPUT -s 123.456.789.0/24 -j DROP |
也能夠很輕易地阻止全部流向攻擊者IP地址的數據包,該命令稍有不一樣:
# iptables -t filter -A OUTPUT -d 123.456.789.0/24 -j DROP |
注意這裏的A選項,如前所述,使用它說明是給現有的鏈添加規則。
網絡上的惡意攻擊者老是在變化的,所以須要不斷改變IP。假設一個網上攻擊者轉移到新的IP地址,而其老的IP地址被分配給一些清白的用戶,那麼這時這些用戶的數據包將沒法經過你的網絡。這種狀況下,可使用帶-D選項的命令來刪除現有的規則:
# iptables -t filter -D OUTPUT -d 123.456.789.0/24 -j DROP
建立一個具備很好靈活性、能夠抵禦各類意外事件的規則須要大量的時間。對於那些沒有時間這樣作的人,最基本的原則是「先拒絕全部的數據包,而後再容許須要的」。下面來爲每個鏈設置缺省的規則:
# iptables -P INPUT DROP # iptables -P FORWARD DROP # iptables -P OUTPUT ACCEPT |
這裏選項-P用於設置鏈的策略,只有三個內建的鏈纔有策略。這些策略可讓信息毫無限制地流出,但不容許信息流入。不少時候須要接收外部信息,則可以使用如下命令:
# iptables -t filter -A INPUT -s 123.456.789.0/24 -j ACCEPT
不能關閉全部端口,也不能只指定某些端口處於打開狀態,那麼怎樣才能設置一個有效的規則,既能夠容許普通用戶正常經過,又能夠阻止惡意攻擊者訪問網絡呢?
剛開始使用iptables的人能夠充分利用syn標識來阻止那些未經受權的訪問。 iptables只檢測數據包的報頭,事實上,除iptables之外,不少其它有用的數據包分析都是基於報頭的。好比,在進行Web衝浪時,一個請求從 你的PC發送至其它地方的Web服務器上,該服務器會響應請求併發回一個數據包,同時獲得你係統上的一個臨時端口。與響應請求不一樣的是,服務器並不關心所 傳送的內容。能夠利用這種特色來設置規則,讓它阻止全部沒有通過你係統受權的TCP鏈接:
# iptables -t filter -A INPUT -i eth0 -p tcp --syn -j DROP |
這裏的-i指的是網卡,-p則是指協議,--syn則表示帶有syn標識設置的TCP數據包。SYN用於初始化一個TCP鏈接,若是本身機器上沒有運行任何服務器,別人也就不會向你發送SYN數據包。
前邊的例子把每個數據包當作是獨立的,而不是相互關聯的,依靠的是數據包的頭信息。iptables會檢查數據包的源和目的IP地址、源和目的端口、流 入數據包的順序號、TCP前後順序的信息及頭標記(SYN、ACK、FIN、RST等)的狀態,即它會跟蹤整個鏈接會話,從而使整個過濾過程是相互關聯 的。
網絡地址翻譯和IP假裝均可以實現多臺主機共享一個Internet鏈接,這個局域網能夠是 Linux和Windows系統組成的多系統局域網。假設如今有一臺機器,配有兩個網卡,其中eth0爲「公共」網卡,eth1爲「私有」網卡,即 eth0被分配了一個靜態的、可路由的IP地址,而eth1被分配了一個私有的、不能路由的IP,該IP是屬於該局域網子網的。要實現上述功能,須要向 nat和filter表中添加一些鏈:
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # iptables -t filter -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT # iptables -t filter -A FORWARD -i eth1 -o eth0 -j ACCEPT |
這顯示了有狀態的數據包檢測的價值。請注意,這裏是如何實現流入數據包只有在屬於一個已經存在的鏈接時才被容許,而全部來自局域網內流向外的數據包則都容許經過。第一條規則讓全部流出的信息看起來都是來自防火牆機器的,而並不會顯示出防火牆後面還有一個局域網。
下面的命令爲FORWARD和POSTROUTING鏈設置缺省的策略,在使用假裝時,有一個缺省的POSTROUTING DROP策略很是重要,不然就可能有心懷惡意的用戶突破網關後假裝本身的身份。
# iptables -t filter -P FORWARD DROP # iptables -t nat -P POSTROUTING DROP |
下面的命令爲撥號鏈接設置,它能夠動態地分配IP地址:
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
有時也會把服務器放置在防火牆後面,這時iptables就須要知道從哪兒經過數據包,設置以下所示:
# iptables -t nat -A PREROUTING -i eth0 -p tcp -dport 80 -j DNAT -to 192.168.0.10:80 # iptables -t nat -A PREROUTING -i eth0 -p tcp -dport 25 -j DNAT -to 192.168.0.11:25
到如今爲止,全部的例子都是在命令行中進行的。在測試新的規則時,這是一種很好的方式,但一旦測試結果使人滿意,就能夠將它們保存爲腳本。可使用 iptables-save 命令來實現:
$ iptables-save > iptables-script |
信息包過濾表中的全部規則都被保存在文件iptables-script中。不管什麼時候再次引導系統,均可以使用iptables-restore命令將規則集從該腳本文件恢復到信息包過濾表。恢復命令以下所示:
$ iptables-restore iptables-script |
若是願意在每次引導系統時自動恢復該規則集,則能夠將上面指定的這條命令放到任何一個初始化Shell腳本中。
下面的例子並非一個完整的腳本,它只是描述瞭如何使用變量及提供了一些附加的規則樣例。
#!/bin/sh #爲變量賦值 IPTABLES=/sbin/iptables LAN_NET="192.168.1.0/24" IFACE= "eth0" LO_IFACE="lo" LO_IP="127.0.0.1" #加載所需的內核 /sbin/modprobe ip_conntrack /sbin/modprobe iptable_nat #缺省狀況下,IP轉發都處於不可用狀態,將其設置爲可用狀態: echo "1" > /proc/sys/net/ipv4/ip_forward #使IP的動態分配功能可用 echo "1" > /proc/sys/net/ipv4/ip_dynaddr #每次重啓這個腳本時,最好清除之前所設的規則 $IPTABLES -P INPUT DROP $IPTABLES -F INPUT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -F OUTPUT $IPTABLES -P FORWARD DROP $IPTABLES -F FORWARD $IPTABLES -F -t nat #只容許在LAN中使用SSH鏈接 $IPTABLES -A INPUT -s LAN_NET -p tcp --destination-port ssh -j ACCEPT #容許loopback! $IPTABLES -A INPUT -i lo -p all -j ACCEPT $IPTABLES -A OUTPUT -o lo -p all -j ACCEPT #丟棄那些流入的宣稱是來自本地機器的數據包 #丟棄那些流出的不是出自本地機的數據包 $IPTABLES -A INPUT -i $IFACE -s $LAN_NET -j DROP $IPTABLES -A OUTPUT -o $IFACE -s ! $LAN_NET -j DROP #限制一些流出的信息 $IPTABLES -A OUTPUT -o eth0 -p tcp -dport 31337 -j DROP $IPTABLES -A OUTPUT -o eth0 -p tcp -sport 31337 -j DROP #此外,3133五、2744四、2766五、20034 NetBus、970四、137-139(smb)端口也應被禁止。