iptables:包過濾型的防火牆
Firewall:防火牆,隔離工具;工作于主機或網絡邊緣,對于進出本主機或本網絡的封包根據事先定義的檢查規則作比對檢測,對于能夠被規則比對到的封包做出相應處理的元件;
主機防火牆
網絡防火牆
軟體防火牆(軟體邏輯)
硬體防火牆(硬體和軟體邏輯)
ipfw(firewall framework)
ipchains(firewall framework)
iptables(netfilter)
netfilter:kernel
iptables:rules until
hook function:
input
output
forward
prerouting
postrouting
鍊(内置):
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
功能:
filter:過濾,防火牆;
nat:network address translation;用于修改源ip或者目标ip,也可以改端口;
mangle:拆解封包,做出修改,并重新封裝起來;
raw:關閉nat表上啟用的連接配接追蹤機制;
功能<-> 鍊
raw:PREROUTING, OUTPUT
mangle:PREROUTING , INPUT , FORWARD,OUTPUT ,POSTROUTING
nat:PREROUTING, [INPUT], OUTPUT, POSTROUTING
filter:INPUT , FORWARD , OUTPUT
封包流向:
流入本機:PREROUTING à INPUT
由本機流出:OUTPUT à POSTROUTING
轉發:PREROUTING à FORWARD à POSTROUTING
路由功能發生時刻:
封包進入本機後;
判斷目标主機是?
封包離開主機前:
判斷由哪個接口送往下一站?
Iptables/netfileter
規則:
組成部分:根據規則比對條件來嘗試比對封包,一旦比對成功,就由規則定義的處理動作;
比對條件:
基本比對條件
擴充比對條件
處理動作:
基本處理動作
擴充處理動作
自定義處理機制
iptables的鍊:内置鍊和自定義鍊
内置鍊:對應于hook function
自定義連結:用于内置鍊的擴充和補充,可實作更靈活的規則管理機制;
添加規則時的考量點:
1) 要實作哪種功能:判斷添加到哪個表上;
2) 封包流經的路徑:判斷添加到哪個鍊上;
鍊:鍊上的規則次序,即為檢查的次序;是以,隐含一定的應用法則;
1) 同類規則(通路同一應用),比對範圍小的放上面;
2) 不同類的規則(通路不同應用),比對範圍小的放上面;
3) 将那些可由一條規則描述的多個規則合并起來;
4) 設定預設政策;
iptables指令:
iptables [-t table] {-A|-C|-D} chain rule_specification
iptables [-t table] –I chain [rulenum] rule-specification
iptables [-t table] –R chain rulenum rule-specification
iptables [-t table] -D chain rulenum
iptables [-t table] –S [chain [rulenum]]
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options…]
iptables [-t table] –N chain
iptables [-t table] -X chain
iptables [-t table] -P chain target
iptables [-t table] -E old-chain-name new-chain-name
rule-specification = [matches…] [target]
match = -m matchname [per-match-options]
target =-j targetname [per-target-options]
規則格式:iptables [-t table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
-t table :
raw,mangle,nat ,[filter]
COMMAND:
鍊管理:
-N:new,自定義一條新的規則鍊;

-X:delete,删除自定義的規則鍊;
-P:Policy,設定預設政策;對filter表中的鍊而言,其預設政策有:
ACCEPT:接受;
DROP:丢棄
REJECT:拒絕
-E:重命名自定義鍊;引用計數不為0的自定義鍊不能夠被重命名,也不能被删除;
規則管理:
為了掩飾友善我們設預設政策為DROP;
-A:append,追加;
-I:insert,插入,要指明位置,省略時表示第一條;
-R:replace,替換指定鍊上的指定規則;
-D:delete,删除:
1) 指明規則序号;
2) 指明規則本身;
-F:flush,清空指定的規則鍊;
-Z:zero,置零;
iptables的每條規則都由兩個計數器;
1) 比對到的封包的個數;
2) 比對到的所有封包大小之和;
檢視:
-L:list,列出指定鍊上的所有規則;
-n:numberic,以數字格式顯示位址和端口号;
-v:verbose,詳細資訊;
-vv,-vvv
-x:exactly,顯示計數器結果的精确值;
--line-numbers:顯示規則的序号;
chain:
PREROUTING , INPUT , FORWARD , OUTPUT , POSTROUTING
基本比對條件:無需加載任何子產品,由iptables/netfilter
[!] –s,--source address[/mask][,…]:檢查封包中的源ip位址是否符合此處指定的位址或範圍;
[!] –d ,--destination address [/mask][,…]:檢查封包中的目标位址是否符合此處指定的位址或範圍;
[!] –p,--protocol PROTOCOL
PROTOCOL:tcp,udp,udplite,icmp,icmpv6,esp,ah,sctp,mh or “all”
{tcp|udp|icmp}
[!] – i,--in-interface name:資料封包流入的接口:隻能應用于資料封包流入的環節,隻能應用于PREROUTING,INPUT和FORWARD鍊;
[!] – 0,--out-interface name:資料封包流出的接口;隻能應用于資料封包流出的環節,智能應用于FORWARD,OUTPUT和POSTROUTING鍊;
擴充比對條件:需要加載擴充子產品,方可生效;
隐式擴充:不需要手動加載擴充子產品;因為他們是對協定的擴充,是以,但凡使用-p指明了協定,就表示已經指明了要擴充的子產品;
tcp:
[!] --source-port, --sport port[:port]:比對封包的源端口;可以是端口範圍
[!] --destination-port,--dport port[:port]:比對封包的目标端口;可以是端口範圍;
[!] --tcp-flages mask comp
mask is the flags which we should examine, written as a comma-separated list,例如 SYN,ACK,FIN,RST
comp is a comma-separated list of flags which must be set,例如SYN
例如:“--tcp-flags SYN,ACK,FIN,RST SYN”表示,要檢查的标志位為SYN,ACK,FIN,RST四個,其中SYN必須為1,餘下的必須為0;
[!] --syn:用于比對第一次握手,相當于“--tcp-flags SYN,ACK,FIN,RST SYN”
udp
[!] --source-port , --sport port[:port]:比對封包的源端口;可以是端口範圍;
icmp
[!] --icmp-type {type[/code]|typename}
echo-request:8
echo-reply:0
顯示擴充:必須要手動加載擴充子產品,[-m matchname [per-match-options]];
-j targetname [per-target-options]
ACCEPT
DROP
REJECT
RETURN:傳回調用鍊;
REDIRECT:端口重定向;
LOG:記錄日志;
MARK:做防火牆标記;
DNAT:目标位址轉換;
SNAT:源位址轉換;
MASQUERADE:位址僞裝;
…
自定義鍊;
防火牆(服務):
Centos6:
service iptables {start|stop|restart|status}
start:讀取實作儲存的規則,并應用到netfilter上;
stop:清空netfilter上的規則,以及還原預設政策等;
status:顯示生效的規則;
restart:清空netfilter上的規則,再讀取事先儲存的規則,并應用到netfilter上;
預設的規則檔案:/etc/sysconfig/iptables
Centos7:
systemctl start|stop|restart|status firewalld.service
systemctl disable firewalld.service 設定iptables開機不自啟;
systemctl stop firewalld.service
iptables(2)
顯示擴充:必須顯示地指明使用的擴充子產品進行的擴充;
使用幫助:
Centos6:man iptables
Centos7:man iptables-extensions
1. multiport擴充;
以離散方式定義多端口比對;最多指定5個端口;
[!] --source-ports,--sports port[,port|,port:port]…:指定多個源端口;
[!] --destination-ports,--dports port[,port|,port:port]…多個目标端口;
[!] --ports port[,port|,port:port]…多個端口;
2. iprange擴充
指明連續的(但一般不包整個網絡)ip位址範圍;
[!] --src-range from[-to]:源ip位址;
[!] --dst-range from[-to]:目标ip位址;
3. string擴充
對封包中的應用層資料做字元串模式比對檢測;
--algo {bm|kmp}:字元串比對檢測算法;
bm:Boyer-Moore
kmp:Knuth-Pratt-Morris
[!] --string pattern:要檢測的字元串模式;
[!] --hex-string pattern:腰間的字元串模式,16進制格式;
4. time擴充
根據将封包到達的時間與指定的時間範圍進行比對;
--datastart YYYY[-MM[--DD[Thh[:mm[:ss]]]]]
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--timestart hh:mm[:ss]
--timestop hh:mm[:ss]
[!] --monthdays day[,day...]
[!] --weekdays day[,day...]
--kerneltz:使用核心上的時區,而非預設的UTC;
5. connlimit擴充;
根據每用戶端IP做并發連接配接數數量比對;
--connlimit-upto n :連接配接數量小于或等于n時比對;
--connlimit-above n:連接配接的數量大于n時比對;
6. limit擴充;
基于收發封包的速率做比對;
令牌通過過濾器;
--limit rate[/second|/minute|/hour|/day]
--limit-burst number
7. state擴充
根據“連接配接追蹤機制”去檢查連接配接的狀态;
Conntrack機制:追蹤本機上的請求和響應之間的關系;狀态有如下幾種;
NEW:新發出的請求;連接配接追蹤模闆中不存在此連結的相關資訊條目,是以,将其識别為第一次發出的請求;
ESTABLISHED:NEW狀态之後,連接配接追蹤模闆中為其建立的條目失效之前期間内所進行的通信狀态;
RELATED:相關聯的連接配接;如ftp協定中的資料連接配接與指令連接配接之間的關系;
INVALID:無效的連接配接;
UNTRACKED:未進行追蹤的連接配接;
[!] --state state
調整連接配接追蹤功能所能夠容納的最大連接配接數量;
/proc/sys/net/nf_contrack_max
已經追蹤到的并記錄下的連接配接;
/proc/net/nf_conntrack
不同的協定的連接配接追蹤時長;
/proc/sys/net/netfilter/
Note:iptables的連接配接跟蹤表最大容量為/proc/sys/net/ipv4/ip_conntrack_max,連結碰到各種狀态的逾時後就會從表中删除;當模闆滿載時,後續的連接配接可能會逾時;
解決方法一般有兩個:
1) 加大nf_conntrack_max的值
vim /etc/sysctl.conf
net.ipv4.nf_conntrack_max = 393216
net.ipv4.netfilter.nf_conntrack_max = 393216
2) 降低nf_conntrack timeout時間;
net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
問題:如何開放被動模式的ftp服務?(server位址為192.168.19.130)
1) 裝載ftp連接配接追蹤的專用子產品;
~]# modproble nf_conntrack_ftp
2) 放行指令連接配接
~]# iptables -A INPUT -d 192.168.19.130 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
~]# iptables -A OUTPUT -s 192.168.19.130 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
3) 放行資料連接配接;
~]# iptables -A INPUT -d 192.168.19.130 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
~]# iptables -I OUTPUT -s 192.168.19.130 -m state --state ESTABLISHED -j ACCEPT
規則優化:
伺服器端規則設定:任何不允許的通路,應該在請求到達時給予拒絕;
1) 可安全放行所有入棧的狀态為ESTABLISHED的狀态的連接配接;
2) 可安全放行所有出站狀态為ESTABLISHED狀态的連接配接;
3) 謹慎放行入棧的心情求;
4) 有特殊目的限制通路功能,要于放行規則之前加以拒絕;
如何使用自定義鍊:
自定義鍊:需要被調用才能生效;自定義鍊最後需要定義傳回規則;
傳回規則使用的target叫做RETURN
規則的有效期限:
使用iptables指令定義的規則,手動删除之前,其生效期限為kernel存活期限;
儲存規則:
儲存規則至指定的檔案中:
Centos6:
service iptables save:将規則儲存至/etc/sysconfig/iptables檔案中;
iptables-save > /path/ro/some_rules_file:将規則儲存指定的檔案中;
centos7:
iptables-save > /path/to/some_rules_file:
重新載入預存規則檔案中的規則:
iptables-restore < /path/from/some_rules_file
Service iptables restart
自動生效規則檔案中的規則;
1) 用腳本儲存各iptables指令:讓此腳本開機後自動運作;
/etc/rc.d/rc.local檔案添加腳本路徑;
/path/to/some_script_file
2) 用規則檔案儲存各規則,開機時自動載入此規則檔案中的規則;
/etc/rc.d/rc.local檔案添加;
Iptables-restore < /path/from/iptables_rules_file
CentOS 7:
引入了新的iptables前端管理工具firewalld,其管理工個有:firewalld-cmd, firewalld-config
網絡防火牆:
netfilter在INPUT和OUTPUT鍊上表現其作為主機防火牆的角色,而其在FORWARD鍊上則表現是作為網絡防火牆的角色;
下面通過執行個體示範網絡防火牆:
centos7主機有兩塊網卡,并且這兩塊網卡的位址位于不同的網絡中,位址分别為192.168.19.130和172.16.23.1;centos6test作為伺服器,位址為172.16.23.2;centos6作為用戶端,位址為192.168.19.134;
要求:通過centos7主機扮演網絡防火牆,在FORWARD鍊上生成過濾規則,規則要求如下;
1) 放行用戶端對伺服器端的ftp服務的通路;
2) 放行用戶端對伺服器端的遠端連接配接ssh服務;
3) 放行用戶端對伺服器端的web服務的通路;
4) 放行用戶端對伺服器端的ping操作;
Centos7主機上;
1. 開啟轉發功能;
2. 設定ip位址為如下位址;
3. 清空規則鍊,建立規則;
Centos6test主機上:
1. 設定其ip位址為如下位址;
2. 設定路由指向centos7主機;
Centos6主機上:
1. 設定ip位址為如下;
2. 删除原有的路由,設定新的路由指向centos7主機;
iptables(3)之nat
netfilter:nat table
nat:network address translation
snat:source nat
dnat:destination nat
pnat:port nat
snat:POSTROUTING , OUTPUT
讓本地網絡中的主機用過某一特定地位址通路外部網絡時,
dnat:PREROUTING
把本地網絡中的某一主機上的某服務開放給外部網絡中的使用者通路時,
nat表的target
SNAT
--to-source [ipaddr [-ipaddr]][:port[-port]]
DNAT
--to-destination [ipaddr[-ipaddr]][:port[-port]]
MASQUERADE
--to-ports port[-port]
--random
SNAT示例:
1. 在上面的網絡防火牆示例中,用centos6主機通路centos6test主機的web服務并做ping操作;
2. 在centos6test主機上使用tcpdump指令抓包,并且檢視httpd的通路日志,可以發現位址都是192.168.19.134;
3. 在網絡防火牆centos7主機上添加net規則;
4. 再一次重複第1步,第2步操作,測試,發現抓包的位址和日志檔案中位址都變成了192.168.115.32;
DNAT示例:
1. 添加規則;
2. 在centos6主機上再次通路centos6test的web服務,發現通路的是centos7主機的web,這裡的目的位址發現了轉換;
3. 當然也可以在轉換目的位址的同時轉換端口;
MASQUERADE示例:位址僞裝
2. 在centos6主機上對centos6test作ping操作;
3. 在centos6test主機抓包測試;
REDIRECT:端口重定向;
Web:8080
80 —> 8080
1. 将centos6test主機的httpd服務監聽端口改為8080;
2. 在centos6test主機上添加規則;
3. 此時通過centos6主機通路centos6test主機的httpd服務;
Note:必須要加端口通路,通路80端口,自動重定向為8080端口;
補充:利用iptables的recent子產品來抵禦DOS攻擊: 22,建立一個清單,儲存有所有通路過指定的服務的用戶端IP
以ssh( 遠端連接配接)為例:
1. 利用connlimit子產品将單IP的并發設定為3;會誤殺使用NAT上網的使用者,可以根據實際情況增大該值;
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
2. 利用recent和state子產品限制單IP在300s内隻能與本機建立2個新連接配接。被限制五分鐘後即可恢複通路。
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
下面對最後兩句做一個說明:
1.第二句是記錄通路tcp 22端口的新連接配接,記錄名稱為SSH
--set 記錄資料包的來源IP,如果IP已經存在将更新已經存在的條目
2.第三句是指SSH記錄中的IP,300s内發起超過3次連接配接則拒絕此IP的連接配接。
--update 是指每次建立連接配接都更新清單;
--seconds必須與--rcheck或者--update同時使用
--hitcount必須與--rcheck或者--update同時使用
3.iptables的記錄:/proc/net/xt_recent/SSH
也可以使用下面的這句記錄日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"