1. 程式人生 > >iptables用法詳解

iptables用法詳解

iptables DNAT SNAT netfilter

iptables 詳解(基於馬哥講的iptables)
看到網上很多人寫的iptables詳解有很多錯誤,還有很多不完整的地方。於是決定自己寫一份。供大家參考。
一, 準備工作
本文章用到vmware workstation中2臺虛擬機。和一臺物理主機
2臺虛擬主機為名字:
server: ipaddr:172.16.100.1/16 gateway:172.16.100.254 網卡連接類型為host only(僅主機模式)
firewall:ipaddr:192.168.0.110/24 gateway:192.168.0.1 網卡連接類型為:橋接模式 (可以連接到互聯網)
ipaddr:172.16.100.254/16 網卡連接類型為host only(僅主機模式)
一臺物理主機window10 (從無線路由中有線接入)ipaddr:192.168.0.111/24 gateway 192.168.0.1 可以連接到互聯網(模擬外網地址)
二, 前言
1,什麽是防火墻: 防火墻,其實說白了講,就是用於實現Linux下訪問控制的功能的,它分為硬件的或者軟件的防火墻兩種。無論是在哪個網絡中,防火墻工作的地方一定是在某個網絡的邊緣。而我們的任務就是需要去定義到底防火墻如何工作,這就是防火墻的策略,規則,以達到讓它對出入網絡的IP、數據進行檢測。

目前市面上比較常見的有3、4層的防火墻,叫網絡層的防火墻,還有7層的防火墻,其實是代理層的網關。
對於TCP/IP的七層模型來講,我們知道第三層是網絡層,三層的防火墻會在這層對源地址和目標地址進行檢測。但是對於七層的防火墻,不管你源端口或者目標端口,源地址或者目標地址是什麽,都將對你所有的東西進行檢查。所以,對於設計原理來講,七層防火墻更加安全,但是這卻帶來了效率更低。所以市面上通常的防火墻方案,都是兩者結合的。而又由於我們都需要從防火墻所控制的這個口來訪問,所以防火墻的工作效率就成了用戶能夠訪問數據多少的一個最重要的控制,配置的不好甚至有可能成為流量的瓶頸。 

三:iptables 的歷史以及工作原理

1.iptables的發展:

iptables的前身叫ipfirewall (內核1.x時代),這是一個作者從freeBSD上移植過來的,能夠工作在內核當中的,對數據包進行檢測的一款簡易訪問控制工具。但是ipfirewall工作功能極其有限(它需要將所有的規則都放進內核當中,這樣規則才能夠運行起來,而放進內核,這個做法一般是極其困難的)。當內核發展到2.x系列的時候,軟件更名為ipchains,它可以定義多條規則,將他們串起來,共同發揮作用,而現在,它叫做iptables,可以將規則組成一個列表,實現絕對詳細的訪問控制功能。

他們都是工作在用戶空間中,定義規則的工具,本身並不算是防火墻。它們定義的規則,可以讓在內核空間當中的netfilter來讀取,並且實現讓防火墻工作。而放入內核的地方必須要是特定的位置,必須是tcp/ip的協議棧經過的地方。而這個tcp/ip協議棧必須經過的地方,可以實現讀取規則的地方就叫做 netfilter.(網絡過濾器)

作者一共在內核空間中選擇了5個位置,
1.內核空間中:從一個網絡接口進來,到另一個網絡接口去的
2.數據包從內核流入用戶空間的
3.數據包從用戶空間流入內核空間的
4.進入/離開本機的外網接口
5.進入/離開本機的內網接口

2.iptables的工作機制

從上面的發展我們知道了作者選擇了5個位置,來作為控制的地方,但是你有沒有發現,其實前三個位置已經基本上能將路徑徹底封鎖了,但是為什麽已經在進出的口設置了關卡之後還要在內部卡呢? 由於數據包尚未進行路由決策,還不知道數據要走向哪裏,所以在進出口是沒辦法實現數據過濾的。所以要在內核空間裏設置轉發的關卡,進入用戶空間的關卡,從用戶空間出去的關卡。那麽,既然他們沒什麽用,那我們為什麽還要放置他們呢?因為我們在做NAT和DNAT的時候,目標地址轉換必須在路由之前轉換。所以我們必須在外網而後內網的接口處進行設置關卡。        

這五個位置也被稱為五個鉤子函數(hook functions),也叫五個規則鏈。
    1.PREROUTING (路由前)
    2.INPUT (數據包流入口)
    3.FORWARD (轉發關卡)
    4.OUTPUT(數據包流出口)
    5.POSTROUTING(路由後)
    這是NetFilter規定的五個規則鏈,任何一個數據包,只要經過本機,必將經過這五個鏈中的其中一個鏈。       

3.防火墻的策略

防火墻策略一般分為兩種,一種叫“通”策略,一種叫“堵”策略,通策略,默認門是關著的,必須要定義誰能進。堵策略則是,大門是洞開的,但是你必須有身份認證,否則不能進。所以我們要定義,讓進來的進來,讓出去的出去,所以通,是要全通,而堵,則是要選擇。當我們定義的策略的時候,要分別定義多條功能,其中:定義數據包中允許或者不允許的策略,filter過濾的功能,而定義地址轉換的功能的則是nat選項。為了讓這些功能交替工作,我們制定出了“表”這個定義,來定義、區分各種不同的工作功能和處理方式。

我們現在用的比較多個功能有3個:還有一個不常用raw(本文不介紹)
    1.filter 定義允許或者不允許的
    2.nat 定義地址轉換的 
    3.mangle功能:修改報文原數據
    4.raw功能:把修改的報文還原回去
我們修改報文原數據就是來修改TTL的。能夠實現將數據包的元數據拆開,在裏面做標記/修改內容的。而防火墻標記,其實就是靠mangle來實現的。

小擴展:
對於filter來講一般只能做在3條鏈上:INPUT ,FORWARD ,OUTPUT
對於nat來講一般也只能做在3條鏈上:PREROUTING ,OUTPUT ,POSTROUTING
而mangle則是5條鏈都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
raw來講只能2條鏈上做:PREROUTING,OUTPUT
註意:規則的次序非常關鍵,誰的規則越嚴格,應該放的越靠前,而檢查規則的時候,是按照從上往下的方式進行檢查的。

iptables/netfilter(這款軟件)是工作在用戶空間的,它可以讓規則進行生效的,本身不是一種服務,而且規則是立即生效的。而我們iptables現在被做成了一個服務,可以進行啟動,停止的。啟動,則將規則直接生效,停止,則將規則撤銷。 
iptables還支持自己定義鏈。但是自己定義的鏈,必須是跟某種特定的鏈關聯起來的。在一個關卡設定,指定當有數據的時候專門去找某個特定的鏈來處理,當那個鏈處理完之後,再返回。接著在特定的鏈中繼續檢查。  
                                                                                                  --以上理論來自:http://blog.chinaunix.net/uid-26495963-id-3279216.html

四:iptables 規則的寫法
1, iptables 規則定義比較復雜(這裏介紹簡單通用的寫法)
iptables [-t TABLE] COMMAND CHAIN [num] 匹配標準 -j 處理辦法

         [-t TABLE] :4個分別是filter,nat,mangle,raw 可以省略,默認為filter表
         COMMAND :定義對規則進行管理。
         CHAIN :5條鏈分別是PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
         [num]:指定對第幾條規則進行處理。
         匹配標準:下面有詳細介紹
         -j 處理方法:對匹配到,指定如何進行處理。

匹配標準:
通用匹配
-s, --src: 指定源地址,可以是一個ip 如:192.168.0.111,也可以是一個網絡 如:192.168.0.0/24
-d, --dst:指定目標地址
-p {tcp|udp|icmp}:指定協議
-i INTERFACE: 指定數據報文流入的接口
可用於定義標準的鏈:PREROUTING,INPUT,FORWARD
-o INTERFACE: 指定數據報文流出的接口
可用於標準定義的鏈:OUTPUT,POSTROUTING,FORWARD
練習1:放行192.168.0.0/24的網絡對192.168.0.110(firewall主機ip)SSH的訪問
iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 22 -j ACCEPT

    練習2:修改firewall iptables 中filter 表中INPUT,和OUTPUT鏈的默認規則為DROP
          iptables -P INPUT DROP
          iptables -P OUTPUT DROP 

    練習3:放行firewall 允許自己和自己通信。
          iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
          iptables -A OUTPUT -s 127.0.0.1 -d  127.0.0.1 -o lo -j ACCEPT

          以上的可以簡寫為
          iptables -A INPUT -i lo -j ACCEPT
          iptables -A OUTPUT  -o lo -j ACCEPT

擴展匹配
隱含擴展:不用特別指明由哪個模塊進行的擴展,因為此時使用-p {tcp|udp|icmp}
-p tcp
--sport PORT[-PORT]: 源端口 可以使用連續的端口 如:--sport 21-23
--dport PORT[-PORT]: 目標端口
--tcp-flags mask comp: 只檢查mask指定的標誌位,是逗號分隔的標誌位列表;comp:此列表中出現的標記位必須為1,comp中沒出現,而mask中出現的,必須為0;
--tcp-flags SYN,FIN,ACK,RST SYN = --syn
--syn 三次握手的第一次
練習4:允許192.168.0.0/24網絡對firewall(192.168.0.110)的80端口進行訪問
iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 80 -j ACCEPT

    練習5:拒絕來自所有主機對firewall(192.168.0.110)非法報文請求(syn=1 ack=1 fin=1)
            iptables -A INPUT -d 192.168.0.110 -p tcp --tcp-flags SYN,ACK,FIN,RST    SYN,ACK,FIN -j DROP

        -p icmp
            --icmp-type 
                 echo-reply 應答回顯 用數字0表示
                echo-request 請求回顯 用數字8表示
    練習6:允許firewall(192.168.0.110)ping 別人的主機,不允許別人ping firewall主機。
          iptables -A INPUT -d 192.168.0.110 -p icmp --icmp-type 0 -j ACCEPT
          iptables -A OUTPUT -s 192.168.0.110 -p icmp --icmp-type 8 -j ACCEPT

        -p udp
            --sport PORT[-PORT]: 源端口 可以使用連續的端口 如:--sport 21-23
            --dport PORT[-PORT]: 目標端口

    顯式擴展:必須指明由哪個模塊進行的擴展,在iptables中使用-m選項可完成此功能
        -m EXTENDSION_NAME --specific-opt
           EXTENDSION_NAME:擴展模塊名  
           --specific-opt: 擴展模塊名對應的選項
        -m state --state
            state擴展是ip_conntrack模塊實現連接追蹤的,它可以對udp, tcp, icmp的狀態追蹤
            NEW:新請求
            ESTABLISHED:已建立的連接
            RELATED:有關聯的連接
            INVALID:無效的請求如:syn=1,fin=1,ack=1 這樣的非法報文

    練習7:允許外面主機訪問firewall 的ftp服務。
            ftp是一個比較比較特殊的服務:分為:控制連接和數據連接兩個階段。控制連接工作的端口號為21 數據連接分為主動模式和被動模式(工作原理自行查找)
            要想iptables對它進行控制需要加載ip_nat_ftp,和ip_contrack_ftp .修改/etc/sysconfig/iptables-config 配置腳本。修改IPTABLES_MODULES="ip_conntrack_ftp ip_nat_ftp"。重啟iptables(上面最的規則要先用service iptables save 命令保存,要不重啟iptables寫的規則就沒有了)
            iptables -A INPUT -d 192.168.0.110 -p tcp --dport 21 -m state --state NEW -j ACCEPT
            iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
            iptables -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT

        -m multiport : 用離散端口
            --source-ports 指定源端口,如:--source-ports 22,53,80
            --destination-ports 指定目標端口 如:--destination-ports 22,53,80
            --ports 通用匹配,不論是源端口,還是目標端口
    練習8:允許外部主機訪問firewall(192.168.0.110)的httpd ,ftpd,SSH 服務
            iptables -A INPUT -d 192.168.0.110 -p tcp -m multiport --destination-ports 21,22,80 -m state --state NEW -j ACCEPT
            iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT (上面如果用過了,就不用寫了)
            iptables -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT (上面如果用過了,就不用寫了)

            這是我們可以刪除:iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport  22 -j ACCEPT
                              iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 22 -j ACCEPT
                              iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 80 -j ACCEPT
                              iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 80 -j ACCEPT

        -m iprange
            --src-range 源地址範圍:如 --src-range 172.168.100.3-172.16.100.100
            --dst-range 目標地址範圍:如 --dst-range 172.168.100.3-172.16.100.100

            iptables -A INPUT -p tcp -m iprange --src-range 172.16.100.3-172.16.100.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

        -m connlimit: 連接數限制
            --connlimit-above n 鏈接上限n表示個數

                iptables -A INPUT -d 192.168.0.110 -p tcp --dport 80 -m connlimit --connlimit-above 2 -j ACCEPT

        -m limit
            --limit RATE 連接速率  如:3/minute 
            --limit-burst n 一次最大並發數 n 表示個數

        -m string 字符串匹配
            --algo {bm|kmp} 指定算法
            --string "STRING" 要匹配的字符

以上條件都可以去反:條件取反:!,-s ! 192.168.0.110

五,命令:
管理規則
-A:附加一條規則,添加在鏈的尾部
-I CHAIN [num]: 插入一條規則,插入為對應CHAIN上的第num條;
-D CHAIN [num]: 刪除指定鏈中的第num條規則;
-R CHAIN [num]: 替換指定的規則;

      練習9:(-I用法)向INPUT鏈中插入為第二條規則
               iptables -I INPUT 2 -d 192.168.0.100 -p tcp --dport 53 -j ACCEPT

               (-R用法)修改INPUT鏈中的第二條規則
               iptables -R INPUT 2 -d 192.168.0.100 -p udp --dport53 -j ACCEPT

               (-D用法)刪除INPUT鏈中的第二條規則
               iptables -D INPUT 2
管理鏈:
    -F [CHAIN]:flush,清空指定規則鏈,如果省略CHAIN,則可以實現刪除對應表中的所有鏈
      例如   iptables -t nat -F PREROUTING
             iptables -t nat -F 清空nat表的所有鏈
    -P CHAIN: 設定指定鏈的默認策略;(ACCEPT | DROP)
      例如:iptables -P INPUT DROP 設定INPUT默認策略為DROP

    -N:自定義一個新的空鏈
      例如: iptables -N NEW_CHAIN 創建新空鏈

    -X: 刪除一個自定義的空鏈
      例如: iptables -X NEW_CHAIN 刪除空鏈(註意只能刪除自己定義的空鏈,iptables默認的5條鏈無法刪除)
    -Z:置零指定鏈中所有規則的計數器;

    -E: 重命名自定義的鏈;
          iptables -E oldname newname
查看類:
    -L: 顯示指定表中的規則;
        -n: 以數字格式顯示主機地址和端口號;
        -v: 顯示鏈及規則的詳細信息
        -vv: 
        -x: 顯示計數器的精確值
        --line-numbers: 顯示規則號碼

    查看規則:iptables [-t TABLE] -n -L 
              iptables [-t TABLE] -n -L -v 顯示詳細信息
              iptables [-t TABLE] -n -L -line-numbers 顯示行號的查看
              iptables [-t TABLE] -n -L -x  顯示計數器的精確值

六,動作(target):
ACCEPT:放行
DROP:丟棄
REJECT:拒絕
DNAT:目標地址轉換
SNAT:源地址轉換
REDIRECT:端口重定向
MASQUERADE:地址偽裝 (做源地址轉換時,目標地址為動態獲取時)
LOG:日誌
MARK:打標記

七,SNAT和DNAT的實現
1,SNAT基於原地址的轉換
基於源地址的轉換一般用在我們的許多內網用戶通過一個外網的口上網的時候,這時我們將我們內網的地址轉換為一個外網的IP,我們就可以實現連接其他外網IP的功能
源地址轉換需要做在POSTROUTING鏈上。
例如;現在我們需要server(172.16.100.1)這臺主機能夠訪問192.168.0.111,還能通過192.168.0.110這個接口訪問互聯網。
具體實現,請看準備工作的firewall和server兩臺主機的配置。
在firewall 這臺主機上開啟ip_forward的功能。編輯/etc/sysctl.conf 文件找到net.ipv4.ip_forward = 0 把0改為1.重讀配置文件:sysctl -p 命令 這樣就能永久有效了。臨時開啟的方法:echo "1" >/proc/sys/net/ipv4/ip_forward

        在firewall主機中:iptables -t nat -A POSTROUTING -s 172.16.100.0/16 -j SNAT --to-source 192.168.0.110 

            那麽,如果192.168.0.110不是固定的怎麽辦?
我們都知道當我們使用聯通或者電信上網的時候,一般它都會在每次你開機的時候隨機生成一個外網的IP,意思就是外網地址是動態變換的。這時我們就要將外網地址換成 MASQUERADE(動態偽裝):它可以實現自動尋找到外網地址,而自動將其改為正確的外網地址。所以,我們就需要這樣設置:
     iptables -t nat -A POSTROUTING -s 172.16.100.0/16 -j MASQUERADE
     這裏要註意:地址偽裝並不適用於所有的地方。

2.DNAT目標地址轉換
對於目標地址轉換,數據流向是從外向內的,外面的是客戶端,裏面的是服務器端通過目標地址轉換,我們可以讓外面的ip通過我們對外的外網ip來訪問我們服務器不同的服務器,而我們的服務卻放在內網服務器的不同的服務器上。
  目標地址轉換時需要做在PREROUTING鏈上
 例如:現在我們需要物理主機window10 (19.168.0.111)想訪問server(172.16.100.1)上的httpd 服務。

    在firewall主機中:iptables -t nat -A PREROUTING -d 192.168.0.110 -p tcp --dprot 80 -j DNAT --to-destination 172.16.100.1
    註意:訪問httpd服務需要的是firewall(192.168.0.110)的地址。

    DNAT 還可以做端口映射。如果httpd監聽的不是在80端口而是在8080端口上,我們可以
    iptables -t nat -A PREROUTING -d 192.168.0.110 -p tcp --dport 80 -j DNAT --to-destination 172.16.100.1:8080

八,控制規則的存放以及開啟

註意:你所定義的所有內容,當你重啟的時候都會失效,要想我們能夠生效,需要使用一個命令將它保存起來
1.service iptables save 命令
    它會保存在/etc/sysconfig/iptables這個文件中
2.iptables-save 命令
    iptables-save > /etc/sysconfig/iptables

3.iptables-restore 命令
        開機的時候,它會自動加載/etc/sysconfig/iptabels
        如果開機不能加載或者沒有加載,而你想讓一個自己寫的配置文件(假設為iptables.2)手動生效的話:
        iptables-restore < /etc/sysconfig/iptables.2
        則完成了將iptables中定義的規則手動生效

九:iptables 的總結
iptables 理論知識很重要,市場上的硬件防火墻就是變型的iptables規則,只是配置方法和寫法不同。理論都是相通的。學好iptables/netfilter 對學習網絡中的防火墻,有很大幫助。

iptables用法詳解