netfilter/iptables 學習
netfilter概述
netfilter 元件位於核心空間(kernelspace),是核心的一部分,由一些資訊包過濾表組成,這些表包含核心用來控制資訊包過濾處理的規則集。
iptables 元件是一種使用者空間(userspace)的工具,用來插入、修改和除去資訊包過濾表中的規則。
Netfilter 提供了整個防火牆的框架,各個協議基於 Netfilter 框架來實現自己的功能。每個協議都有獨立的表來儲存自己的配置資訊,他們之間完全獨立的進行配置和執行。
下圖是netfilter的主要組成(來源wikipedia):
其中各模組說明:
- 鏈路層的防火牆模組,在鏈路層中對資料幀進行處理。對應使用者空間的配置工具是ebtables。
- 對ARP處理的防火牆模組,有獨立的表來存放自己的配置,對應使用者空間的配置工具是arptables。
- 網路層中ipv6的防火牆模組,在Ipv6協議棧中對報文進行處理,對應使用者空間的配置工具是ip6tables
- 網路層中ipv4的防火牆模組,在Ipv4協議棧中對報文進行處理,對應使用者空間的配置工具是iptables/nftables。
nftables是iptables的後繼者,nftables在使用者態把網路規則編譯成位元組碼,然後由核心的虛擬機器執行。
一個數據包在netfilter中的處理流程如下圖(來源wikipedia):
網路層中的hook
Netfilter 提供了5個網路層的hook,分別位於linux 網路棧中的各個處理節點,如下圖:
--->[NF_IP_PRE_ROUTING]--->[ROUTE]--->[NF_IP_FORWARD]--->[NF_IP_POST_ROUTING]---> | ^ | | | [ROUTE] v | [NF_IP_LOCAL_IN] [NF_IP_LOCAL_OUT] | ^ | | v | --------Local Process-------
Netfilter Hook的意義(參考:www.netfilter.org):
- NF_IP_PRE_ROUTING: 位於路由之前,報文一致性檢查之後(報文一致性檢查包括: 報文版本、報文長度和checksum)。
- NF_IP_LOCAL_IN: 位於報文經過路由之後,並且目的是本機的。
- NF_IP_FORWARD:位於在報文路由之後,目的地非本機的。
- NF_IP_LOCAL_OUT: 由本機發出去的報文,並且在路由之前。
- NF_IP_POST_ROUTING: 所有即將離開本機的報文。
Linux 核心模組可以註冊到任何的hook,註冊的回撥函式也必需指定優先順序。當一個報文通過hook的時候,hook將會依據優先順序呼叫回撥函式。註冊的回撥函式,可以有五種返回,每種返回代表對報文不同的操作:
- NF_ACCEPT: 繼續正常處理此報文,即允許報文通過。
- NF_DROP: 丟棄此報文,不再進行繼續處理,即拒絕此報文。
- NF_STOLEN: 取走這個報文,不再繼續處理。
- NF_QUEUE: 報文進行重新排隊,可以將報文發到使用者空間的程式,進行修改或者決定是拒絕或者允許。
- NF_REPEAT: 報文重新呼叫hook。
iptables的介紹
關於iptables的原理已經有很多部落格都介紹過了,這裡把我做的一個圖放上來供大家參考:
iptables常用的就是如上圖所示的四表五鏈(實際上還有個Security Table,應該是五個表,但這個表很少用):
- 四表:
- raw:可以對報文在鏈路跟蹤之前進行處理
- mangle:主要用於對報文的修改
- nat:主要用於NAT轉換
- filter:預設的規則表,用於報文的過濾
- 五鏈:PREROUTING, INPUT, OUTPUT, POSTROUTING, FORWARD,分別對應的是netfilter的五個hook。
iptables 工具使用
iptables命令基本格式:
iptables [-t table] [option] chain [rulenum] rule-specification
iptables 的操作是針對表中的鏈進行的,如果不指定,預設表為filter。
常用的Option如下
規則級別的修改:
-A | 新增規則到指定鏈最後一行 |
-D | 刪除指定鏈指定行 |
-I | 插入規則到指定鏈的指定行,預設插入第一行 |
-R | 替換規則到指定鏈指定行 |
針對規則查詢的:
-L | 列出指定鏈中所有規則,若未指定鏈,則列出所有規則。-n 以數字方式顯示,-v 顯示具體資訊 |
-S | 類似於-L,按照iptables-save的格式列印規則 |
鏈級別的修改:
-N | 新增自定義鏈 |
-X | 刪除指定鏈,如未指定,則預設刪除所有鏈 |
-P | 修改內建鏈的預設策略,值為ACCEPT或DROP |
-F | 刪除指定鏈中的所有規則,預設刪除所有規則(所有鏈都還在,只不過規則被清空) |
規則語法(rule-specification)
規則由包匹配和目標動作組成。目標動作由-j
選項指定。
常用的包匹配:
-p | 指定協議。常見的有:tcp, udp, icmp |
-s | 指定源地址,格式類似於192.168.1.0/24 ,多個地址使用逗號分隔,並且會自動形成多條規則 |
-d | 指定目的地址,格式與-s一樣 |
-i | 指定某網絡卡的流入規則 |
-o | 指定某網絡卡的流出規則 |
-m | 指定擴充套件匹配,可以匹配到特定性質的包。最常用的是tcp, udp, conntrack。當使用tcp和udp時,可以使用--dport指定目標地址埠,--sport指定源地址埠 |
大部分都支援使用!
進行反向匹配。如:
iptables -A INPUT -s 192.168.2.0/24 -p tcp ! -i enth0 -j ACCEPT
# 接受所有非enth0的網絡卡流入的源地址為192.168.2.0/24網段的包。
-j
中包含很多操作,比如對包的標記,ip地址的修改,ttl的修改等操作。某些操作只能在特定表和鏈中進行。
常用的動作:
-j user-chain |
跳轉到指定的自定義鏈。注意,自定義鏈匹配到最後一行以後會返回跳轉之前的地方繼續向後匹配 |
-j ACCEPT|DROP|REJECT |
設定策略 |
-j LOG [options] |
記錄日誌 |
-j MASQUERADE |
僅在nat表的POSTROUTING鏈中使用。用於snat自動轉換IP功能 |
-j SNAT |
僅在nat表的POSTROUTING鏈中使用 |
-j DNAT |
僅在nat表的PRETROUTING和OUTPUT鏈中使用 |
最後補充一個剛剛犯的錯誤:
在配置FORWARD的時候,要保證正常通訊,一定要配置雙向的規則。任何網絡卡流入的包首先經過的鏈都是PREROUTING。總結如下圖:
enth-a和enth-b都是主機的網絡卡。在FORWARD鏈上配置:
iptables -A FORWARD -i enth-a -j ACCEPT
iptables -A FORWARD -o enth-a -j ACCEPT
即可簡單實現雙網絡卡之間的互相轉發。