iptables/netfilter介紹、樣例實驗和配置規則

0x 01 前言

Iptables是運行在用戶空間的應用級(Ring3)防火牆軟件,通過調用Linux內核的Netfilter模塊,進行網絡數據包的流動、轉送以及修改。iptables是狀態防火牆,可以對會話的狀態進行跟蹤,這點相較於無狀態防火牆要方便許多。
Netfilter是由Rusty Russell提出的Linux 2.4.x內核防火牆框架,目前支持的內核包括2.4、2.6及3.0。iptables所設置的規則最終是存放在內核內存中的Xtables(Netfilter的配置表)。Iptables和ip6_tables、arp_tables等Netfilter的項目都是建構在Xtables的架構下。


0x 02 表,鏈以及規則

1、表(tables)

表是包含了不同默認鏈的組合,每個表都和數據包的處理有關,iptables共內置了5個表,即filter,nat,mangle,raw,security分別實現數據包過濾、動態網絡地址轉換,(Network Address Translation,NAT),數據包修改,數據包狀態跟蹤,以及實現強制訪問控制MAC(Mandatory Access Control )和自主訪問控制DAC(Discretionary Access Control )等。

2、鏈(chains)

鏈是決定數據包是否可以通過的決定因素,每個數據包從進入系統,到離開系統,都至少要通過2條鏈。
鏈是Netfilter中的掛載點(Hook Point)在iptables中的體現,共包括5條鏈,分別爲PREROUTING(數據包進入路由表之前),INPUT(通過路由表後目的地爲本機),FORWARD(通過路由表後,目的地不爲本機),OUTPUT(由本機產生,向外轉發),POSTROUTING(發送到網卡接口之前),對應Netfilter中5個掛載點:

NF_INET_PRE_ROUTING,NF_INET_LOCAL_IN,NF_INET_FORWARD,NF_INET_LOCAL_OUT,NF_INET_POST_ROUTING

圖1 Netfilter框架

注:掛載點(Hook Point),可以理解爲回調函數點,數據包到達這些位置的時候,會主動調用對應的函數,使其在數據包路由的時候可以改變它們的路徑以及內容。

3、規則(rules)

規則在鏈裏面決定對數據包的處理動作,存儲在內核空間的Xtables中。在這裏,可以定義對數據包的具體處理(target)。當數據包穿過一條鏈的時候,每條規則會依序檢查它(包括源目地址,協議等參數),如果沒有規則與其相匹配,則數據包會被傳遞到下一條規則去嘗試匹配,當匹配上之後,會按照target中規定的動作對數據包進行梳理。

圖2  iptables中表、鏈以及規則的對應關係


0x 03 利用Iptables進行網絡地址轉換實例展示

我們經常使用xshell等交互式工具進行端口轉發和地址轉換,iptables中的地址轉換功能對大部分人來說用到不算很多,但是卻很有用。以此例來展示iptables的使用。

1、環境:

  • 1臺centos7主機作爲web主機
ip=192.168.0.10,hostname=webserver
  • 1臺Ubuntu 16.04作爲iptables所在主機,iptables版本爲iptables 1.6.0
ip=192.168.0.5,hostname= IptablesTest
  • 1臺Ubuntu 16.04作爲client(192.168.0.20)
ip=192.168.0.20,hostname=client

2、需求描述

模仿反向代理的場景,webserver的http流量不能被其他機器直接訪問,需要通過IptablesTest作爲中轉才能到達。

  • 首先在webserver將所有的入流量全部DROP,這樣所有的流量都無法進入該機器
         iptables -P INPUT DROP
  • 在webserver上放行IptablesTest的流量以及宿主機(192.168.0.4)的流量
iptables -I INPUT -s 192.168.0.4 -j ACCEPT
iptables -I INPUT -s 192.168.0.5 -j ACCEPT
  • webserver上的iptables配置完成後的filter表如下:

  • 由於Linux默認將路由功能關閉,因此需要在IptablesTest機器上打開Linux路由轉發開關功能,具體方法如下:
    編輯/etc/sysctl.conf,並加入如下語句

如果僅希望臨時生效,下次開機失效,可以執行如下語句:

echo "1" > /proc/sys/net/ipv4/ip_forward

如果需要永久生效的話,需要修改sysctl.conf:
net.ipv4.ip_forward = 1
執行sysctl -p 立即生效

注:這點很重要,也很容易被忽略

  • 在IptablesTest機器上將所有訪問該機器80端口的TCP流量全部做DNAT轉換,將目的地址轉換爲webserver的地址;並將webserver返回的流量使用SNAT轉回給client,這裏也可以使用路由反向做回的方向實現。
iptables -t  nat -A PREROUTING -d  192.168.0.5/32  -p tcp --dport 80 -j DNAT --to-destination  192.168.0.10:80
iptables -t nat -A POSTROUTING -d  192.168.0.10/32  -p tcp -j SNAT --to  192.168.0.5
  • IptablesTest上iptables配置完成後的filter表如下:

  • 我們發現直接訪問webserver地址,發現並不通,而訪問IptablesTest的80端口,發現可以打開http服務。說明訪問webserver的流量被IptablesTest進行了轉換和代理。


0x 04 Iptables常見配置命令和操作

一、鏈及NAT的基本操作

1、清除所有的規則

清空自定義鏈、清空規則、清空規則計數器

iptables -X
iptables -F
iptables -Z

清除NAT表規則

iptables -F -t nat

NAT表的顯示

iptables -t nat -nL
2、設置鏈的默認策略。一般有兩種方法。

首先允許所有的包,然後再禁止有危險的包通過放火牆。

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

首先禁止所有的包,然後根據需要的服務允許特定的包通過防火牆。

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
3、列出表/鏈中的所有規則。默認只列出filter表。
iptables -L
4、向鏈中添加規則。下面的語句用於開放網絡接口:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACEPT
iptables -A OUTPUT -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
iptables -A FORWARD -0 eth1 -j ACCEPT

注意:由於本地進程不會經過FORWARD鏈,因此迴環接口lo只在INPUT和OUTPUT兩個鏈上作用。

5、按需自定義鏈。
iptables -N custom
iptables -A custom -s 0/0 -d 0/0 -p icmp -j DROP
iptables -A INPUT -s 0/0 -d 0/0 -j custom

二、設置基本的規則匹配

1、指定協議匹配。

匹配指定協議。

iptables -A INPUT -p tcp

匹配指定協議之外的所有協議。

iptables -A INPUT -p !tcp
2、指定地址匹配。

指定匹配的主機。

iptables -A INPUT -s 192.168.0.18

指定匹配的網絡。

iptables -A INPUT -s 192.168.2.0/24

匹配指定主機之外的地址。

iptables -A FORWARD ! -s 192.168.0.19

匹配指定網絡之外的網絡。

iptables -A FORWARD ! -s  192.168.3.0/24
3、指定網絡接口匹配。

指定單一的網絡接口匹配。

iptables -A INPUT -i eth0
iptables -A FORWARD -o eth0

指定同類型的網絡接口匹配。

iptables -A FORWARD -o ppp+
4、指定端口匹配。

指定單一端口匹配。

iptables -A INPUT -p tcp --sport www
iptables -A INPUT -p udp --dport 53

匹配指定端口之外的端口。

iptables -A INPUT -p tcp --dport !22

匹配端口範圍。

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

匹配ICMP端口和ICMP類型。

iptables -A INPUT -p icmp --icmp-type 8

指定ip碎片。

  • 每個網絡接口都有一個MTU(最大傳輸單元),這個參數定義了可以通過的數據包的最大尺寸。如果一個數據包大於這個參數值時,系統會將其劃分成更小的數據包(稱爲ip碎片)來傳輸,而接受方則對這些ip碎片再進行重組以還原整個包。這樣會導致一個問題:當系統將大數據包劃分成ip碎片傳輸時,第一個碎片含有完整的包頭信息(IP+TCP、UDP和ICMP),但是後續的碎片只有包頭的部分信息(如源地址、目的地址)。因此,檢查後面的ip碎片的頭部(像有TCP、UDP和ICMP一樣)是不可能的。假如有這樣的一條規則:
iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.2.100 –dport 80 -j ACCEPT
  • 並且這時的FORWARD的policy爲DROP時,系統只會讓第一個ip碎片通過,而餘下的碎片因爲包頭信息不完整而無法通過。可以通過—fragment/-f 選項來指定第二個及以後的ip碎片解決上述問題。
iptables -A FORWARD -f -s 192.168.1.0/24 -d 192.168.2.100 -j ACCEPT

注意現在有許多進行ip碎片的實例,如DoS,因此允許ip碎片通過是有安全隱患的,對於這一點可以採用iptables的匹配擴展來進行限制。

三、設置擴展的規則匹配(舉例已忽略目標動作)

1、多端口匹配。

匹配多個源端口。

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

匹配多個目的端口。

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

匹配多端口(無論是源端口還是目的端口)

iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
2、指定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”的簡寫。

3、limit速率匹配擴展。

指定單位時間內允許通過的數據包個數,單位時間可以是/second、/minute、/hour、/day或使用第一個子母。

iptables -A INPUT -m limit --limit 300/hour

指定觸發事件的閥值。

iptables -A INPUT -m limit --limit-burst 10 

用來比對一次同時涌入的封包是否超過10個,超過此上限的包將直接丟棄。

同時指定速率限制和觸發閥值。

iptables -A INPUT -p icmp -m limit –-limit 3/m --limit-burst 3

表示每分鐘允許的最大包數量爲限制速率(本例爲3)加上當前的觸發閥值burst數。任何情況下,都可保證3個數據包通過,觸發閥值burst相當於允許額外的包數量。

基於狀態的匹配擴展(連接跟蹤)

每個網絡連接包括以下信息:源地址、目標地址、源端口、目的端口,稱爲套接字對(socket pairs);協議類型、連接狀態(TCP協議)和超時時間等。防火牆把這些信息稱爲狀態(stateful)。狀態包過濾防火牆能在內存中維護一個跟蹤狀態的表,比簡單包過濾防火牆具有更大的安全性,命令格式如下:

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

其中,state表是一個逗號分割的列表,用來指定連接狀態,4種:

NEW: 該包想要開始一個新的連接(重新連接或連接重定向)
RELATED:該包是屬於某個已經建立的連接所建立的新連接。舉例:
FTP的數據傳輸連接和控制連接之間就是RELATED關係。
ESTABLISHED:該包屬於某個已經建立的連接。
INVALID:該包不匹配於任何連接,通常這些包被DROP。

例如:
(1)在INPUT鏈添加一條規則,匹配已經建立的連接或由已經建立的連接所建立的新連接。即匹配所有的TCP迴應包。

iptables -A INPUT -m state --state RELATED,ESTABLISHED

(2)在INPUT鏈鏈添加一條規則,匹配所有從非eth0接口來的連接請求包。

iptables -A INPUT -m state -–state NEW -i !eth0

又如,對於ftp連接可以使用下面的連接跟蹤:
(3)被動(Passive)ftp連接模式。

iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state –-state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m 
state -–state ESTABLISHED,RELATED -j ACCEPT

(4)主動(Active)ftp連接模式

iptables -A INNPUT -p tcp --sport 20 -m state –-state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp –dport 20 -m state --state ESTABLISHED -j ACCEPT

參考:

https://zh.wikipedia.org/wiki/Iptables

http://www.cnblogs.com/LittleHann/p/3708222.html

https://blog.csdn.net/sealyao/article/details/5934268

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://www.vpser.net/security/linux-iptables.html

http://blog.51cto.com/xjsunjie/1902993

http://blog.51cto.com/qujunorz/1884459

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章