iptables踩坑記

1:第一坑:衆所周知nf_conntrack,下面會有介紹補坑方法。服務器

2:連環坑:併發

要解決第一個坑,須要修改內核參數,如:tcp

net.netfilter.nf_conntrack_tcp_timeout_established = 600    ide

net.netfilter.nf_conntrack_max = 1048576spa

net.nf_conntrack_max = 1048576.net


這幾個參數是基於nf_conntrack模塊的,若是nf_conntrack在系統中沒有被加載,則上面三個選項就恢復成默認值。設計

/etc/init.d/iptables stop這個命令會將nf_conntrack模塊移除,運行stop命令後使用sysctl -a 你會發現nf_conntrack的三個選項恢復成了默認值。orm

而後你再一次啓動/etc/init.d/iptables start ,而此時nf_conntrack仍是保持默認值。系統大量報錯。。。介,介,介,你踩到iptables精心設計的「連環坑」。中間件


修改:blog

NF_MODULES_COMMON=(x_tables nf_nat nf_conntrack) # Used by netfilter v4 and v6

NF_MODULES_COMMON=(x_tables nf_nat) # Used by netfilter v4 and v6

便可。


對於「連環坑」,遇到是有條件的:

便是:系統中不存在ipv6包

由於nf_conntrack_ipv6 是依賴nf_conntrack的,這樣iptables腳本使用modprobe -r nf_conntrack 卸載不掉該模塊,就不會恢復nf_conntrack默認值


3:自埋坑

在上面「連環坑」中,咱們經過修改/etc/init.d/iptables的腳本配置,stop時候不卸載nf_conntrack模塊,解決不會恢復nf_conntrack默認值的問題。今天就遭此一坑。

咱們線上的中間件服務器的訪問量很是巨大,使用nf_conntrack_max = 1048576參數後,瞬間跑滿。請求沒法到達1.31,按照之前的方法我執行/etc/init.d/iptables stop,而由於我修改了腳本stop的時候,不會移除nf_conntrack模塊,悲劇了。而此時,咱們手動移除modprobe -r nf_conntrack 報錯"模塊正在使用"。。。  情急之下我卸載了iptables, 模塊依舊存在,因而修改了內核參數:net.nf_conntrack_max = 10485760 剛開始正常,過一會,機器直接重啓。。。

如此看來,修改/etc/init.d/iptables 中的NF_MODULES_COMMON選項是不正確的,這樣會致使出問題的時候,你執行/etc/init.d/iptables stop都不會好轉。咱們必須想別的途徑。


咱們分析iptables啓動過程:

執行iptables start --->啓動nf_conntrack模塊 ---> 應用iptables策略。

執行iptables stop --->卸載nf_conntrack模塊(sysctl的nf_conntrack 選項恢復默認值)--->中止iptables 進程 


咱們以前的解決方案是:

執行iptables start --->啓動nf_conntrack模塊 ---> 應用iptables策略。

執行iptables stop --->中止iptables 進程  (不卸載nf_conntrack)



最後的解決方案:

執行iptables stop --->卸載nf_conntrack模塊(sysctl的nf_conntrack 選項恢復默認值)--->中止iptables 進程 

執行iptables start --->啓動nf_conntrack模塊 (加載/etc/sysctl中的配置)---> 應用iptables策略。


方法是:

sed -ri 's/IPTABLES_SYSCTL_LOAD_LIST=.*/IPTABLES_SYSCTL_LOAD_LIST="net.nf_conntrack"/g' /etc/init.d/iptables


最後,奉勸諸位同窗,對於大流量大併發的機器。放棄對nf_conntrack的引用纔是正解。當kenel的nf_conntrack參數的值設置不合理當執行/etc/init.d/iptables stop時候直接會致使機器重啓,介,我親身經歷過!


方法一:刪除鏈接跟蹤模塊`lsmod | grep nf_conntrack`,不使用鏈接狀態的跟蹤功能。

rmmod nf_conntrack_ipv4 
rmmod nf_conntrack_ipv6 
rmmod xt_state 
rmmod xt_CT 
rmmod xt_conntrack 
rmmod iptable_nat 
rmmod ipt_REDIRECT 
rmmod nf_nat 
rmmod nf_conntrack


# 禁用 nf_conntrack 模塊 
blacklist nf_conntrack 
blacklist nf_conntrack_ipv6 
blacklist xt_conntrack 
blacklist nf_conntrack_ftp 
blacklist xt_state 
blacklist iptable_nat 
blacklist ipt_REDIRECT 
blacklist nf_nat 
blacklist nf_conntrack_ipv4


方法二:

使用祼表,添加「不跟蹤」標識。


iptables -t raw -A PREROUTING -p tcp -m tcp --dport 8983 -j NOTRACK

iptables -t raw -A OUTPUT -p tcp -m tcp --sport 8983 -j NOTRACK

iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 8983 -j ACCEPT

iptables -A INPUT -m state --state RELATED,ESTABLISHED,UNTRACKED -j ACCEPT

或者,直接將全部訪問,忽略跟蹤:

iptables -t raw -A PREROUTING -p tcp -j NOTRACK

iptables -t raw -A PREROUTING -p udp -j NOTRACK

iptables -t raw -A OUTPUT -p tcp -j NOTRACK

iptables -t raw -A OUTPUT -p udp -j NOTRACK


參考:

http://my.oschina.net/kisops/blog/150995

相關文章
相關標籤/搜索