原帖發(fā)布于2018年11月
原理
??IPTables是Linux服務(wù)器上進(jìn)行網(wǎng)絡(luò)隔離的核心技術(shù),內(nèi)核在處理網(wǎng)絡(luò)請(qǐng)求時(shí)會(huì)對(duì)IPTables中的策略進(jìn)行逐條解析,因此當(dāng)策略較多時(shí)效率較低;而是用IPSet技術(shù)可以將策略中的五元組(協(xié)議,源地址,源端口,目的地址,目的端口)合并到有限的集合中,可以大大減少IPTables策略條目從而提高效率。測試結(jié)果顯示IPSet方式效率將比IPTables提高100倍。
??使用到的IPTables參數(shù)如下:
- -A INPUT|OUTPUT 指定IPTables鏈,對(duì)應(yīng)網(wǎng)絡(luò)數(shù)據(jù)流相對(duì)于當(dāng)前網(wǎng)卡的方向是流入或流出
- -p tcp|udp|icmp 指定網(wǎng)絡(luò)數(shù)據(jù)流使用的協(xié)議
- -m state|set 指定加載的模塊:set對(duì)應(yīng)IPSet模塊,具體的介紹在后面;state模塊用于限定連接狀態(tài),配置此項(xiàng)可以避免對(duì)每個(gè)ACCEPT的策略同時(shí)加入INPUT鏈和OUTPUT鏈
- -j ACCEPT|REJECT 指定對(duì)網(wǎng)絡(luò)數(shù)據(jù)流放行或拒絕
??目前網(wǎng)絡(luò)隔離使用默認(rèn)拒絕+白名單的方式配置,在配置IPSet表時(shí),根據(jù)其方向、協(xié)議、是否放行及五元組類型可以分為24個(gè)list:set類型的集合,每個(gè)list:set集合可以容納65536個(gè)其他類型集合(目前為hash:ip hash:ip,port),從而容納海量策略:
in_tcp_acc_si out_tcp_acc_di
in_tcp_rej_si out_tcp_rej_di
in_udp_acc_si out_udp_acc_di
in_udp_rej_si out_udp_rej_di
in_tcp_acc_dp out_tcp_acc_dp
in_tcp_rej_dp out_tcp_rej_dp
in_udp_acc_dp out_udp_acc_dp
in_udp_rej_dp out_udp_rej_dp
in_tcp_acc_sidp out_tcp_acc_didp
in_tcp_rej_sidp out_tcp_rej_didp
in_udp_acc_sidp out_udp_acc_didp
in_udp_rej_sidp out_udp_rej_didp
IPSet策略設(shè)計(jì)
使用到的IPSet類型
- hash:ip 用于單獨(dú)指定(si=源地址)或(di=目標(biāo)地址),這兩種在本方案中都會(huì)使用
- hash:ip,port 用于指定(sisp=源地址-源端口)、(disp=目的地址-源端口)、(sidp=源地址-目的端口)、(didp=目的地址-目的端口),后兩種在本方案中會(huì)使用
- bitmap:port 用于單獨(dú)指定端口(sp=源端口)或(dp=目的端口),后一種在本方案中會(huì)使用
- list:set 用于容納前述三種集合類型,且不能包含本身
??目前存在的hash:ip hash:ip,port容量設(shè)置為1048576,bitmap:port容量設(shè)置為65536,外層list:set容量設(shè)置為65536,這樣任意一個(gè)list:set集合可以容納1048576*65536=600億 個(gè)元素,整體結(jié)構(gòu)如下:
IPTables
in_tcp_acc_si
set1
set2
....
setn
in_tcp_rej_si
set1
set2
....
setn
in_udp_acc_si
in_udp_rej_si
in_tcp_acc_dp
in_tcp_rej_dp
in_udp_acc_dp
in_udp_rej_dp
in_tcp_acc_sidp
in_tcp_rej_sidp
in_udp_acc_sidp
in_udp_rej_sidp
out_tcp_acc_di
out_tcp_rej_di
out_udp_acc_di
out_udp_rej_di
out_tcp_acc_dp
out_tcp_rej_dp
out_udp_acc_dp
out_udp_rej_dp
out_tcp_acc_didp
out_tcp_rej_didp
out_udp_acc_didp
out_udp_rej_didp
IPSet使用注意事項(xiàng)
- hash類型集合在iptables命令執(zhí)行時(shí)大小確定,后期如果對(duì)該集合增加較多元素會(huì)發(fā)生哈希沖突,影響策略匹配。因此建立集合時(shí)需要設(shè)定一個(gè)較大容量
- ipset的集合在執(zhí)行iptables后進(jìn)行更新操作時(shí),會(huì)在這段時(shí)間執(zhí)行默認(rèn)操作(reject)
- list:set不能包含list:set類型,只能包含其他類型
IPTables策略設(shè)計(jì)
??按如下形式固定IPTables策略,可避免IPTables本身策略的備份與恢復(fù)操作(IPTables進(jìn)行restore操作時(shí)會(huì)全量還原重置,而IPSet進(jìn)行restore操作時(shí)是增量進(jìn)行的):
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set in_tcp_acc_si src
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set in_tcp_acc_dp dst
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set in_tcp_acc_sidp src,dst
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -j REJECT -m set --set in_tcp_rej_si src
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -j REJECT -m set --set in_tcp_rej_dp dst
-A INPUT -p tcp -m state --state NEW,ESTABLISHED -j REJECT -m set --set in_tcp_rej_sidp src,dst
-A INPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set in_udp_acc_si src
-A INPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set in_udp_acc_dp dst
-A INPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set in_udp_acc_sidp src,dst
-A INPUT -p udp -m state --state NEW,ESTABLISHED -j REJECT -m set --set in_udp_rej_si src
-A INPUT -p udp -m state --state NEW,ESTABLISHED -j REJECT -m set --set in_udp_rej_dp dst
-A INPUT -p udp -m state --state NEW,ESTABLISHED -j REJECT -m set --set in_udp_rej_sidp src,dst
-A INPUT -m state --state NEW -j REJECT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set out_tcp_acc_di src
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set out_tcp_acc_dp dst
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set out_tcp_acc_didp src,dst
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j REJECT -m set --set out_tcp_rej_di src
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j REJECT -m set --set out_tcp_rej_dp dst
-A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j REJECT -m set --set out_tcp_rej_didp src,dst
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set out_udp_acc_di src
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set out_udp_acc_dp dst
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j ACCEPT -m set --set out_udp_acc_didp src,dst
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j REJECT -m set --set out_udp_rej_di src
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j REJECT -m set --set out_udp_rej_dp dst
-A OUTPUT -p udp -m state --state NEW,ESTABLISHED -j REJECT -m set --set out_udp_rej_didp src,dst
-A OUTPUT -j LOG --log-prefix "iptables:"
-A OUTPUT -m state --state NEW -j REJECT
COMMIT
??現(xiàn)在來考慮IPSet指定的五元組的問題
INPUT連接:考慮socket的accept函數(shù),源端即遠(yuǎn)程主機(jī),目的端即本機(jī)。這里只考慮新鏈接(NEW)
源地址 即遠(yuǎn)程主機(jī)地址,可以作為策略限制因子
源端口 即遠(yuǎn)程主機(jī)端口,一般為隨機(jī)端口,不可作為策略限制因子
目的地址 即本機(jī)地址,由于是固定的,無需作為策略限制因子
目的端口 即本機(jī)端口,可以作為策略限制因子
OUTPUT連接:考慮socket的connect函數(shù),源端即本機(jī),目的端即遠(yuǎn)程主機(jī)。這里只考慮新鏈接(NEW)
源地址 即本機(jī)地址,由于是固定的,無需作為策略限制因子
源端口 即本機(jī)端口,一般為隨機(jī)端口,不可作為策略限制因子
目的地址 即遠(yuǎn)程主機(jī)地址,可以作為策略限制因子
目的端口 即遠(yuǎn)程主機(jī)端口,可以作為策略限制因子
??綜上,對(duì)于INPUT連接,可以指定源地址(si)、目的端口(dp)、源地址+目的端口(sidp);而對(duì)于OUTPUT連接,可以指定目的地址(di)、目的端口(dp)、目的地址+目的端口(didp)
IPSet方案相比IPTables方案的優(yōu)點(diǎn)
- IPSet基于IPTables方案,是對(duì)IPTables技術(shù)的優(yōu)化,將線性策略查找優(yōu)化為集合元素查找,提高了通信速度
- IPSet方案在進(jìn)行下發(fā)更新時(shí),只需要對(duì)IPSet策略進(jìn)行更新,無需對(duì)IPTables策略進(jìn)行更新,由于在這種情況下IPTables條目極少,且無需還原操作,因此在更新的時(shí)間段對(duì)網(wǎng)絡(luò)策略的影響較小,不會(huì)出現(xiàn)因?yàn)镮PTables重置而導(dǎo)致短時(shí)間策略失效問題