Linux數據包路由原理、Iptables/netfilter入門學習


相關學習資料

https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html
http://zh.wikipedia.org/wiki/Netfilter
http://www.netfilter.org/projects/iptables/
http://linux.vbird.org/linux_server/0250simple_firewall.php
http://linux.vbird.org/linux_server/0250simple_firewall.php
http://www.vpser.net/security/linux-iptables.html

 

目錄

1. Iptables/Netfilter原理分析
2. Linux數據包路由原理
3. Iptables規則編寫原則

 

1. Iptables/Netfilter原理分析

在文章的最開頭,我們首先要明確一個概念,Iptables/Netfilter到底是什么,它們之間的關系是怎樣的。

我們可以這樣簡單地理解:

1. Netfilter是Linux操作系統核心層內部的一個數據包處理模塊,它具有如下功能:
    1) 網絡地址轉換(Network Address Translate)
    2) 數據包內容修改
    3) 以及數據包過濾的防火牆功能
Netfilter平台中制定了五個數據包的掛載點(Hook Point,我們可以理解為回調函數點,數據包到達這些位置的時候會主動調用我們的函數,使我們有機會能在數據包路由的時候有機會改變它們
的方向、內容),這5個掛載點分別是
1) PRE_ROUTING 2) INPUT 3) OUTPUT 4) FORWARD 5) POST_ROUTING 2. Iptables Netfilter所設置的規則是存放在內核內存中的,Iptables是一個應用層(Ring3)的應用程序,它通過Netfilter放出的接口來對存放在內核內存中的Xtables(Netfilter的配置表)進行修改
(這是一個典型的Ring3和Ring0配合的架構)

Xtables

我們知道Netfilter是負責實際的數據流改變工作的內核模塊,而Xtables就是它的規則配置文件,Netfilter依照Xtables的規則來運行,Iptables在應用層負責修改這個規則文件。

Xtables由"表"、"鏈"、"規則rule"組成

1. Filter(表)
filter表是專門過濾包的,內建三個鏈,可以毫無問題地對包進行DROP、LOG、ACCEPT和REJECT等操作 
    1) INPUT(鏈)
    INPUT針對那些目的地是本地的包
        1.1) 規則rule
        ..
    2) FORWARD(鏈)
    FORWARD鏈過濾所有不是本地產生的並且目的地不是本地(即本機只是負責轉發)的包
        2.1) 規則rule
        ..
    3) OUTPUT(鏈)
    OUTPUT是用來過濾所有本地生成的包
        3.1) 規則rule
        ..
2. Nat(表)
Nat表的主要用處是網絡地址轉換,即Network Address Translation,縮寫為NAT。做過NAT操作的數據包的地址就被改變了,當然這種改變是根據我們的規則進行的。屬於一個流的包(因為包
的大小限制導致數據可能會被分成多個數據包)只會經過這個表一次。如果第一個包被允許做NAT或Masqueraded,那么余下的包都會自動地被做相同的操作。也就是說,余下的包不會再通過這個表
,一個一個的被NAT,而是自動地完成
1) PREROUTING(鏈) PREROUTING 鏈的作用是在包剛剛到達防火牆時改變它的目的地址 1.1) 規則rule      .. 2) INPUT(鏈) 2.1) 規則rule      .. 3) OUTPUT(鏈) OUTPUT鏈改變本地產生的包的目的地址 3.1) 規則rule      .. 4) POSTROUTING(鏈) POSTROUTING鏈在包就要離開防火牆之前改變其源地址。 4.1) 規則rule      .. 3. Mangle(表) 這個表主要用來mangle數據包。我們可以改變不同的包及包 頭的內容,比如 TTL,TOS或MARK。 注意MARK並沒有真正地改動數據包,它只是在內核空間為包設了一個標記。防火牆內的其他的規
則或程序(如tc)可以使用這種標記對包進行過濾或高級路由。注意,mangle表不能做任何NAT,它只是改變數據包的TTL,TOS或MARK,而不是其源目地址。NAT必須在nat表中操作的。
1) PREROUTING(鏈) PREROUTING在包進入防火牆之后、路由判斷之前改變 包 1.1) 規則rule      .. 2) INPUT(鏈) INPUT在包被路由到本地之后,但在用戶空間的程序看到它之前改變包 2.1) 規則rule      .. 3) FORWARD(鏈) FORWARD在最初的路由判斷之后、最后一次更改包的目的之前mangle包 3.1) 規則rule      .. 4) OUTPUT(鏈) OUTPUT在確定包的目的之前更改數據包 4.1) 規則rule      .. 5) POSTROUTING(鏈) POSTROUTING是在所有路由判斷之后 5.1) 規則rule      ..

Netfilter的Hook點

Netfilter的架構就是在整個網絡流程的若干位置放置了一些檢測點(HOOK)(或者說是回調函數),而在每個檢測點上登記(callback)了一些處理函數進行處理(如包過濾,NAT等,甚至可以是 用戶自定義的功能)

1. NF_IP_PRE_ROUTING:
剛剛通過數據鏈路層解包,進入網絡層的數據包通過此點(剛剛進行完版本號,校驗
和等檢測),目的地址轉換在此點進行
2. NF_IP_LOCAL_IN
經路由查找后,送往本機的通過此檢查點,INPUT包過濾在此點進行
3. NF_IP_FORWARD
要轉發的包通過此檢測點,FORWARD包過濾在此點進行
4. NF_IP_POST_ROUTING
所有馬上便要通過網絡設備出去的包通過此檢測點,內置的源地址轉換功能(包括地址偽裝)在此點進行
5. NF_IP_LOCAL_OUT
本機進程發出的包通過此檢測點,OUTPUT包過濾在此點進行

可以看到:

Iptables/Netfilter的工作是針對網絡的數據包進行修改的,所以,Iptables/Netfilter在某種程度上可以算是一種網絡層的路由器/防火牆

我們可以看到,通過"5個代表不同階段的Hook點""表、鏈、規則"這種"松耦合""規則型"的結構,我們作為管理員可以獲得最大程度的控制靈活性、可以有非常巨大的想象空間

Netfilter是由Rusty Russell提出的Linux 2.4內核防火牆框架,該框架既簡潔又靈活,可實現安全策略應用中的許多功能,如數據包過濾、數據包處理、地址偽裝、透明代理、動態網絡地址轉換(Network Address Translation,NAT),以及基於用戶及媒體訪問控制(Media Access Control,MAC)地址的過濾和基於狀態的過濾、包速率限制等
Iptables/Netfilter的這些規則可以通過靈活組合,形成非常多的功能、涵蓋各個方面,這一切都得益於它的優秀設計思想

 

2. Linux數據包路由原理

我們已經知道了Netfilter和Iptables的架構和作用,並且學習了控制Netfilter行為的Xtables表的結構,那么這個Xtables表是怎么在內核協議棧的數據包路由中起作用的呢?

網口數據包由底層的網卡NIC接收,通過數據鏈路層的解包之后(去除數據鏈路幀頭),就進入了"TCP/IP協議棧(本質就是一個處理網絡數據包的內核驅動)和Netfilter混合"的"數據包處理流程"中了。

數據包的接收、處理、轉發流程構成一個有限狀態向量機,經過一些列的內核處理函數、以及Netfilter Hook點,最后被轉發、或者本次上層的應用程序消化掉

從這張圖中,我們可以總結出以下規律:

1. 當一個數據包進入網卡時,數據包首先進入PREROUTING鏈,在PREROUTING鏈中我們有機會修改數據包的DestIP(目的IP),然后內核的"路由模塊"根據"數據包目的IP"以及"內核中的路由表"
判斷是否需要轉送出去(注意,這個時候數據包的DestIP有可能已經被我們修改過了) 2. 如果數據包就是進入本機的(即數據包的目的IP是本機的網口IP),數據包就會沿着圖向下移動,到達INPUT鏈。數據包到達INPUT鏈后,任何進程都會收到它 3. 本機上運行的程序也可以發送數據包,這些數據包經過OUTPUT鏈,然后到達POSTROTING鏈輸出(注意,這個時候數據包的SrcIP有可能已經被我們修改過了) 4. 如果數據包是要轉發出去的(即目的IP地址不再當前子網中),且內核允許轉發,數據包就會向右移動,經過FORWARD鏈,然后到達POSTROUTING鏈輸出(選擇對應子網的網口發送出去)

我們在寫Iptables規則的時候,要時刻牢記這張路由次序圖,根據所在Hook點的不同,靈活配置規則

 

3. Iptables規則編寫原則

我們前面說過,使用Iptables是一個非常靈活的過程,我們在寫規則的時候,一定要時刻牢記上面的這張"數據包路由圖",明白在5個Hook點,3種"表"分別所處的位置,以及結合在這個5個Hook點可以實現的功能,來理解規則。理解規則的原理比強記規則本身效果要好得多

0x1: 提出需求

在正式編寫Iptables規則之前,我們一定是有一個實現某個功能、目的的需求,我們必須先將它整理出來,為下一步抽象化作准備,這里我以我項目中的需求為例,大家在自己的實驗中可以舉一反三

1. 網口at0(10.0.0.1)是一個偽AP的網口,目標客戶端連接到偽AP網口at0之后會發起DHCPDISCOVER過程,監聽在at0上的DHCPD會進行回應,為客戶端分配10.0.0.100的IP地址,並設置客戶
端的默認網關為10.0.0.1(即at0的IP地址)、默認DNS服務器為10.0.0.1(即at0的IP地址) 2. 需要將網口at0(10.0.0.1)的入口流量牽引到真正連接外網的網卡接口eth0(192.168.159.254)上,做一個NAT服務 3. 對網口at0(10.0.0.1)的DHCP流量(目的端口67的廣播數據包)予以放行,因為我們需要在偽AP所在的服務器上假設DHCP服務器 4. 對網口at0(10.0.0.1)的DNS流量(目的端口53)予以放行,因為我們需要在偽AP所在的服務器上假設DNS服務器

0x2: 逐步抽象化我們的需求

我們根據我們的需求進行抽象化,即用規則來抽象化描述我們的目的,在編寫的過程中要注意不同的Hook點所能做的修改是不同的

//開啟Linux路由轉發開關,由於本機對數據包進行轉發
echo "1" > /proc/sys/net/ipv4/ip_forward
//將客戶端的HTTP流量進行NAT,改變數據包的SrcIP,注意,是在POSTROUTING(數據包即將發送出去之前進行修改)
iptables -t nat -A POSTROUTING -p tcp -s 10.0.0.0/24 --dport 80 -j SNAT --to-source 192.168.159.254
//將遠程WEB服務器返回來的HTTP流量進行NAT,回引回客戶端,注意,是在PREROUTING(數據包剛進入協議棧之后馬上就修改)
iptables -t nat -A PREROUTING -p tcp -d 192.168.159.254 -j DNAT --to 10.0.0.100

我們在DHCP服務器中指定客戶端的默認DNS服務器是10.0.0.1(本機),即偽DNS,但我目前還沒有在本機架設DNS,所以目前還需要將53號端口的DNS數據包NAT出去,牽引到谷歌的DNS: 8.8.8.8上去

iptables -t nat -A PREROUTING -p udp -s 10.0.0.0/24 --dport 53 -j DNAT --to 8.8.8.8
iptables -t nat -A POSTROUTING -p udp -s 10.0.0.0/24 --dport 53 -j SNAT --to-source 192.168.159.254

iptables -t nat -A PREROUTING -p udp -d 192.168.159.254 --sport 53 -j DNAT --to 10.0.0.100
iptables -t nat -A POSTROUTING -p udp -s 8.8.8.8 --sport 53 -j SNAT --to-source 10.0.0.1

 

 

 

Copyright (c) 2014 LittleHann All rights reserved

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM