天天看點

linux下 iptables 的配置

什麼是Iptables?

      iptables 是建立在 netfilter 架構基礎上的一個包過濾管理工具,最主要的作用是用來做防火牆或透明代理。Iptables 從 ipchains 發展而來,它的功能更為強大。Iptables 提供以下三種功能:包過濾、NAT(網絡位址轉換)和通用的 pre-route packet mangling。包過濾:用來過濾包,但是不修改包的内容。Iptables 在包過濾方面相對于 ipchians 的主要優點是速度更快,使用更友善。NAT:NAT 可以分為源位址 NAT 和目的位址 NAT。

  Iptables 可以追加、插入或删除包過濾規則。實際上真正執行這些過慮規則的是 netfilter 及其相關子產品(如 iptables 子產品和 nat 子產品)。Netfilter 是 Linux 核心中一個通用架構,它提供了一系列的 “表”(tables),每個表由若幹 “鍊”(chains)組成,而每條鍊中可以有一條或數條 “規則”(rule)組成。

  系統預設的表為 “filter”,該表中包含了 INPUT、FORWARD 和 OUTPUT 3 個鍊。

  每一條鍊中可以有一條或數條規則,每一條規則都是這樣定義的:如果資料標頭符合這樣的條件,就這樣處理這個資料包。當一個資料包到達一個鍊時,系統就會從第一條規則開始檢查,看是否符合該規則所定義的條件: 如果滿足,系統将根據該條規則所定義的方法處理該資料包;如果不滿足則繼續檢查下一條規則。最後,如果該資料包不符合該鍊中任一條規則的話,系統就會根據該鍊預先定義的政策來處理該資料包。

? table,chain,rule

  iptables 可以操縱3 個表:filter 表,nat 表,mangle 表。

  NAT 和一般的 mangle 用 -t 參數指定要操作哪個表。filter 是預設的表,如果沒有 -t 參數,就預設對 filter 表操作。

  Rule 規則:過濾規則,端口轉發規則等,例如:禁止任何機器 ping 我們的伺服器,可以在伺服器上設定一條規則:

 iptables -A INPUT -s ! 127.0.0.1 -p icmp -j DROP

  從 –s 開始即是一條規則,-j 前面是規則的條件,-j 開始是規則的行為(目的)。整條指令解釋為,在filter 表中的 INPUT 規則鍊中插入一條規則,所有源位址不為 127.0.0.1 的 icmp 包都被抛棄。

  Chain 規則鍊:由一系列規則組成,每個包順序經過 chain 中的每一條規則。chain 又分為系統 chain和使用者建立的 chain。下面先叙述系統 chain。

  filter 表的系統 chain: INPUT,FORWAD,OUTPUT

  nat 表的系統 chain: PREROUTING,POSTROUTING,OUTPUT

  

  mangle 表的系統 chain: PREROUTING,OUTPUT

  每條系統 chain 在确定的位置被檢查。比如在包過濾中,所有的目的位址為本地的包,則會進入INPUT 規則鍊,而從本地出去的包會進入 OUTPUT 規則鍊。

  所有的 table 和 chain 開機時都為空,設定 iptables 的方法就是在合适的 table 和系統 chain 中添相應的規則。

--------------------------------------------------------------

IPTABLES 文法:

表: iptables從其使用的三個表(filter、nat、mangle)而得名, 對包過濾隻使用 filter 表, filter還是預設表,無需顯示說明.

操作指令: 即添加、删除、更新等。

鍊:對于包過濾可以針對filter表中的INPUT、OUTPUT、FORWARD鍊,也可以操作使用者自定義的鍊。

規則比對器:可以指定各種規則比對,如IP位址、端口、包類型等。

目标動作:當規則比對一個包時,真正要執行的任務,常用的有:

 ACCEPT 允許包通過

 DROP 丢棄包

  一些擴充的目标還有:

  REJECT 拒絕包,丢棄包同時給發送者發送沒有接受的通知

  LOG 包有關資訊記錄到日志

  TOS 改寫包的TOS值

為使FORWARD規則能夠生效,可使用下面2種方法的某種:

[root@rhlinux root]# vi /proc/sys/net/ipv4/ip_forward

[root@rhlinux root]# echo "1" > /proc/sys/net/ipv4/ip_forward

[root@rhlinux root]# vi /etc/sysconfig/network

[root@rhlinux root]# echo "FORWARD_IPV4=true" > /etc/sysconfig/network

--------------------------------------------------------

iptables文法可以簡化為下面的形式:

iptables [-t table] CMD [chain] [rule-matcher] [-j target]

常用操作指令:

-A 或 -append 在所選鍊尾加入一條或多條規則

-D 或 -delete 在所選鍊尾部删除一條或者多條規則

-R 或 -replace 在所選鍊中替換一條比對規則

-I 或 -insert 以給出的規則号在所選鍊中插入一條或者多條規則. 如果規則号為1,即在鍊頭部.

-L 或 -list 列出指定鍊中的所有規則,如果沒有指定鍊,将列對外連結中的所有規則.

-F 或 -flush 清除指定鍊和表中的所由規則, 假如不指定鍊,那麼所有鍊都将被清空.

-N 或 -new-chain 以指定名建立一條新的使用者自定義鍊,不能與已有鍊名相同.

-X 或 -delete-chain 删除指定的使用者定義簾,必需保證鍊中的規則都不在使用時才能删除,若沒有指定鍊,則删除所有使用者鍊.

-P 或 -policy 為永久簾指定預設規則(内置鍊政策),使用者定義簾沒有預設規則,預設規則也使規則鍊中的最後一條規則,用-L顯示時它在第一行顯示.

-C 或 -check 檢查給定的包是否與指定鍊的規則相比對.

-Z 或 -zero 将指定簾中所由的規則包位元組(BYTE)計數器清零.

-h 顯示幫助資訊.

-------------------------------------------------------------

常用比對規則器:

-p , [!] protocol 指出要比對的協定,可以是tcp, udp, icmp, all, 字首!為邏輯非,表示除該協定外的所有協定.

-s [!] address[/mask] 指定源位址或者位址範圍.

-sport [!] port[:port] 指定源端口号或範圍,可以用端口号也可以用/ETC/SERVICES檔案中的名子.

-d [!] address[/mask] 指定目的位址或者位址範圍.

-dport [!] port[:port] 指定目的端口号或範圍,可以用端口号也可以用/ETC/SERVICES檔案中的名子.

-icmp-type [!] typename 指定比對規則的ICMP資訊類型(可以使用 iptables -p icmp -h 檢視有效的ICMP類型名)

-i [!] interface name[+] 比對單獨或某種類型的接口,此參數忽略時,預設符合所有接口,接口可以使用"!"來比對捕食指定接口來的包.參數interface是接口名,如 eth0, eht1, ppp0等,指定一個目前不存在的接口是完全合法的,規則直到接口工作時才起作用,折中指定對于PPP等類似連接配接是非常有用的."+"表示比對所有此類型接口.該選項隻針對于INPUT,FORWARD和PREROUTING鍊是合法的.

-o [!] interface name[+] 比對規則的對外網絡接口,該選項隻針對于OUTPUT,FORWARD,POSTROUTING鍊是合法的.

[!] --syn 僅僅比對設定了SYN位, 清除了ACK, FIN位的TCP包. 這些包表示請求初始化的TCP連接配接.阻止從接口來的這樣的包将會阻止外來的TCP連接配接請求.但輸出的TCP連接配接請求将不受影響.這個參數僅僅當協定類型設定為了TCP才能使用. 此參數可以使用"!"标志比對已存在的傳回包,一般用于限制網絡流量,即隻允許已有的,向外發送的連接配接所傳回的包.

----------------------------------------------------------

如何制定永久規則集:

/etc/sysconfig/iptables 檔案是 iptables 守護程序調用的預設規則集檔案.

可以使用以下指令儲存執行過的IPTABLES指令:

 /sbin/iptables-save >  /etc/sysconfig/iptables

要恢複原來的規則庫,可以使用:

 /sbin/iptables-restore <  /etc/sysconfig/iptables

iptables指令和route等指令一樣,重新開機之後就會恢複,是以:

[root@rhlinux root]# service iptables save

将目前規則儲存到 /etc/sysconfig/iptables:                 [  确定  ]

令一種方法是 /etc/rc.d/init.d/iptables 是IPTABLES的啟動腳本,是以:

[root@rhlinux root]# /etc/rc.d/init.d/iptables save

以上幾種方法隻使用某種即可.

若要自定義腳本,可直接使用iptables指令編寫一個規則腳本,并在啟動時執行:

例如若規則使用腳本檔案名/etc/fw/rule, 則可以在/etc/rc.d/rc.local中加入以下代碼:

if [-x /etc/fw/rule]; then /etc/fw/sule; fi;

這樣每次啟動都執行該規則腳本,如果用這種方法,建議NTSYSV中停止IPTABLES.

執行個體:

鍊基本操作:

[root@rh34 root]# iptables -L -n

(列出表/鍊中的所有規則,包過濾防火牆預設使用的是filter表,是以使用此指令将列出filter表中所有内容,-n參數可加快顯示速度,也可不加-n參數。)

[root@rh34 root]# iptables -F

(清除預設表filter中所有規則鍊中的規則)

[root@rh34 root]# iptables -X

(清除預設表filter中使用者自定義鍊中的規則)

[root@rh34 root]# iptables -Z

(将指定鍊規則中的所有包位元組計數器清零)

------------------------------------------------------------

設定鍊的預設政策,預設允許所有,或者丢棄所有:

[root@rh34 root]# iptables -P INPUT ACCEPT

[root@rh34 root]# iptables -P OUTPUT ACCEPT

[root@rh34 root]# iptables -P FORWARD ACCEPT

(以上我們在不同方向設定預設允許政策,若丢棄則應是DROP,嚴格意義上防火牆應該是DROP然後再允許特定)

---------------------------------------------------------------

向鍊中添加規則,下面的例子是開放指定網絡接口(信任接口時比較實用):

[root@rh34 root]# iptables -A INPUT -i eth1 -j ACCEPT

[root@rh34 root]# iptables -A OUTPUT -o eth1 -j ACCEPT

[root@rh34 root]# iptables -A FORWARD -i eth1 -j ACCEPT

[root@rh34 root]# iptables -A FORWARD -o eth1 -j ACCEPT

使用使用者自定義鍊:

[root@rh34 root]# iptables -N brus

(建立一個使用者自定義名叫brus的鍊)

[root@rh34 root]# iptables -A brus -s 0/0 -d 0/0 -p icmp -j DROP

(在此鍊中設定了一條規則)

[root@rh34 root]# iptables -A INPUT -s 0/0 -d 0/0 -j brus

(向預設的INPUT鍊添加一條規則,使所有包都由brus自定義鍊處理)

----------------------------------------------------------------

基本比對規則執行個體:

比對協定:

iptables -A INPUT -p tcp

(指定比對協定為TCP)

iptables -A INPUT -p ! tcp

(指定比對TCP以外的協定)

比對位址:

iptables -A INPUT -s 192.168.1.1

(比對主機)

iptables -A INPUT -s 192.168.1.0/24

(比對網絡)

iptables -A FORWARD -s ! 192.168.1.1

(比對以外的主機)

iptables -A FORWARD -s ! 192.168.1.0/24

(比對以外的網絡)

比對接口:

iptables -A INPUT -i eth0

iptables -A FORWARD -o eth0

(比對某個指定的接口)

iptables -A FORWARD -o ppp+

(比對所有類型為ppp的接口)

比對端口:

iptables -A INPUT -p tcp --sport www

iptables -A INPUT -p tcp --sport 80

(比對單一指定源端口)

iptables -A INPUT -p ucp --dport 53

(比對單一指定目的端口)

iptables -A INPUT -p ucp --dport ! 53

(指定端口以外)

iptables -A INPUT -p tcp --dport 22:80

(指定端口範圍,這裡我們實作的是22到80端口)

---------------------------------------------------------------------------------

指定IP碎片的處理:

[root@rh34 root]# iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.1.234 --dport 80 -j ACCEPT

[root@rh34 root]# iptables -A FORWARD -f -p tcp -s 192.168.1.0/24 -d 192.168.1.234 --dport 80 -j ACCEPT

[root@rh34 root]# iptables -L

Chain INPUT (policy ACCEPT)

target     prot opt source               destination

Chain FORWARD (policy ACCEPT)

ACCEPT     tcp  --  192.168.1.0/24       192.168.1.234      tcp dpt:http

ACCEPT     tcp  -f  192.168.1.0/24       192.168.1.234      tcp dpt:http

Chain OUTPUT (policy ACCEPT)

----------------------------------------------------------------------------------

設定擴充的規測比對:

(希望獲得比對的簡要說明,可使用: iptables -m name_of_match --help)

多端口比對擴充:

iptables -A INPUT -p tcp -m multiport --source-port 22,53,80

(比對多個源端口)

iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80

(比對多個目的端口)

iptables -A INPUT -p tcp -m multiport --port 22,53,80

(比對多個端口,無論是源還是目的端口)

-----------------------------------------------------------------------------

TCP比對擴充:

iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN

(表示SYN、ACK、FIN的标志都要被檢查,但是隻有設定了SYN的才比對)

iptables -A INPUT -p tcp --tcp-flags ALL SYN,ACK

(表示ALL:SYN、ACK、FIN、RST、URG、PSH的标志都被檢查,但是隻有設定了SYN和ACK的才比對)

iptables -p tcp --syn

(選項--syn是以上的一種特殊情況,相當于“--tcp-flags SYN,RST,ACK SYN”的簡寫)

--------------------------------------------------------------------------------

limit速率比對擴充:

[root@redhatlinux9 root]# iptables -A FORWARD -m limit --limit 300/hour

(表示限制每小時允許通過300個資料包)

[root@redhatlinux9 root]# iptables -A INPUT -m limit --limit-burst 10

(--limit-burst指定觸發時間的值(預設為5),用來比對瞬間大量資料包的數量。)

(上面的例子用來比對一次同時湧入的資料包是否超過十個,超過此上限的包将直接被丢棄)

[root@redhatlinux9 root]# iptables -A FORWARD -p icmp -m limit --limit 3/m --limit-burst 3

(假設均勻通過,平均每分鐘3個,那麼觸發值burst保持為3。如果每分鐘通過的包的數目小于3,那麼觸發值busrt将在每個周期(若每分鐘允許通過3個,則周期數為20秒)後加1,但最大值為3。每分鐘要通過的包數量如果超過3,那麼觸發值busrt将減掉超出的數值,例如第二分鐘有4個包,那麼觸發值變為2,同時4個包都可以通過,第三分鐘有6個包,則隻能通過5個,觸發值busrt變為0。之後,每分鐘如果包數量小于等于3個,則觸發值busrt将加1,如果每分鐘包數大于3,觸發值busrt将逐漸減少,最終維持為0)

(即每分鐘允許的最大包數量等于限制速率(本例中為3)加上目前的觸發值busrt數。任何情況下,都可以保證3個包通過,觸發值busrt相當于是允許額外的包數量)

基于狀态的比對擴充(連接配接跟蹤):

每個網絡連接配接包括以下資訊:源和目的位址、源和目的端口号,稱為套接字對(cocket pairs);協定類型、連接配接狀态(TCP協定)和逾時時間等。防火牆把這些叫做狀态(stateful)。能夠監測每個連接配接狀态的防火牆叫做狀态寶過濾防火牆,除了能完成普通包過濾防火牆的功能外,還在自己的記憶體中維護一個跟蹤連接配接狀态的表,是以擁有更大的安全性。

其指令格式如下:

iptables -m state --state [!] state [,state,state,state]

state表示一個用逗号隔開的的清單,用來指定的連接配接狀态可以有以下4種:

NEW:該包想要開始一個連接配接(重新連接配接或将連接配接重定向)。

RELATED:該包屬于某個已經建立的連接配接所建立的新連接配接。例如FTP的資料傳輸連接配接和控制連接配接之間就是RELATED關系。

ESTABLISHED:該包屬于某個已經建立的連接配接。

INVALID:該包不比對于任何連接配接,通常這些包會被DROP。

例如:

[root@redhatlinux9 root]# iptables -A INPUT -m state --state RELATED,ESTABLISHED

(比對已經建立的連接配接或由已經建立的連接配接所建立的新連接配接。即比對所有的TCP回應包)

[root@redhatlinux9 root]# iptables -A INPUT -m state --state NEW -i ! eth0

(比對所有從非eth0接口來的連接配接請求包)

下面是一個被動(Passive)FTP連接配接模式的典型連接配接跟蹤

[root@redhatlinux9 root]# iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT

[root@redhatlinux9 root]# iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT

下面是一個主動(Active)FTP連接配接模式的典型連接配接跟蹤

[root@redhatlinux9 root]# iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT

[root@redhatlinux9 root]# iptables -A INPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT

--------------------------------------------------------------------------------------

日志記錄:

格式為: -j LOG --log-level 7 --log-prefix "......"

[root@redhatlinux9 root]# iptables -A FORWARD -m tcp -p tcp -j LOG

[root@redhatlinux9 root]# iptables -A FORWARD -m icmp -p icmp -f -j LOG

[root@redhatlinux9 root]# iptables -A FORWARD -s 192.168.1.0/24 -d 10.10.10.0/24 -p tcp --sport 80 -j LOG

[root@redhatlinux9 root]# iptables -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-prefix "INPUT packet died:"

[root@redhatlinux9 root]# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New net syn:"

繼續閱讀