歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Iptables工作原理使用詳解

Iptables工作原理使用詳解

日期:2017/2/28 13:49:18   编辑:Linux教程

Iptables防火牆簡介

Netfilter/Iptables(以下簡稱Iptables)是unix/linux自帶的一款優秀且開放源代碼的完全自由的基於包過濾的防火牆工具,它的功能十分強大,使用非常靈活,可以對流入和流出服務器的數據包進行很精細的控制。特別是它可以在一台非常低的硬件配置下跑得非常好。IPtables是linux2.4及2.6內核中集成的服務。其功能與安全性比其老一輩ipfwadm,ipchains強大的多,Iptables主要工作在OSI七層的二、三、四層。

Iptables名詞和術語

容器

用來形容包含或者說屬於的關系

Netfilter/iptables是表的容器,iptables包含的各個表
表(table)

iptables的表又是鏈的容器

鏈(chains)

INPUT,OUTPUT,FORWARD,PREROUTING,POSTROUTING

鏈是規則的容器

規則(Policy)

一條條過濾的語句 Policy

filter表

主要和主機自身有關,真正負責主機防火牆功能的(過濾流入流出主機的數據包)。filter表是iptables默認使用的表。這個表定義了三個鏈(Chains);

  • INPUT: 負責過濾所有目標地址是主機地址的數據包。通俗的講,就是過濾進入主機的數據包。

  • FORWARD:負責轉發流經主機的數據包。起轉發的作用,和Nat關系很大。LVS NAT模式。net.ipv4_forward = 1

  • OUTPUT:處理所有源地址是本機地址的數據包,通俗的講,就是處理從主機發出去的數據包。

nat表

負責網絡地址轉換,即來源與目的ip地址和port的轉換。
應用:和主機本身無關。一般用於局域網共享上網或者特殊的端口轉換服務相關。

這個表定義了三個鏈(Chainc),nat功能就相當於網絡的acl控制。和網絡交換機acl類似。

  • OUTPUT:和主機發出去的數據包有關。改變主機發出數據包的目標地址。

  • PREROUTING:在數據包到達防火牆時進行路由判斷之前執行的規則,作用是改變數據包的目的地址、目的端口等。

  • POSTROUTING:在數據包離開防火牆時進行路由判斷之後執行的規則,作用改變數據包的源地址、源端口等,例如:我們現在的筆記本和虛擬機都是192.168.30.0/24,就是出網的時候被我們企業路由器把源地址改成了公網地址了。生產應用:局域網共享上網。

Iptables工作流程


iptables工作流程


排除mangle表


數據包流向

規則從上往下匹配,只要匹配到就不往下匹配,如果沒有匹配上就走默認規則。

  1. 防火牆是層層過濾的。實際上是按照配置規則的順序從上到下,從前到後進行過濾的。

  2. 如果匹配上規則,則明確表明是阻止還是通過,數據包就不再匹配任何新規則了。

  3. 如果所有規則中沒有明確表明是阻止還是通過,也就是沒有匹配規則,向下進行匹配,直到匹配默認規則得到明確的阻止還是通過。

  4. 防火牆默認規則是對應鏈的所有的規則執行完才會執行的。

基本語法

Filter

Iptables啟動方式
/etc/init.d/iptables restart
先來看幾個常用對鏈的操作,常用的就那麼幾種
-I(插入) -A(追加) -R(替換) -D(刪除) -L(列表顯示)
這裡要說明的就是-I將會把規則放在第一行,-A將會放在最後一行。
舉例:

iptables –t filter  -A INPUT  -p  tcp  --dport  22  -j DROP

iptables –t filter  -A INPUT  -p  tcp  --dport  3306  -j DROP

iptables –t filter  -I  INPUT  -p  tcp  --dport  80  -j DROP

iptables -t filter -A INPUT -i eth0 !-s 192.168.30.150 -j DROP

查看防火牆規則:
iptables -L -n
清除防火牆
--flush -F [chain] Delete all rules in chain or all chains
清除用戶自定義的鏈
-X [chain] Delete a user-defined chain
創建一個新的自定義鏈
--new -N chain Create a new user-defined chain
把鏈中的計數器清零
--zero -Z [chain [rulenum]] Zero counters in chain or all chains
總結:
iptables –F / /清除所有規則,不會處理默認的規則
iptables –X / /刪除用戶自定義的鏈
iptables –Z / /鏈的計數器清零

iptables [-t filter] [-AI INPUT,OUTPUT,FORWARD] [-io interface] [-p tcp,udp.icmp,all] [-s ip/nerwork] [--sport ports] [-d ip/netword] [--dport ports] [-j ACCEPT DROP]
以上是iptables的基本語法
-A 是添加的意思
-I 是插入的意思
-i -o 指的是數據要進入或出去所要經過的網卡 如eth1 eth0等
-p 你所要指定的協議,如tcp、udp、icmp、all
-s 指源地址 可是單個IP如192.168.2.6 也可以是一個網絡 192.168.2.0/24 還可以 是一個域名 如163.com 如果你填寫的是域名,系統會自動解析出他的IP並在iptables裡 顯示
--sport 來源端口
-d 同-s相似 只不過他指的是目標地址 也可以是IP 域名 和網絡
--dport 目標端口
-j 執行參數 ACCEPT DROP

參數說明

禁止10.0.0.0網段連入:
iptables -t filter -A INPUT -i eth0 -s 10.0.0.0/24 -j DROP iptables -A INPUT -i eth0 -s 10.0.0.0/24 -j DROP
-i:流量進入的接口,從eth0進入
-s:源地址
從eth0進入的流量,源地址是10.0.0.0網段的地址,拒絕連接。

源地址不是192.168.30.150的單個IP的禁止連接:
iptables -t filter -A INPUT -i eth0 !-s 192.168.30.150 -j DROP
禁用icmp協議:
iptables -t filter -A INPUT -p icmp --icmp-type 8 -i eth0 -s 192.168.30.0/24 -j DROP
封掉3306端口:
iptables –t filter -A INPUT -p tcp --dport 3306 -j DROP
匹配指定協議以外的所有協議:
iptables -A INPUT -p ! tcp iptables -A INPUT ! –p tcp –s 10.0.0.0/24 -j DROP
匹配主機源IP
iptables -A INPUT -s 10.0.0.14 iptable -A INPUT -s ! 10.0.0.13
匹配網段
iptables -A INPUT -s 10.0.0.0/24 iptables -A INPUT -s ! 10.0.0.0/24
禁用dns:
iptables -A INPUT -p tcp --sport 53 iptables -A INPUT -p udp --dport 53
匹配指定端口之外的端口:
iptables -A INPUT -p tcp --dport ! 22 iptables -I INPUT -p tcp ! --dport 22 -s 10.0.0.123 -j DROP
匹配端口范圍
iptables -A INPUT -p tcp --sport 22:80 iptables -I INPUT -p tcp -m multiport --dport 21,22,23,24 -j ACEEPT iptables -I INPUT -p tcp –dport 3306:8809 -j ACCEPT
匹配icmp類型:
iptables –A INPUT -p icmp --icmp-type 8 -j DROP iptables -A FORWARD -s 192.168.30.0/24 -p icmp -m icmp --icmp-type any -j ACCEPT
匹配指定的網絡接口:
iptables -A INPUT -i eth0 iptables -A FORWARD -o eth0
匹配網絡狀態
-m state --state
NEW:已經或將啟動新的連接
ESTABLISHED:已建立的連接
RELATED:正在啟動新鏈接
INVALID:非法或無法識別的
允許關聯的狀態包通過
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state -state ESTABLISHED,RELATED -j ACCEPT

-m limit --limit n/{second/minute/hour}:指定時間內的請求速率"n"為速率,後面為時間分別為:秒、分、時
--limit-burst [n]:在同一時間內允許通過的請求"n"為數字,不指定默認為5
fg:本機地址:172.16.14.1,允許172.16.0.0/16網絡ping本機,但限制每分鐘請求不能超過20,每次並發不能超過6個
iptables -A INPUT -s 172.16.0.0/16 -d 172.16.14.1 -p icmp --icmp-type 8 -m limit --limit 20/min --limit-burst 6 -j ACCEPT
iptables -A OUTPUT -s 172.16.14.1 -d 172.16.0.0/16 -p icmp --icmp-type 0 -j ACCEPT

指定TCP匹配擴展
使用 –tcp-flags 選項可以根據tcp包的標志位進行過濾。
#iptables -A INPUT -p tcp –tcp-flags SYN,FIN,ACK SYN #iptables -A FROWARD -p tcp –tcp-flags ALL SYN,ACK
上實例中第一個表示SYN、ACK、FIN的標志都檢查,但是只有SYN匹配。第二個表示ALL(SYN,ACK,FIN,RST,URG,PSH)的標志都檢查,但是只有設置了SYN和ACK的匹配。
#iptables -A FORWARD -p tcp --syn
選項—syn相當於”--tcp-flags SYN,RST,ACK SYN”的簡寫。

NAT表:

NAT我們一般用來做企業共享上網或外網端口映射。我們現在的筆記本和虛擬機都是192.168.30.0/24,就是出網的時候被我們企業路由器把源地址改成了公網地址了。
那麼Linux如何做共享上網的呢?比如一個內網的10.1.1.11的pc訪問www.baidu.com的一個web服務器,linux的內網接口10.1.1.1在收到這個包之後把原來的PC的 ip10.1.1.11改變為60.1.1.1(我們公司的出網ip)的合法地址然後送出,同時在自己的ip_conntrack表裡面做一個記錄,記住是內網的哪一個ip的哪個端口訪問的這個web服務器,自己把它的源地址改成多少了,端口改成多少了,以便這個web服務器返回數據包的時候linux將它准確的送回給發送請求的這個pc
設置共享上網有兩種方式:.
方法1:適合有固定上網地址的:
iptables -t nat -A POSATROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-sorce 10.0.0.19
(1)-s 192.168.1.0/24 辦公網或IDC內網網段
(2) -o eth0 為網關的外網卡接口
(3) –j SNAT --to-sorce 10.0.0.19 是網關外網卡IP地址
方法2:適合變化外網地址(ADSL)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUEREDE(偽裝)
注:MASQUEREDE動態偽裝成出網ip。
外部IP映射到內部服務器IP(包括端口):
iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.8:9000

Icmp協議

在iptables看來,只有四種ICMP分組,這些分組類型可以被歸為NEW、ESTABLISHED兩類:
ECHO請求(ping,8)和ECHO應答(pong,0)。
時間戳請求(13)和應答(14)。
信息請求(15)和應答(16)。
地址掩碼請求(17)和應答(18)。
這些ICMP分組類型中,請求分組屬於NEW,應答分組屬於ESTABLISHED。而其它類型的ICMP分組不基於請求/應答方式,一律被歸入RELATED。
我們先看一個簡單的例子:
``iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED, RELATED -j ACCEPT
iptables -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT ```
這鏈條規則進行如下的過濾:
一個ICMP echo請求是一個NEW連接。因此,允許ICMP echo請求通過OUTPUT鏈。
當對應的應答返回,此時連接的狀態是ESTABLISED,因此允許通過INPUT鏈。而INPUT鏈沒有NEW狀態,因此不允許echo請求通過INPUT鏈。也就是說,這兩條規則允許內部主機ping外部主機,而不允許外部主機ping內部主機。
一個重定向ICMP(5)分組不是基於請求/應答方式的,因此屬於RELATED。INPUT和OUTPUT鏈都允許RELATED狀態的連接,因此重定向(5)分組可以通過INPUT和OUTPUT鏈。

TCP FLAG 標記

基於標記的TCP包匹配經常被用於過濾試圖打開新連接的TCP數據包。
TCP標記和他們的意義如下所列

  • F : FIN - 結束; 結束會話

  • S : SYN - 同步; 表示開始會話請求

  • R : RST - 復位;中斷一個連接

  • P : PUSH - 推送; 數據包立即發送

  • A : ACK - 應答

  • U : URG - 緊急

  • E : ECE - 顯式擁塞提醒回應

  • W : CWR - 擁塞窗口減少
    示例
    三次握手Three-way Handshake
    一個虛擬連接的建立是通過三次握手來實現的

  1. (B) --> [SYN] --> (A)
    假如有服務器A、客戶機B. 當B要和A通信時,B首先向A發一個SYN (Synchronize) 標記的包,告訴A請求建立連接.
    注意: 一個 SYN包就是僅SYN標記設為1的TCP包(參見TCP包頭Resources). 只有當A收到B發來的SYN包,才可建立連接,除此之外別無他法。

  2. (B) <-- [SYN/ACK] <--(A)
    接著,A收到後會發一個對SYN包的確認包(SYN/ACK)回去,表示對第一個SYN包的確認,並繼續握手操作.
    注意: SYN/ACK包是僅SYN 和 ACK 標記為1的包.

  3. (B) --> [ACK] --> (A)
    B收到SYN/ACK 包,B發一個確認包(ACK),通知A連接已建立。至此,三次握手完成,一個TCP連接完成。
    注意: ACK包就是僅ACK 標記設為1的TCP包.
    特別注意:需要注意的是當三此握手完成、連接建立以後,TCP連接的每個包都會設置ACK位

    PS:這就是為何連接跟蹤很重要的原因了. 沒有連接跟蹤,防火牆將無法判斷收到的ACK包是否屬於一個已經建立的連接.一般的包過濾(Ipchains)收到ACK包時,會讓它通過(這絕對不是個好主意). 而當狀態型防火牆收到此種包時,它會先在連接表中查找是否屬於哪個已建連接,否則丟棄該包

四次握手Four-way Handshake
四次握手用來關閉已建立的TCP連接

  1. (B) --> ACK/FIN --> (A)

  2. (B) <-- ACK <-- (A)

  3. (B) <-- ACK/FIN <-- (A)

  4. (B) --> ACK --> (A)

注意: 由於TCP連接是雙向連接, 因此關閉連接需要在兩個方向上做。ACK/FIN 包(ACK 和FIN 標記設為1)通常被認為是FIN(終結)包.然而, 由於連接還沒有關閉, FIN包總是打上ACK標記. 沒有ACK標記而僅有FIN標記的包不是合法的包,並且通常被認為是惡意的
連接復位Resetting a connection
四次握手不是關閉TCP連接的唯一方法. 有時,如果主機需要盡快關閉連接(或連接超時,端口或主機不可達),RST (Reset)包將被發送. 注意在,由於RST包不是TCP連接中的必須部分, 可以只發送RST包(即不帶ACK標記). 但在正常的TCP連接中RST包可以帶ACK確認標記。

注意: RST包是可以不要收到方確認的

無效的TCP標記Invalid TCP Flags
到目前為止,你已經看到了 SYN, ACK, FIN, 和RST 標記. 另外,還有PSH (Push) 和URG (Urgent)標記.
最常見的非法組合是SYN/FIN 包. 注意:由於 SYN包是用來初始化連接的, 它不可能和 FIN和RST標記一起出現. 這也是一個惡意攻擊.
由於現在大多數防火牆已知 SYN/FIN 包, 別的一些組合,例如SYN/FIN/PSH, SYN/FIN/RST, SYN/FIN/RST/PSH。很明顯,當網絡中出現這種包時,很你的網絡肯定受到攻擊了。
別的已知的非法包有FIN (無ACK標記)和"NULL"包。如同早先討論的,由於ACK/FIN包的出現是為了關閉一個TCP連接,那麼正常的FIN包總是帶有 ACK 標記。"NULL"包就是沒有任何TCP標記的包(URG,ACK,PSH,RST,SYN,FIN都為0)。
到目前為止,正常的網絡活動下,TCP協議棧不可能產生帶有上面提到的任何一種標記組合的TCP包。當你發現這些不正常的包時,肯定有人對你的網絡不懷好意。

什麼是狀態檢測

每個網絡連接包括以下信息:源地址、目的地址、源端口和目的端口,叫作套接字對(socket pairs);協議類型、連接狀態(TCP協議)和超時時間等。防火牆把這些信息叫作狀態(stateful),能夠檢測每個連接狀態的防火牆叫作狀態包過濾防火牆。它除了能夠完成簡單包過濾防火牆的包過濾工作外,還在自己的內存中維護一個跟蹤連接狀態的表,比簡單包過濾防火牆具有更大的安全性。
iptables中的狀態檢測功能是由state選項來實現的。
--state state
這裡,state是一個用逗號分割的列表,表示要匹配的連接狀態。有效的狀態選項包括:INVAILD,表示分組對應的連接是未知的;
ESTABLISHED,表示分組對應的連接已經進行了雙向的分組傳輸,也就是說連接已經建立;NEW,表示這個分組需要發起一個連接,或者說,分組對應的連接在兩個方向上都沒有進行過分組傳輸
RELATED,表示分組要發起一個新的連接,但是這個連接和一個現有的連接有關,例如:FTP的數據傳輸連接和控制連接之間就是RELATED關系。

iptables的狀態檢測是如何工作的

如果要在兩個網絡接口之間轉發一個分組,這個分組將以以下的順序接收規則鏈的檢查:
iptables的狀態檢測機制將重組分組,並且以以下某種方式跟蹤其狀態:
分組是否匹配狀態表中的一個已經實現(ESTABLISHED)的連接。
這個分組是否要發起一個新(NEW)的連接。
如果分組和任何連接無關,就被認為是無效(INVALID)的。

iptables 自定義鏈實例

1、案例場景:將已建立連接和與一個現有連接有效的包放行。
2、配置步驟:
(1)創建自定義鏈block並添加規則:
#iptables -N block
#iptables -A block -m –state ESTABLISHED,RELATED -j ACCEPT
(2)將流經INPUT鏈的數據包跳轉到block鏈處理數據包:
#iptables -A INPUT -j block
通過-j去跳轉到自定義鏈,然後根據規則自上到下一條條執行,執行完畢後,回到原來執行的語句。


自定義鏈
Copyright © Linux教程網 All Rights Reserved