首頁 > 軟體

Iptables工作原理使用詳解

2020-06-16 17:34:05

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去跳轉到自定義鏈,然後根據規則自上到下一條條執行,執行完畢後,回到原來執行的語句。

 


自定義鏈

更多iptables相關教學見以下內容

CentOS 7.0關閉預設防火牆啟用iptables防火牆  http://www.linuxidc.com/Linux/2015-05/117473.htm

iptables使用範例詳解 http://www.linuxidc.com/Linux/2014-03/99159.htm

Linux防火牆iptables詳細教學 http://www.linuxidc.com/Linux/2013-07/87045.htm

iptables的備份、恢復及防火牆指令碼的基本使用 http://www.linuxidc.com/Linux/2013-08/88535.htm

Linux下防火牆iptables用法規則詳解 http://www.linuxidc.com/Linux/2012-08/67952.htm

Linux下iptables防火牆設定 http://www.linuxidc.com/Linux/2015-10/123843.htm

本文永久更新連結地址http://www.linuxidc.com/Linux/2016-09/134945.htm


IT145.com E-mail:sddin#qq.com