LPI Linux 認證/高階網路配置和故障排除
(LPIC-2 版本 4.5)
權重 4
描述: 候選人應該能夠配置網路裝置以實現各種網路身份驗證方案。本目標包括配置多宿主網路裝置並解決通訊問題。
關鍵知識領域
- 用於操作路由表的實用程式
- 用於配置和操作乙太網網路介面的實用程式
- 用於分析網路裝置狀態的實用程式
- 用於監控和分析 TCP/IP 流量的實用程式
術語和實用程式
ipifconfigroutearpssnetstatlsofping,ping6nctcpdumpnmap
描述: 候選人應該能夠配置網路裝置以實現各種網路身份驗證方案。本目標包括配置多宿主網路裝置,配置虛擬專用網路並解決網路和通訊問題。
關鍵檔案,術語,和實用程式包括
/sbin/route /sbin/ifconfig /bin/netstat /bin/ping /sbin/arp /usr/sbin/tcpdump /usr/sbin/lsof /usr/bin/nc
在 Linux 下,網路資料包過濾可以透過以下三種方式之一實現
- Ipfwadm : 核心 2.0.x 及更高版本 (RedHat 5.x)
- Ipchains : 核心 2.2.x 及更高版本 (RedHat 6.x, 7.0)
- Iptables : 核心 2.4.x 及更高版本 (RedHat 7.1 – 9.0)
它們的設計和功能大不相同 - 請注意,ipfwadm 被認為是過時的,iptables 是最先進的和當前的。在 iptables 中,資料包流圖如下所示
Iptables 需要在你的核心中配置一些選項 (或作為模組)
- CONFIG_PACKET
- 此選項允許需要直接與各種網路裝置互動的應用程式和實用程式。此類實用程式的示例包括 tcpdump 或 snort。
- CONFIG_NETFILTER
- 如果要使用你的計算機作為防火牆或閘道器連線到網際網路,則需要此選項。
- CONFIG_IP_NF_CONNTRACK
- 此模組對於實現連線跟蹤是必需的。連線跟蹤由 NAT 和偽裝等功能使用。如果需要在 LAN 上對機器進行防火牆,那麼你絕對應該選中此選項。
- CONFIG_IP_NF_FTP
- 如果要對 FTP 連線進行連線跟蹤,則需要此模組。由於 FTP 連線在正常情況下很難進行連線跟蹤,因此 conntrack 需要一個所謂的輔助程式,此選項將編譯該輔助程式。如果未新增此模組,將無法透過防火牆或閘道器正常使用 FTP。
- CONFIG_IP_NF_IPTABLES
- 如果要執行任何型別的過濾、偽裝或 NAT,則需要此選項。它將整個 iptables 識別框架新增到核心。沒有它,你將無法使用 iptables 執行任何操作。
- CONFIG_IP_NF_MATCH_LIMIT
- 此模組並非嚴格意義上的必需項。此選項提供 LIMIT 匹配,它增加了控制每分鐘匹配資料包數量的可能性,受相應規則控制。例如,-m limit --limit 3/minute 將匹配每分鐘最多 3 個數據包。此模組還可以用於避免某些拒絕服務攻擊。
- CONFIG_IP_NF_MATCH_MAC
- 這使我們能夠根據 MAC 地址匹配資料包。每個乙太網介面卡都有自己的 MAC 地址。例如,我們可以根據使用的 MAC 地址阻止資料包,並很好地阻止特定計算機,因為 MAC 地址很少更改。
- CONFIG_IP_NF_MATCH_MARK
- 這使我們能夠使用 MARK 匹配。例如,如果使用 MARK 目標,我們可以標記資料包,然後根據此資料包是否在表中被進一步標記,我們就可以根據此標記進行匹配。此選項是實際的 MARK 匹配,稍後我們將介紹實際的 MARK 目標。
- CONFIG_IP_NF_MATCH_MULTIPORT
- 此模組使我們能夠匹配具有整個目標埠或源埠範圍的資料包。通常這不可能,但有了此匹配就成為可能。
- CONFIG_IP_NF_MATCH_TOS
- 有了此匹配,我們可以根據資料包的 TOS 欄位匹配資料包。TOS 代表服務型別。TOS 也可以透過 mangle 表中的某些規則和透過 ip/tc 命令設定。
- CONFIG_IP_NF_MATCH_TCPMSS
- 此選項為我們增加了根據 TCP 資料包的 MSS 欄位匹配 TCP 資料包的可能性。
- CONFIG_IP_NF_MATCH_STATE
- 這是與 ipchains 相比最大的改進之一。有了此模組,我們可以在資料包上進行有狀態匹配。例如,如果我們已經看到 TCP 連線中雙向的流量,則此資料包將被視為 ESTABLISHED。
- CONFIG_IP_NF_MATCH_UNCLEAN
- 此模組將增加我們匹配不符合型別或無效的 IP、TCP、UDP 和 ICMP 資料包的可能性。例如,我們可以丟棄這些資料包,但我們永遠不知道它們是否合法。請注意,此匹配仍在試驗中,可能無法在所有情況下都能完美執行。
- CONFIG_IP_NF_MATCH_OWNER
- 此選項將增加我們根據套接字所有者進行匹配的可能性。例如,我們可以只允許 root 使用者訪問網際網路。此模組最初只是作為新 iptables 可以做什麼的示例編寫的。請注意,此匹配仍在試驗中,可能無法適用於所有人。
- CONFIG_IP_NF_FILTER
- 此模組將新增基本的 filter 表,它將使你能夠執行 IP 過濾。在 filter 表中,你會找到 INPUT、FORWARD 和 OUTPUT 鏈。如果你計劃對收發的資料包進行任何型別的過濾,則需要此模組。
- CONFIG_IP_NF_TARGET_REJECT
- 此目標使我們能夠指定應該傳送 ICMP 錯誤訊息來回復傳入資料包,而不是簡單地將它們丟棄。請記住,與 ICMP 和 UDP 不同,TCP 連線始終使用 TCP RST 資料包重置或拒絕。
- CONFIG_IP_NF_TARGET_MIRROR
- 這使資料包能夠反彈回資料包的傳送者。例如,如果我們在 INPUT 鏈上的目標埠 HTTP 上設定了 MIRROR 目標,並且有人試圖訪問此埠,我們將把他的資料包反彈回他,最終他可能會看到他自己的主頁。
- CONFIG_IP_NF_NAT
- 此模組允許各種形式的網路地址轉換 (NAT)。此選項使我們能夠訪問 iptables 中的 nat 表。如果要執行埠轉發、偽裝等操作,則需要此選項。請注意,此選項不是執行 LAN 防火牆和偽裝所必需的,但除非你能夠為所有主機提供唯一的 IP 地址,否則你應該擁有它。
- CONFIG_IP_NF_TARGET_MASQUERADE
- 此模組添加了 MASQUERADE 目標。例如,如果我們不知道我們的網際網路 IP 地址,這將是獲取 IP 地址的最佳方式,而不是使用 DNAT 或 SNAT。換句話說,如果我們使用 DHCP、PPP、SLIP 或其他分配 IP 地址的連線,我們需要使用此目標,而不是 SNAT。偽裝比 NAT 給計算機帶來稍微高的負載,但無需預先知道 IP 地址即可工作。
- CONFIG_IP_NF_TARGET_REDIRECT
- 此目標與應用程式代理一起使用非常有用,例如。我們不會讓資料包直接透過,而是將其重新對映到我們的本地框。換句話說,我們可以透過這種方式建立透明代理。
- CONFIG_IP_NF_TARGET_LOG
- 這將 LOG 目標及其功能新增到 iptables。我們可以使用此模組將某些資料包記錄到 syslogd,從而瞭解資料包的處理情況。這對於安全審計、取證或除錯您編寫的指令碼非常寶貴。
- CONFIG_IP_NF_TARGET_TCPMSS
- 此選項可用於應對阻止 ICMP 分片需要的網際網路服務提供商和伺服器。這會導致網頁無法透過,小郵件能夠透過而大郵件無法透過,ssh 正常工作但 scp 在握手後掛起等等。然後我們可以使用 TCPMSS 目標透過將我們的 MSS(最大段大小)限制為 PMTU(路徑最大傳輸單元)來克服此問題。這樣,我們就能處理 Netfilter 作者在核心配置幫助中所說的“犯罪性質的腦殘 ISP 或伺服器”。
- CONFIG_IP_NF_COMPAT_IPCHAINS
- 添加了對過時的 ipchains 的相容模式。不要將其視為解決從 Linux 2.2 核心遷移到 2.4 核心的任何真正的長期解決方案,因為它可能在 2.6 核心中消失。
- CONFIG_IP_NF_COMPAT_IPFWADM
- 與過時的 ipfwadm 的相容模式。絕對不要將其視為真正的長期解決方案。
當資料包第一次進入防火牆時,它會撞擊硬體,然後被傳遞到核心中的適當裝置驅動程式。然後,資料包開始在核心中經歷一系列步驟,然後要麼被髮送到正確的應用程式(本地),要麼被轉發到另一個主機 - 或者發生任何其他情況。
首先,讓我們看一下一個目標是我們自己本地主機的包。在實際交付給接收它的應用程式之前,它將經過以下步驟
請注意,這次資料包透過 INPUT 鏈而不是 FORWARD 鏈傳遞。非常合乎邏輯。最有可能的是,從一開始,唯一真正合乎邏輯的是您眼中的表和鏈的遍歷,但如果您繼續思考,您會發現它隨著時間的推移會變得更加清晰。現在我們看一下來自我們自己本地主機的傳出資料包,以及它們經過的步驟。
在本例中,我們假設資料包的目標是另一個網路上的另一個主機。資料包以以下方式經過不同的步驟
如您所見,要經過很多步驟。資料包可以在任何 iptables 鏈中被阻止,或者在格式錯誤的任何其他地方被阻止;但是,我們主要對這批 iptables 方面感興趣。請注意,沒有針對不同介面或任何其他內容的特定鏈或表。所有透過此防火牆/路由器轉發的資料包始終透過 FORWARD。
不要在前面的場景中使用 INPUT 鏈進行過濾!INPUT 專門用於到達我們本地主機的,不會路由到任何其他目標的資料包。
我們現在已經瞭解了三種不同場景中不同鏈的遍歷方式。如果我們要找出所有這些內容的良好地圖,它看起來會像這樣
為了闡明此影像,請考慮以下內容。如果我們接收到一個在第一個路由決策中沒有目標為本地機器本身的資料包,它將透過 FORWARD 鏈路由。另一方面,如果資料包的目標是本地機器正在監聽的 IP 地址,我們將透過 INPUT 鏈將資料包傳送到本地機器。
還值得注意的是,資料包可能是目標為本地機器,但目標地址可能在 PREROUTING 鏈中透過執行 NAT 被更改。由於這發生在第一個路由決策之前,因此資料包將在更改後進行檢視。因此,路由可能會在路由決策完成之前更改。請注意,所有資料包都將經過此影像中的某條路徑。如果您將資料包 DNAT 回到它來自的同一個網路,它仍然會經過其餘的鏈,直到它回到網路上。
Mangle 表
[edit | edit source]如我們已經提到的,此表主要用於修改資料包。換句話說,您可以自由使用可以用來更改 TOS(服務型別)欄位等的修改匹配項。
強烈建議您不要使用此表進行任何過濾;並且任何 DNAT、SNAT 或偽裝都將無法在此表中工作。
僅在修改表中有效的目標
- TOS
- TTL
- MARK
TOS 目標用於設定和/或更改資料包中的服務型別欄位。這可以用於建立有關資料包應如何路由等的網路策略。請注意,這尚未完善,並且在 Internet 上並未真正實現,大多數路由器並不關心此欄位中的值,有時它們的行為會根據接收到的內容而出現故障。換句話說,除非您想使用 iproute2 對其進行路由決策,否則不要將此設定為傳送到 Internet 的資料包。
TTL 目標用於更改資料包的 TTL(生存時間)欄位。我們可以告訴資料包只具有特定的 TTL 等等。這樣做的一個很好的理由可能是我們不想向愛窺探的網際網路服務提供商洩露我們的行蹤。一些網際網路服務提供商不喜歡使用者在一個單一連線上執行多臺計算機,並且有一些網際網路服務提供商已知會查詢生成不同 TTL 值的單個主機,並將其視為連線到單個連線的多臺計算機的許多跡象之一。
MARK 目標用於將特殊標記值設定為資料包。然後,iproute2 程式可以識別這些標記,根據資料包的標記或是否沒有標記來執行不同的資料包路由。我們還可以根據這些標記執行頻寬限制和基於類別的排隊。
NAT 表
[edit | edit source]此表僅用於對不同資料包執行 NAT(網路地址轉換)。換句話說,它應該僅用於轉換資料包的源欄位或目標欄位。請注意,如前所述,只有流中的第一個資料包會命中此鏈。此後,其餘資料包將自動執行與第一個資料包相同的操作。執行此類操作的實際目標是
- DNAT
- SNAT
- MASQUERADE
DNAT 目標主要用於您擁有公共 IP 並且想要將對防火牆的訪問重定向到其他主機(例如 DMZ)的情況。換句話說,我們更改資料包的目標地址並將其重新路由到主機。
SNAT 主要用於更改資料包的源地址。在大多數情況下,您將隱藏您的本地網路或 DMZ 等等。一個很好的例子是防火牆,我們知道外部 IP 地址,但需要用防火牆的 IP 地址替換本地網路的 IP 地址。使用此目標,防火牆將自動對資料包進行 SNAT 和 De-SNAT,從而可以從 LAN 建立到 Internet 的連線。例如,如果您的網路使用 192.168.0.0/netmask,那麼資料包將永遠無法從 Internet 返回,因為 IANA 已將這些網路(以及其他網路)劃分為私有網路,僅供隔離的 LAN 使用。
MASQUERADE 目標的使用方式與 SNAT 完全相同,但 MASQUERADE 目標需要更多的計算開銷。原因是,每次 MASQUERADE 目標被資料包命中時,它會自動檢查要使用的 IP 地址,而不是像 SNAT 目標那樣 - 只使用配置的單個 IP 地址。MASQUERADE 目標使使用您的 ISP 可能會為您提供的 PPP、PPPoE 或 SLIP 連線到 Internet 的動態 DHCP IP 地址成為可能。
Filter 表
[edit | edit source]Filter 表主要用於過濾資料包。我們可以匹配資料包並以任何我們想要的方式過濾它們。這是我們實際上對資料包採取行動並檢視它們包含的內容,並根據它們的內容將其丟棄或接受的地方。當然,我們也可以進行預過濾;但是,此特定表是為其設計過濾的地方。幾乎所有目標都可以在此鏈中使用。我們將在此處對 Filter 表更加詳細地說明;但是您現在知道,此表是進行主要過濾的正確地方。
狀態機
[edit | edit source]狀態機是 iptables 中的一個特殊部分,其實不應該被稱為狀態機,因為它實際上是一個連線跟蹤機器。然而,大多數人還是習慣用第一個名字稱呼它。在本章中,我將或多或少地使用這兩個名稱,就好像它們是同義詞一樣。這應該不會造成過多的混淆。連線跟蹤的作用是讓 Netfilter 框架了解特定連線的狀態。實現這一點的防火牆通常被稱為狀態防火牆。狀態防火牆通常比無狀態防火牆安全得多,因為它允許我們編寫更嚴格的規則集。
在 iptables 中,資料包可以與跟蹤的連線關聯起來,分為四種不同的狀態。它們被稱為 NEW、ESTABLISHED、RELATED 和 INVALID。我們將在稍後更深入地討論每一種狀態。使用 --state 匹配,我們可以輕鬆地控制誰或什麼可以發起新的會話。
所有連線跟蹤都是由核心中一個稱為 conntrack 的特殊框架完成的。conntrack 可以作為模組載入,也可以作為核心本身的內部部分載入。大多數情況下,我們需要並希望比預設的 conntrack 引擎所能維護的更具體的連線跟蹤。因此,conntrack 中還有更具體的模組來處理 TCP、UDP 或 ICMP 協議,以及其他協議。這些模組從資料包中獲取特定、唯一的資訊,以便它們可以跟蹤每個資料流。conntrack 收集的資訊隨後用於告訴 conntrack 當前資料流處於哪個狀態。例如,UDP 資料流通常由其目標 IP 地址、源 IP 地址、目標埠和源埠唯一標識。在以前的核心中,我們可以選擇開啟或關閉碎片重組。然而,自從引入了 iptables 和 Netfilter,特別是連線跟蹤之後,這個選項就被取消了。原因是,連線跟蹤無法在不進行資料包碎片重組的情況下正常工作,因此碎片重組已經被整合到 conntrack 中,並自動執行。它無法被關閉,除非關閉連線跟蹤。如果開啟連線跟蹤,就會始終執行碎片重組。
所有連線跟蹤都在 PREROUTING 鏈中處理,除了本地生成的包,它們在 OUTPUT 鏈中處理。這意味著 iptables 會在 PREROUTING 鏈中執行所有狀態的重新計算等操作。如果我們傳送資料流中的初始包,狀態在 OUTPUT 鏈中被設定為 NEW,當我們收到返回包時,狀態在 PREROUTING 鏈中被更改為 ESTABLISHED,依此類推。如果第一個包不是由我們自己發起的,那麼 NEW 狀態將在 PREROUTING 鏈中設定,當然。因此,所有狀態更改和計算都在 nat 表的 PREROUTING 和 OUTPUT 鏈中完成。
conntrack 條目
[edit | edit source]讓我們簡要地看一下 conntrack 條目以及如何在 /proc/net/ip_conntrack 中讀取它們。這列出了 conntrack 資料庫中的所有當前條目。如果已載入 ip_conntrack 模組,則 /proc/net/ip_conntrack 的 cat 可能看起來像
tcp 6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
dport=22 [UNREPLIED] src=192.168.1.9 dst=192.168.1.6 sport=22 \
dport=32775 use=2
此示例包含 conntrack 模組維護的所有資訊,以瞭解特定連線處於哪個狀態。首先,我們有一個協議,在本例中是 tcp。接下來,是相同的值,以正常的十進位制編碼表示。在此之後,我們看到這個 conntrack 條目還有多少時間存活。該值現在設定為 117 秒,並且會定期遞減,直到我們看到更多流量。然後,該值將重置為與它在相關時間點所處狀態相對應的預設值。接下來是該條目在當前時間點所處的實際狀態。在上面提到的例子中,我們看到的是一個處於 SYN_SENT 狀態的包。連線的內部值與在 iptables 中使用的外部值略有不同。SYN_SENT 值告訴我們,我們看到的是一個連線,它在一個方向上只看到了一個 TCP SYN 包。接下來,我們看到源 IP 地址、目標 IP 地址、源埠和目標埠。此時,我們看到一個特定的關鍵字,告訴我們我們沒有看到該連線的任何返回流量。最後,我們看到我們對返回包的預期。該資訊詳細說明了源 IP 地址和目標 IP 地址(它們都被反轉了,因為資料包要被定向回我們)。源埠和目標埠也是如此。這些是我們應該感興趣的值。
連線跟蹤條目可能採用一系列不同的值,所有這些值都指定在 conntrack 標頭檔案中,這些標頭檔案在 linux/include/netfilter-ipv4/ip_conntrack*.h 檔案中可用。這些值取決於我們使用的 IP 子協議。TCP、UDP 或 ICMP 協議採用特定預設值,如 linux/include/netfilter-ipv4/ip_conntrack.h 中所指定。我們將在檢視每個協議時更詳細地檢視這一點;但是,我們不會在本章中廣泛使用它們,因為它們在 conntrack 內部以外的地方沒有使用。此外,根據此狀態的更改方式,連線被銷燬之前的時間預設值也會改變。
最近,iptables patch-o-matic 中釋出了一個新的補丁,稱為 tcp-window-tracking。這個補丁在其他東西中添加了所有上述超時,並將它們新增到特殊的 sysctl 變數中,這意味著它們可以在系統執行時動態更改。因此,每次想要更改超時時就不需要重新編譯核心了。可以透過使用 /proc/sys/net/ipv4/netfilter 目錄中提供的特定系統呼叫來更改這些超時。你應該特別檢視 /proc/sys/net/ipv4/netfilter/ip_ct_* 變數。
當連線在兩個方向上都看到了流量時,conntrack 條目將擦除 [UNREPLIED] 標誌,然後重置它。該條目告訴我們,該連線在兩個方向上都沒有看到任何流量,將被 [ASSURED] 標誌替換,該標誌位於條目的末尾附近。[ASSURED] 標誌告訴我們,該連線是確定的,如果我們達到最大可能的跟蹤連線數,它不會被擦除。因此,標記為 [ASSURED] 的連線不會被擦除,與非確定連線(那些沒有標記為 [ASSURED] 的連線)相反。連線跟蹤表可以容納多少連線取決於一個變數,該變數可以透過最近核心中的 ip-sysctl 函式設定。該條目所持有的預設值根據你的記憶體大小而有很大差異。在 128 MB 的 RAM 上,你將獲得 8192 個可能的條目,而在 256 MB 的 RAM 上,你將獲得 16376 個條目。你可以透過 /proc/sys/net/ipv4/ip_conntrack_max 設定來讀取和設定你的設定。
使用者空間狀態
[edit | edit source]正如你所看到的,資料包在核心本身中可能處於幾種不同的狀態,具體取決於我們討論的是什麼協議。然而,在核心外部,我們只有前面描述的 4 種狀態。這些狀態主要可以與狀態匹配一起使用,然後狀態匹配將能夠根據資料包當前的連線跟蹤狀態來匹配資料包。有效狀態為 NEW、ESTABLISHED、RELATED 和 INVALID 狀態。下表將簡要解釋每種可能的狀態
這些狀態可以與 --state 匹配一起使用,以根據資料包的連線跟蹤狀態來匹配資料包。這就是狀態機對於我們的防火牆如此強大而高效的原因。以前,我們經常不得不開啟 1024 以上的所有埠,以便讓所有流量重新進入我們的本地網路。有了狀態機,就不再需要這樣做了,因為我們現在只需要為返回流量開啟防火牆,而不需要為所有其他型別的流量開啟防火牆。
TCP 連線
[edit | edit source]在本節和接下來的幾節中,我們將更仔細地研究狀態以及它們是如何針對三種基本協議 TCP、UDP 和 ICMP 處理的。此外,我們將更仔細地研究在預設情況下如何處理連線,如果它們不能歸類為這三種協議中的任何一種。我們選擇從 TCP 協議開始,因為它本身就是一個有狀態的協議,並且在 iptables 的狀態機方面有很多有趣的細節。
TCP 連線總是以 3 次握手的方式啟動,這建立並協商實際的連線,資料將透過該連線傳送。整個會話從一個 SYN 包開始,然後是一個 SYN/ACK 包,最後是一個 ACK 包來確認整個會話的建立。此時,連線已建立,可以開始傳送資料。最大的問題是,連線跟蹤如何連線到這個過程中?實際上很簡單。
就使用者而言,連線跟蹤對於所有連線型別的工作原理基本相同。請檢視下面的圖片,瞭解資料流在連線的不同階段進入哪個狀態。正如你所看到的,連線跟蹤程式碼並沒有真正遵循 TCP 連線的流程,從使用者的角度來看。一旦它看到一個包(SYN),它就認為連線是 NEW。一旦它看到返回包(SYN/ACK),它就認為連線是 ESTABLISHED。如果你仔細想想,你就會明白為什麼。透過這種特殊的實現,你可以允許 NEW 和 ESTABLISHED 包離開你的本地網路,只允許 ESTABLISHED 連線返回,並且這將完美地工作。相反,如果連線跟蹤機器將整個連線建立視為 NEW,那麼我們實際上永遠無法阻止外部連線到我們的本地網路,因為我們必須允許 NEW 包再次進入。為了使事情更加複雜,核心內部使用了許多其他內部狀態來處理 TCP 連線,但這些狀態在使用者空間不可用。粗略地說,它們遵循 RFC 793 - 傳輸控制協議第 21-23 頁中指定的 state 標準。
正如你所看到的,從使用者的角度來看,這實際上非常簡單。然而,從核心的角度來看,整個結構要複雜一些。讓我們看一個例子。考慮連線狀態在 /proc/net/ip_conntrack 表中是如何變化的。第一個狀態是在連線中收到第一個 SYN 包時報告的。
tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 \
dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 \
dport=1031 use=1
如上條目所示,我們處於一個精確的狀態,其中已傳送 SYN 資料包(已設定 SYN_SENT 標誌),但尚未傳送任何回覆(請注意 [UNREPLIED] 標誌)。當我們在另一個方向看到另一個數據包時,將到達下一個內部狀態。
tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 \
dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 \
use=1
現在我們已經收到了相應的 SYN/ACK 作為回覆。一旦接收到此資料包,狀態就會再次改變,這次變為 SYN_RECV。SYN_RECV 告訴我們原始 SYN 已成功傳送,並且 SYN/ACK 回覆資料包也已正確透過防火牆。此外,此連線跟蹤條目現在已在兩個方向上看到流量,因此被認為已得到回覆。這不是明確的,而是假設的,就像上面的 [UNREPLIED] 標誌一樣。一旦我們看到 3 次握手中的最終 ACK,最後一步將完成。
tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 \
sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 \
sport=23 dport=1031 use=1
在最後一個例子中,我們已經收到了 3 次握手中的最終 ACK,並且連線已進入 ESTABLISHED 狀態,就 iptables 的內部機制而言。在幾個資料包之後,連線也將變為 [ASSURED],如本章介紹部分所示。當 TCP 連線關閉時,它以以下方式完成並經過以下狀態。
如您所見,連線在傳送最後一個 ACK 之前永遠不會真正關閉。請注意,此圖僅描述了在正常情況下如何關閉連線。例如,如果拒絕連線,則可以透過傳送 RST(重置)來關閉連線。在這種情況下,連線將在預定的時間後關閉。
當 TCP 連線關閉時,連線進入 TIME_WAIT 狀態,預設情況下設定為 2 分鐘。這是為了確保即使連線已關閉,所有亂序到達的資料包仍能透過我們的規則集。這用作一種緩衝時間,以便卡在某個擁塞路由器中的資料包仍然可以到達防火牆或連線的另一端。
如果連線由 RST 資料包重置,則狀態將變為 CLOSE。這意味著連線預設情況下有 10 秒的時間才能徹底關閉。RST 資料包不會以任何方式進行確認,並且會直接斷開連線。除了我們已經介紹過的狀態之外,還有一些其他的狀態。
以下是 TCP 流可能採取的所有狀態及其超時值的完整列表。
這些值絕對不是絕對的。它們可能會隨著核心版本的改變而改變,也可能透過 /proc/sys/net/ipv4/netfilter/ip_ct_tcp_* 變數在 proc 檔案系統中改變。但是,預設值應該在實踐中相當穩定。這些值以節拍(或 1/100 秒)設定,因此 3000 表示 30 秒。
還要注意,狀態機中的使用者空間不檢視 TCP 資料包中設定的 TCP 標誌。這通常是不好的,因為您可能希望允許 NEW 狀態的資料包透過防火牆,但是當您指定 NEW 標誌時,大多數情況下是指 SYN 資料包。
UDP 連線
[edit | edit source]UDP 連線本身不是有狀態連線,而是無狀態連線。有幾個原因,主要是因為它們不包含任何連線建立或連線關閉;最重要的是它們缺乏排序。以特定順序接收兩個 UDP 資料報並不能說明它們傳送的順序。但是,仍然可以在核心中設定連線上的狀態。讓我們看看如何跟蹤連線以及它在 conntrack 中可能是什麼樣子。
如您所見,連線的建立方式與 TCP 連線幾乎完全相同。也就是說,從使用者空間的角度來看。在內部,conntrack 資訊看起來完全不同,但本質上細節相同。首先,讓我們看看初始 UDP 資料包傳送後的條目。
udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 \
[UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 \
dport=137 use=1
從第一個和第二個值可以看出,這是一個 UDP 資料包。第一個是協議名稱,第二個是協議編號。這與 TCP 連線完全相同。第三個值標記此狀態條目可以生存多少秒。在此之後,我們獲得了我們已經看到的資料包的值以及從發起資料包傳送者那裡到達我們的連線上的資料包的未來期望。這些是源、目的地、源埠和目標埠。此時,[UNREPLIED] 標誌告訴我們到目前為止還沒有對資料包的響應。最後,我們得到了返回資料包的預期列表。請注意,後者的條目順序與第一個值的順序相反。此時超時設定為 30 秒,這是預設值。
udp 17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 \
dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 \
dport=137 use=1
此時,伺服器已經看到對傳送出去的第一個資料包的回覆,並且連線現在被認為是 ESTABLISHED。正如您所看到的,這在連線跟蹤中沒有顯示。主要區別在於 [UNREPLIED] 標誌現在已經消失了。此外,預設超時已更改為 180 秒,但在本例中,它現在已減少到 170 秒——在 10 秒內,它將變為 160 秒。不過,還有一件事是缺失的,並且可能會發生一些變化,那就是上面描述的 [ASSURED] 標誌。為了在跟蹤的連線上設定 [ASSURED] 標誌,必須在該連線上有一些流量。
udp 17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 \
dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 \
dport=1025 [ASSURED] use=1
此時,連線已變得可靠。該連線與前面的示例完全相同,除了 [ASSURED] 標誌。如果此連線在 180 秒內未使用,它將超時。180 秒是一個相對較低的值,但對於大多數用途來說應該足夠。對於每個與同一條目匹配並透過防火牆的資料包,此值將重置為其完整值,就像所有內部狀態一樣。
ICMP 連線
[edit | edit source]ICMP 資料包遠非有狀態流,因為它們僅用於控制,永遠不會建立任何連線。但是,有四種 ICMP 型別會生成返回資料包,它們有兩種不同的狀態。這些 ICMP 訊息可以採用 NEW 和 ESTABLISHED 狀態。我們談論的 ICMP 型別是回顯請求和回覆、時間戳請求和回覆、資訊請求和回覆,以及地址掩碼請求和回覆。在這其中,時間戳請求和資訊請求已經過時,很可能可以直接丟棄。但是,回顯訊息在 ping 主機等多種設定中使用。地址掩碼請求並不常用,但在某些情況下可能有用,值得允許。為了瞭解這可能是什麼樣子,請檢視以下影像。
如上圖所示,主機向目標傳送回顯請求,防火牆將其視為 NEW。然後目標用回顯回覆進行響應,防火牆將其視為狀態 ESTABLISHED。當看到第一個回顯請求時,以下狀態條目將進入 ip_conntrack。
icmp 1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 \
id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 \
type=0 code=0 id=33029 use=1
如您所見,此條目看起來與 TCP 和 UDP 的標準狀態略有不同。協議在裡面,超時也在裡面,還有源地址和目標地址。但是,問題出現在此之後。我們現在有 3 個新的欄位,稱為型別、程式碼和 id。它們並不特殊,型別欄位包含 ICMP 型別,程式碼欄位包含 ICMP 程式碼。這些都在 ICMP 型別附錄中提供。最後一個 id 欄位包含 ICMP ID。每個 ICMP 資料包在傳送時都會設定一個 ID,當接收方接收到 ICMP 訊息時,它會在新的 ICMP 訊息中設定相同的 ID,以便傳送方能夠識別回覆,並能夠將其與正確的 ICMP 請求聯絡起來。
下一個欄位,我們再次將其識別為 [UNREPLIED] 標誌,我們之前已經見過它。與之前一樣,此標誌告訴我們目前正在檢視一個僅在一個方向上看到流量的連線跟蹤條目。最後,我們看到了回覆 ICMP 資料包的回覆預期,它是原始源和目標 IP 地址的反轉。至於型別和程式碼,這些將更改為回覆資料包的正確值,因此回顯請求將更改為回顯回覆,依此類推。ICMP ID 從請求資料包中保留下來。
回覆資料包被認為是 ESTABLISHED,正如我們已經解釋過的。但是,我們可以確定,在 ICMP 回覆之後,在相同的連線中絕對不會再有任何合法流量。為此,一旦回覆透過 Netfilter 結構傳播,連線跟蹤條目就會被銷燬。
在上述每種情況下,請求被認為是 NEW,而回覆被認為是 ESTABLISHED。讓我們更仔細地考慮一下。當防火牆看到請求資料包時,它將其視為 NEW。當主機向請求傳送回覆資料包時,它被認為是 ESTABLISHED。
請注意,這意味著回覆資料包必須與連線跟蹤條目中給定的標準相匹配,才能被視為已建立,就像所有其他流量型別一樣。
ICMP 請求的預設超時時間為 30 秒,您可以在 /proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout 條目中更改此值。通常,這應該是一個很好的超時時間,因為它能夠捕獲大多數傳輸中的資料包。
ICMP 的另一個非常重要的部分是它用於告知主機特定 UDP 和 TCP 連線或連線嘗試發生了什麼。由於這個簡單的原因,ICMP 回覆通常會被識別為與原始連線或連線嘗試相關。一個簡單的例子是 ICMP 主機不可達或 ICMP 網路不可達。如果我們的主機嘗試與其他主機建立不成功的連線,則這些訊息應始終被髮送回我們的主機,但網路或主機可能已關閉,因此最後一個嘗試到達目標站點的路由器將回復 ICMP 訊息告訴我們。在這種情況下,ICMP 回覆被視為相關資料包。以下圖片應該可以解釋它的外觀。
在上面的示例中,我們向特定地址傳送 SYN 資料包。這被防火牆視為新的連線。但是,資料包試圖到達的網路不可達,因此路由器向我們返回網路不可達的 ICMP 錯誤。連線跟蹤程式碼可以識別此資料包與已新增的跟蹤條目相關。因此,ICMP 回覆將正確傳送到客戶端,然後客戶端將希望中止。同時,防火牆銷燬了連線跟蹤條目,因為它知道這是一個錯誤訊息。
如果 UDP 連線遇到上述任何問題,也會出現與上述相同的行為。所有作為 UDP 連接回復發送的 ICMP 訊息都視為相關訊息。考慮以下影像。
這次,UDP 資料包被髮送到主機。此 UDP 連線被視為新的。但是,該網路被途中的某些防火牆或路由器在管理上禁止。因此,我們的防火牆收到了一個 ICMP 網路禁止的回覆。防火牆知道此 ICMP 錯誤訊息與已開啟的 UDP 連線相關,並將其作為相關資料包傳送到客戶端。此時,防火牆銷燬了連線跟蹤條目,客戶端收到 ICMP 訊息,並希望中止。
預設連線
[edit | edit source]在某些情況下,conntrack 機器不知道如何處理特定的協議。如果它對該協議不瞭解,或者不知道它的工作原理,就會發生這種情況。在這些情況下,它會回到預設行為。例如,預設行為用於 NETBLT、MUX 和 EGP。這種行為看起來非常類似於 UDP 連線跟蹤。第一個資料包被視為新的,回覆流量等等被視為已建立。
使用預設行為時,所有這些資料包都將獲得相同的預設超時時間。這可以透過 /proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout 變數設定。此處的預設值為 600 秒,即 10 分鐘。根據您嘗試透過使用預設連線跟蹤行為的鏈路傳送的流量型別,可能需要更改此值。特別是如果您透過衛星等網路傳輸流量,這可能需要很長時間。
複雜協議和連線跟蹤
[edit | edit source]某些協議比其他協議更復雜。當涉及到連線跟蹤時,這意味著這些協議可能更難正確跟蹤。這些協議的典型例子是 ICQ、IRC 和 FTP 協議。這些協議中的每一個都在資料包的實際資料有效負載中攜帶資訊,因此需要特殊的連線跟蹤幫助程式才能使其正常工作。
以 FTP 協議為例。FTP 協議首先開啟一個稱為 FTP 控制會話的單一連線。當我們透過此會話發出命令時,其他埠將被開啟以承載與該特定命令相關聯的其餘資料。這些連線可以透過兩種方式進行,主動或被動。當連線被主動建立時,FTP 客戶端向伺服器傳送一個埠和 IP 地址以進行連線。之後,FTP 客戶端開啟埠,伺服器從自己的埠 20(稱為 FTP-Data)連線到該指定埠,並透過它傳送資料。
這裡的問題是,防火牆將不知道這些額外的連線,因為它們是在協議資料的實際有效負載中協商的。因此,防火牆將無法知道它應該允許伺服器透過這些特定埠連線到客戶端。
解決此問題的方法是向連線跟蹤模組新增一個特殊的幫助程式,該幫助程式將掃描控制連線中的資料以查詢特定語法和資訊。當它遇到正確的資訊時,它會將該特定資訊新增為相關資訊,並且伺服器將能夠跟蹤連線,這要歸功於該相關條目。考慮以下圖片以瞭解 FTP 伺服器連接回客戶端時的狀態。
被動 FTP 以相反的方式工作。FTP 客戶端告訴伺服器它想要一些特定資料,伺服器會回覆一個連線的 IP 地址和埠。客戶端收到此資料後,將從自己的埠 20(FTP-data 埠)連線到該特定埠,並獲取相關資料。換句話說,如果您的防火牆後面有一個 FTP 伺服器,除了標準 iptables 模組之外,您還需要此模組才能讓 Internet 上的客戶端正確連線到 FTP 伺服器。如果您對使用者極其嚴格,並且只希望他們訪問 Internet 上的 HTTP 和 FTP 伺服器並阻止所有其他埠,也是如此。考慮以下影像及其對被動 FTP 的影響。
某些 conntrack 幫助程式已在核心本身中可用。更具體地說,截至本文撰寫時,FTP 和 IRC 協議已包含 conntrack 幫助程式。如果您在核心本身中找不到所需的 conntrack 幫助程式,您應該檢視使用者空間 iptables 中的 patch-o-matic 樹。patch-o-matic 樹可能包含更多 conntrack 幫助程式,例如用於 ntalk 或 H.323 協議的幫助程式。
Conntrack 幫助程式可以靜態編譯到核心中,也可以作為模組編譯。如果它們作為模組編譯,您可以使用以下命令載入它們
modprobe ip_conntrack_*
請注意,連線跟蹤與 NAT 無關,因此如果您也正在進行 NAT 連線,則可能需要更多模組。例如,如果您想 NAT 並跟蹤 FTP 連線,您還需要 NAT 模組。所有 NAT 幫助程式都以 ip_nat_ 開頭,並遵循該命名約定;因此,例如,FTP NAT 幫助程式將命名為 ip_nat_ftp,而 IRC 模組將命名為 ip_nat_irc。conntrack 幫助程式遵循相同的命名約定,因此 IRC conntrack 幫助程式將命名為 ip_conntrack_irc,而 FTP conntrack 幫助程式將命名為 ip_conntrack_ftp。
如何構建規則
[edit | edit source]正如我們已經解釋的,每個規則都是核心檢視的一行,以找出如何處理資料包。如果滿足所有條件(或匹配),我們將執行目標(或跳轉)指令。通常我們會以類似於這樣的語法編寫我們的規則
iptables [-t table] command [match] [target/jump]
沒有任何規定說目標指令必須是行中的最後一個函式。但是,您通常會堅持這種語法以獲得最佳可讀性。無論如何,您將看到的大多數規則都是以這種方式編寫的。因此,如果您閱讀了其他人的指令碼,您很可能會識別出語法並輕鬆理解規則。
如果您想使用其他表而不是標準表,您可以在指定 [table] 的位置插入表規範。但是,不需要明確說明要使用哪個表,因為預設情況下 iptables 使用 filter 表來實現所有命令。您也不必只在規則中的這一點處指定表。它幾乎可以設定在行中的任何地方。但是,將表規範放在開頭是或多或少標準的做法。
但有一點需要考慮:命令應始終放在最前面,或者可選地直接放在表規範之後。我們使用“command”來告訴程式要做什麼,例如插入規則或將規則新增到鏈的末尾,或者刪除規則。我們將在下面進一步討論這一點。匹配是我們傳送到核心的規則部分,它詳細說明了資料包的具體特徵,是什麼使它與所有其他資料包不同。在這裡,我們可以指定資料包來自哪個 IP 地址、來自哪個網路介面、目標 IP 地址、埠、協議或其他任何內容。我們可以使用大量的不同匹配,我們將在下面進一步討論這些匹配。
最後我們有了資料包的目標。如果所有匹配都滿足了某個資料包,我們會告訴核心如何處理它。例如,我們可以告訴核心將資料包傳送到我們自己建立的另一個鏈,該鏈是該特定表的組成部分。我們可以告訴核心直接丟棄資料包,不再進行處理,或者我們可以告訴核心向傳送者傳送指定的回覆。與本節中的其餘內容一樣,我們將在下面進一步討論它。
表格
[edit | edit source]-t 選項指定要使用的表。預設情況下,使用 filter 表。我們可以使用 -t 選項指定以下表之一。請注意,這是一個極其簡短的摘要
命令
[edit | edit source]在本節中,我們將介紹所有不同的命令以及如何使用它們。該命令告訴 iptables 如何處理我們傳送到解析器的規則的其餘部分。通常我們想要在某個表中新增或刪除某些內容。以下命令可用於 iptables
除非您只是想檢視 iptables 的內建幫助或獲取命令的版本,否則您應始終輸入完整的命令列。要獲取版本,請使用 -v 選項,要獲取幫助資訊,請使用 -h 選項。像往常一樣,換句話說。接下來是一些可以在不同命令中使用的選項。請注意,我們會告訴您哪些命令可以使用這些選項以及它們會產生什麼影響。還要注意,這裡不包含任何影響規則或匹配的選項。相反,我們將在本章的後面部分介紹匹配和目標。
選項
匹配
[edit | edit source]首先,我們有通用的匹配,它們可以在所有規則中使用。然後我們有 TCP 匹配,它們只能應用於 TCP 資料包。我們有 UDP 匹配,它們只能應用於 UDP 資料包,還有 ICMP 匹配,它們只能用於 ICMP 資料包。最後,我們有特殊的匹配,例如狀態、所有者和限制匹配等等。這些最終的匹配又進一步細分為更多子類別,即使它們可能並不一定是不同的匹配。
通用匹配
[edit | edit source]本節將介紹通用匹配。通用匹配是一種始終可用的匹配,無論我們使用哪種協議,或者載入了哪些匹配擴充套件。使用這些匹配不需要任何特殊引數;換句話說。我還包括了 --protocol 匹配,即使它更特定於協議匹配。例如,如果我們想使用 TCP 匹配,我們需要使用 --protocol 匹配並將 TCP 作為選項傳送給匹配。但是,--protocol 本身也是一個匹配,因為它可以用於匹配特定協議。以下匹配始終可用。
通用匹配
隱式匹配
[edit | edit source]這些是隱式載入的匹配。隱式匹配是隱含的、理所當然的、自動的。例如,當我們匹配 --protocol tcp 而不使用任何其他條件時。目前,三種協議有三種類型的隱式匹配。它們是 TCP 匹配、UDP 匹配和 ICMP 匹配。基於 TCP 的匹配包含一組僅適用於 TCP 資料包的唯一條件。基於 UDP 的匹配包含另一組僅適用於 UDP 資料包的條件。ICMP 資料包也是如此。另一方面,可以有顯式匹配,它們是顯式載入的。顯式匹配不是隱含的或自動的,您必須專門指定它們。對於這些匹配,您使用 -m 或 --match 選項,我們將在下一節中討論。
TCP 匹配
[edit | edit source]這些匹配是特定於協議的,並且僅在使用 TCP 資料包和流時可用。要使用這些匹配,您需要在嘗試使用它們之前在命令列中指定 --protocol tcp。請注意,--protocol tcp 匹配必須位於協議特定匹配的左側。從某種意義上說,這些匹配是隱式載入的,就像 UDP 和 ICMP 匹配是隱式載入的一樣。其他匹配將在 TCP 匹配部分之後在本節的後續部分中進行介紹。
UDP 匹配
[edit | edit source]將僅與 UDP 資料包一起使用。當您指定 --protocol UDP 匹配時,這些匹配會隱式載入,並且在進行此指定後會可用。請注意,UDP 資料包不是面向連線的,因此沒有在資料包中設定不同的標誌以提供有關資料報應該執行的操作(例如開啟或關閉連線,或者它們是否應該簡單地傳送資料)的資訊。UDP 資料包也不需要任何型別的確認。如果它們丟失,它們就會簡單地丟失(不考慮 ICMP 錯誤訊息等)。這意味著與 TCP 資料包相比,UDP 資料包的匹配要少得多。請注意,狀態機將處理所有型別的資料包,即使 UDP 或 ICMP 資料包被視為無連線協議。狀態機在 UDP 資料包上的工作方式與在 TCP 資料包上的工作方式基本相同。
ICMP 匹配
[edit | edit source]這些是 ICMP 匹配。從某種意義上說,這些資料包比 UDP 資料包更短暫,即生命週期更短,因為它們是無連線的。ICMP 協議主要用於錯誤報告以及連線控制等。ICMP 不是 IP 協議的從屬協議,而是一種增強 IP 協議並幫助處理錯誤的協議。ICMP 資料包的報頭與 IP 報頭非常相似,但在許多方面有所不同。該協議的主要特徵是型別報頭,它告訴我們資料包的用途。例如,如果我們嘗試訪問不可訪問的 IP 地址,通常會收到 ICMP 主機不可達的回覆。有關 ICMP 型別的完整列表,請參閱 ICMP 型別的附錄。ICMP 資料包只有一個可用的 ICMP 特定匹配,希望這應該足夠了。當我們使用 --protocol ICMP 匹配時,此匹配會隱式載入,並且我們可以自動訪問它。請注意,所有通用匹配也可以使用,因此除了其他事項之外,我們還可以匹配源地址和目標地址。
顯式匹配
[edit | edit source]顯式匹配是指必須使用 -m 或 --match 選項專門載入的匹配。例如,狀態匹配要求在輸入您要使用的實際匹配之前使用指令 -m state。其中一些匹配可能是特定於協議的。有些可能與任何特定協議無關——例如連線狀態。它們可能是 NEW(尚未建立的連線的第一個資料包)、ESTABLISHED(已在核心中註冊的連線)、RELATED(由較舊的已建立連線建立的新連線)等等。少數可能只是為了測試或實驗目的而發展而來,或者只是為了說明 iptables 的功能。這反過來意味著並非所有這些匹配乍一看都有用。然而,您個人很可能會發現某些顯式匹配的用途。而且,隨著每個新 iptables 版本的釋出,不斷有新的匹配出現。您是否會找到它們的用途取決於您的想象力和需求。隱式載入的匹配和顯式載入的匹配之間的區別在於,隱式載入的匹配將在您匹配 TCP 資料包的屬性時自動載入,而顯式載入的匹配永遠不會自動載入——您需要自己發現並激活顯式匹配。
限制匹配
[edit | edit source]限制匹配擴充套件必須使用 -m limit 選項顯式載入。例如,此匹配可以用來有效地限制特定規則的日誌記錄等。例如,您可以使用它來匹配所有不超過給定值的包,並且在超過此值後,限制對所述事件的日誌記錄。想想時間限制:您可以限制某個規則在某個時間範圍內匹配的次數,例如減少 DoS syn 泛洪攻擊的影響。這是它的主要用法,當然還有更多用法。限制匹配也可以透過在限制匹配前面新增 ! 標誌來反轉。它將被表示為 -m limit ! --limit 5/s。這意味著所有資料包在超出限制後都會被匹配。
為了進一步解釋限制匹配,它基本上是一個令牌桶過濾器。想象有一個漏桶,桶以每時間單位 X 個數據包的速度漏水。X 的定義取決於我們獲得的匹配資料包數量,因此如果我們獲得 3 個數據包,則桶以每時間單位 3 個數據包的速度漏水。--limit 選項告訴我們每時間單位向桶中補充多少個數據包,而 --limit-burst 選項告訴我們桶最初有多大。因此,設定 --limit 3/minute --limit-burst 5,然後接收 5 個匹配項將清空桶。20 秒後,桶會補充另一個令牌,以此類推,直到再次達到 --limit-burst 或直到它們被使用。
請考慮以下示例,以進一步說明這可能是什麼樣子。
- 我們使用 -m limit --limit 5/second --limit-burst 10 設定一個規則。limit-burst 令牌桶最初設定為 10。每個與規則匹配的資料包都會使用一個令牌。
- 我們得到與規則匹配的資料包,1-2-3-4-5-6-7-8-9-10,所有資料包都在 1/1000 秒內。
- 令牌桶現在為空。一旦令牌桶為空,否則符合規則的資料包不再與規則匹配,並將繼續到下一個規則(如果有),或命中鏈策略。
- 每隔 1/5 秒如果沒有匹配的包,令牌計數就會增加 1,直到達到最大值 10。在收到 10 個包後 2 秒,我們將再次剩下 10 個令牌。
- 當然,對於每個收到的包,桶的令牌數量都會減少 1。
MAC(乙太網介質訪問控制)匹配可以用來根據包的 MAC 源地址進行匹配。截至撰寫本文件時,這種匹配功能有一些限制,但在未來可能會得到改進,變得更加實用。這種匹配只能用於根據源 MAC 地址進行匹配。
請注意,要使用此模組,我們需要使用 -m mac 選項顯式載入它。我之所以說這一點,是因為很多人想知道是否應該使用 -m mac-source,而實際上不應該。
標記匹配擴充套件用於根據包所設定的標記進行匹配。標記是一個特殊的欄位,僅在核心中維護,它與包在計算機中傳輸時相關聯。標記可供不同的核心例程用於諸如流量整形和過濾之類的任務。截至目前,在 Linux 中只有一種設定標記的方法,即 iptables 中的 MARK 目標。這以前是用 ipchains 中的 FWMARK 目標完成的,這就是為什麼人們在高階路由領域仍然提到 FWMARK 的原因。標記欄位當前設定為無符號整數,或 32 位系統上 4294967296 個可能的取值。換句話說,你很可能很長時間不會遇到這個限制。
多埠匹配擴充套件可以用來指定多個目標埠和埠範圍。如果沒有此匹配功能,你將不得不使用多個相同型別的規則來匹配不同的埠。
你不能同時使用標準埠匹配和多埠匹配,例如,你不能這樣寫:--sport 1024:63353 -m multiport --dport 21,23,80。這將無法工作。事實上,如果你這樣寫,iptables 會優先處理規則中的第一個元素,而忽略 multiport 指令。
所有者匹配擴充套件用於根據建立包的程序身份進行匹配。所有者可以指定為發出該命令的使用者、組、程序、會話或命令本身的程序 ID。此擴充套件最初是作為 iptables 用途的一個例子而編寫的。所有者匹配只在 OUTPUT 鏈中起作用,原因很明顯:幾乎不可能從另一端找出傳送包的例項的身份資訊,或者從中間跳躍到真實目標的例項的身份資訊。即使在 OUTPUT 鏈中,它也不太可靠,因為某些包可能沒有所有者。這類臭名昭著的包(除其他外)是不同的 ICMP 響應。ICMP 響應永遠不會匹配。
狀態匹配擴充套件與核心中的連線跟蹤程式碼結合使用。狀態匹配訪問 conntracking 機器的包的連線跟蹤狀態。這使我們能夠知道連線處於什麼狀態,並且適用於幾乎所有協議,包括無狀態協議,例如 ICMP 和 UDP。在所有情況下,連線將有一個預設超時時間,然後它將從連線跟蹤資料庫中刪除。此匹配需要透過向規則新增 -m state 語句來顯式載入。然後你就可以使用一個名為 state 的新匹配。
TOS 匹配可以用來根據包的 TOS 欄位進行匹配。TOS 代表**服務型別**,由 8 位組成,位於 IP 首部。此匹配透過向規則新增 -m tos 來顯式載入。TOS 通常用於通知中間主機流及其內容的優先順序(它實際上並沒有通知,而是通知流的任何特定要求,例如必須以最快的速度傳送,或者需要能夠傳送儘可能多的有效載荷)。不同的路由器和管理員如何處理這些值取決於他們自己。大多數人根本不在乎,而另一些人則盡力對這些包及其提供的資料做一些有益的事情。
TTL 匹配用於根據位於 IP 首部中的 TTL(生存時間)欄位進行匹配。TTL 欄位包含 8 位資料,每當它被客戶端和接收主機之間的中間主機處理一次,它就會減 1。如果 TTL 達到 0,則會向傳送包的一方傳送一個 ICMP 型別 11 程式碼 0(傳輸過程中 TTL 等於 0)或程式碼 1(重新組裝過程中 TTL 等於 0)的報文,通知它出現的問題。此匹配僅用於根據包的 TTL 進行匹配,而不會更改任何內容。順便說一下,這適用於所有型別的匹配。要載入此匹配,你需要向規則新增 -m ttl。
目標/跳轉告訴規則如何處理與規則匹配部分完全匹配的包。有幾個基本目標,ACCEPT 和 DROP 目標,我們將首先討論它們。但是,在我們這樣做之前,讓我們簡要地看一下跳轉是如何完成的。
跳轉規範與目標定義完全相同,只是它需要在同一個表內的鏈中進行跳轉。要跳轉到一個特定的鏈,前提是該鏈存在。正如我們已經解釋過的,使用者定義的鏈是用 -N 命令建立的。例如,假設我們在 filter 表中建立一個名為 tcp_packets 的鏈,如下所示:iptables -N tcp_packets
然後我們可以向它新增一個跳轉目標,如下所示
iptables -A INPUT -p tcp -j tcp_packets
然後我們將從 INPUT 鏈跳轉到 tcp_packets 鏈,並開始遍歷該鏈。當我們到達該鏈的末端時,我們會被丟回到 INPUT 鏈,並且包會從跳轉到另一個鏈(本例中是 tcp_packets)的規則下面一步開始遍歷。如果一個包在其中一個子鏈中被 ACCEPT,它也會在超集鏈中被 ACCEPT,並且它不會再遍歷任何超集鏈。但是,請注意,該包將按照正常方式遍歷其他表中的所有其他鏈。
另一方面,目標指定對目標包採取的操作。例如,我們可以根據我們的需要來 DROP 或 ACCEPT 該包。我們可能還想採取其他一些操作,我們將在本節後面部分對此進行描述。跳轉到目標可能會帶來不同的結果。有些目標會導致包停止遍歷該特定鏈和上面的鏈,如上所述。此類規則的典型例子是 DROP 和 ACCEPT。停止的規則不會透過該鏈中或上面鏈中的任何其他規則。其他目標可能會對包採取操作,然後包將繼續透過同一組鏈中的其他規則。這方面的典型例子是 LOG、ULOG 和 TOS 目標。這些目標可以記錄包、對其進行修改,然後將其傳遞給同一組鏈中的其他規則。例如,我們可能會: