相關學習資料php
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
目錄html
1. Iptables/Netfilter原理分析 2. Linux數據包路由原理 3. Iptables規則編寫原則
1. Iptables/Netfilter原理分析linux
在文章的最開頭,咱們首先要明確一個概念,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點tcp
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