iptables的連接跟蹤表最大容量爲/proc/sys/net/ipv4/ip_conntrack_max(有的地方可能叫nf_conntrack_max),連接碰到各類狀態的超時後就會從表中刪除。node
因此解決方法通常有兩個:linux
(1)、加大 ip_conntrack_max 值web
vi /etc/sysctl.conf net.ipv4.ip_conntrack_max = 393216 net.ipv4.netfilter.ip_conntrack_max = 393216
(2)、下降 ip_conntrack timeout時間服務器
vi /etc/sysctl.conf net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300 net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120 net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60 net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120
iptables -t nat -L -n
練習:INPUT和OUTPUT默認策略爲DROP;網絡
一、限制本地主機的web服務器在週一不容許訪問;新請求的速率不能超過100個每秒;web服務器包含了admin字符串的頁面不容許訪問;web服務器僅容許響應報文離開本機;併發
二、在工做時間,即週一到週五的8:30-18:00,開放本機的ftp服務給172.16.0.0網絡中的主機訪問;數據下載請求的次數每分鐘不得超過5個;app
三、開放本機的ssh服務給172.16.x.1-172.16.x.100中的主機,x爲你的座位號,新請求創建的速率一分鐘不得超過2個;僅容許響應報文經過其服務端口離開本機;框架
四、拒絕TCP標誌位所有爲1及所有爲0的報文訪問本機;ssh
五、容許本機ping別的主機;但不開放別的主機ping本機;tcp
練習:判斷下述規則的意義:
# iptables -N clean_in(自定義規則鏈) # iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP # iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP # iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP(拒絕非法(多是別人通過巧妙假裝的視圖發起攻擊的)報文) # iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP # iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP # iptables -A clean_in -d 172.16.100.7 -j RETURN (調用自定義規則鏈並從自定義規則鏈中返回的) # iptables -A INPUT -d 172.16.100.7 -j clean_in # iptables -A INPUT -i lo -j ACCEPT # iptables -A OUTPUT -o lo -j ACCEPT # iptables -A INPUT -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP # iptables -A INPUT -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP # iptables -A INPUT -i eth0 -p udp --dport 1026 -j DROP # iptables -A INPUT -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP # iptables -A INPUT -p icmp -m limit --limit 10/second -j ACCEPT
補充:利用iptables的recent模塊來抵禦DOS攻擊: 22,創建一個列表,保存有全部訪問過指定的服務的客戶端IP;
recent模塊可以實現對於某一個服務的請求頻率知足之後作後續拒絕一段時間訪問的;
ssh: 遠程鏈接:
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
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.利用connlimit模塊將單IP的併發設置爲3;會誤殺使用NAT上網的用戶,能夠根據實際狀況增大該值;
2.利用recent和state模塊限制單IP在300s內只能與本機創建2個新鏈接。被限制五分鐘後便可恢復訪問。
下面對最後兩句作一個說明:
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"
(學習向內核打補丁編譯使用)
iptables直接訪問應用層協議,根據應用層協議作控制,好比訪問http協議沒有問題,可是訪問ftp協議就拒絕。再好比qq協議就拒絕。
模塊:layer7
用於識別應用層協議;
注意:layer7是一個擴展,不過這個擴展iptables沒有自帶,因此要想實現七層訪問過濾,得爲iptables補上layer7這一模塊,而layer7模塊須要內核的netfilter框架的支持也須要用戶空間iptables命令在寫規則能支持,因此若是咱們要想使用layer7,第一,得對內核打補丁,從新編譯升級內核;第二,得對iptables打補丁,從新編譯升級iptables。layer7提供的補丁包只適用於較老版本的內核和較老版本的iptables,因此從互聯網上直接下載的補丁包用起來可能會有必定的問題。
iptables/netfilter
iptables -m state,
netfilter state
對內核中的netfilter,打補丁layer7,從新編譯內核
對iptables打補丁,補上layer7模塊,從新iptables
diff/patch:文本操做工具
diff是Unix系統的一個很重要的工具程序。它用來比較兩個文本文件的差別,是代碼版本管理的核心工具之一。其用法很是簡單:
diff <變更前的文件> <變更後的文件>
因爲歷史緣由,diff有三種格式:
* 正常格式(normal diff)
* 上下文格式(context diff)
* 合併格式(unified diff)
一、正常格式的diff
例如,對file1(變更前的文件)和file2(變更後的文件)進行比較可以使用以下命令:
diff file1 file2
顯示結果中,第一行是一個提示,用來講明變更位置。它分紅三個部分:前面的數字,表示file1的第n行有變化;中間的"c"表示變更的模式是內容改變(change),其餘模式還有"增長"(a,表明addition)和"刪除"(d,表明deletion);
二、上下文格式的diff
上個世紀80年代初,加州大學伯克利分校推出BSD版本的Unix時,以爲diff的顯示結果太簡單,最好加入上下文,便於瞭解發生的變更。所以,推出了上下文格式的diff。它的使用方法是加入-c選項(即context)。
diff -c f1 f2
結果分紅四個部分。第一部分的兩行,顯示兩個文件的基本狀況:文件名和時間信息,"***"表示變更前的文件,"---"表示變更後的文件。第二部分是15個星號,將文件的基本狀況與變更內容分割開。第三部分顯示變更前的文件,即file1。
另外,文件內容的每一行最前面,還有一個標記位。若是爲空,表示該行無變化;若是是感嘆號(!),表示該行有改動;若是是減號(-),表示該行被刪除;若是是加號(+),表示該行爲新增。
第四部分顯示變更後的文件,即file2。
三、合併格式的diff
若是兩個文件類似度很高,那麼上下文格式的diff,將顯示大量重複的內容,很浪費空間。1990年,GNU diff率先推出了"合併格式"的diff,將f1和f2的上下文合併在一塊兒顯示。
它的使用方法是加入u參數(表明unified)。
diff -u f1 f2
其結果的第一部分,也是文件的基本信息。"---"表示變更前的文件,"+++"表示變更後的文件。第二部分,變更的位置用兩個@做爲起首和結束。第三部分是變更的具體內容。
除了有變更的那些行之外,也是上下文各顯示3行。它將兩個文件的上下文,合併顯示在一塊兒,因此叫作"合併格式"。每一行最前面的標誌位,空表示無變更,減號表示第一個文件刪除的行,加號表示第二個文件新增的行。
diff
-u
patch
儘管並無指定patch和diff的關係,但一般patch都使用diff的結果來完成打補丁的工做,這和patch自己支持多種diff輸出文件格式有很大關係。patch經過讀入patch命令文件(能夠從標準輸入),對目標文件進行修改。一般先用diff命令比較新老版本,patch命令文件則採用diff的輸出文件,從而保持原版本與新版本一致。
patch的標準格式爲
patch [options] [originalfile] [patchfile]
若是patchfile爲空則從標準輸入讀取patchfile內容;若是originalfile也爲空,則從patchfile(確定來自標準輸入)中讀取須要打補丁的文件名。所以,若是須要修改的是目錄,通常都必須在patchfile中記錄目錄下的各個文件名。絕大多數狀況下,patch都用如下這種簡單的方式使用:
patch命令能夠忽略文件中的冗餘信息,從中取出diff的格式以及所須要patch的文件名,文件名按照diff參數中的"源文件"、"目標文件"以及冗餘信息中的"Index:"行中所指定的文件的順序來決定。
-p參數決定了是否使用讀出的源文件名的前綴目錄信息,不提供-p參數,則忽略全部目錄信息,-p0(或者-p 0)表示使用所有的路徑信息,-p1將忽略第一個"/"之前的目錄,依此類推。如/usr/src/linux-2.4.15/Makefile這樣的文件名,在提供-p3參數時將使用linux-2.4.15/Makefile做爲所要patch的文件。
patch
-p
-R
mockbuild
總結:操做步驟
一、獲取並編譯內核
# useradd mockbuild # rpm -ivh kernel-2.6.32-431.5.1.x86_64.el6.src.rpm # cd rpmbuild/SOURCES # tar linux-2.6.32-*.tar.gz -C /usr/src
# cd /usr/src # ln -sv
二、給內核打補丁
# tar xf netfilter-layer7-v2.23.tar.bz2 # cd /usr/src/linux # patch -p1 < /root/netfilter-layer7-v2.23/kernel-2.6.32-layer7-2.23.patch # cp /boot/config-* .config # make menuconfig
按以下步驟啓用layer7模塊
Networking support → Networking Options →Network packet filtering framework → Core Netfilter Configuration
<M> 「layer7」 match support
三、編譯並安裝內核
# make
# make modules_install
# make install
四、重啓系統,啓用新內核
五、編譯iptables
# tar xf iptables-1.4.20.tar.gz
# cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* /root/iptables-1.4.20/extensions/
# cp /etc/rc.d/init.d/iptales /root
# cp /etc/sysconfig/iptables-config /root
# rpm -e iptables iptables-ipv6 --nodeps
# ./configure --prefix=/usr --with-ksource=/usr/src/linux
# make && make install
# cp /root/iptables /etc/rc.d/init.d
# cp /root/iptables-config /etc/sysconfig
六、爲layer7模塊提供其所識別的協議的特徵碼
# tar zxvf l7-protocols-2009-05-28.tar.gz # cd l7-protocols-2009-05-28 # make install
七、如何使用layer7模塊
ACCT的功能已經能夠在內核參數中按需啓用或禁用。此參數須要裝載nf_conntrack模塊後方能生效。
net.netfilter.nf_conntrack_acct = 1
l7-filter uses the standard iptables extension syntax
# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]
# iptables -A FORWARD -m layer7 --l7proto qq -j REJECT
編譯內核:
make menuconfig
make -j #
make modules_install
make install
清理內核源碼樹:
提示:xt_layer7.ko依賴於nf_conntrack.ko模塊
tcp_wrapper:tcp包裝器
是一個相似於iptables的實現訪問控制工具。可是,只是對基於TCP協議開發並提供服務的應用程序,提供的一層訪問控制工具;
iptables是工做在內核中的,因此只要是一個網絡服務經由經由內核中的TCP/IP協議棧就可以收到netfilter的控制,那tcp_wrapper也須要在用戶請求的報文所必經的路上實現對於某個服務的訪問控制的功能,可是tcp_wrapper不像netfilter是在內核中實現而是基於庫調用來實現其功能的。這就意味着只有那些在開發時不光是TCP協議還必須是基於TCP協議開發提供服務而且在開發時調用了tcp_wrapper相關庫的(這個庫叫libwrap)的應用tcp_wrapper的應用才能生效。
很顯然,tcp_wrapper比起netfilter的適用範圍要窄的多了,那咱們怎麼知道哪個應用程序調用了tcp_wrapper而且支持對於tcp_wrapper進行控制呢?
判斷服務是否可以由tcp_wrapper進行訪問控制:
此前說過,一個程序在開發時若是調用了某個接口,可是它在編譯時卻有兩種方式編譯,第一,動態編譯,第二,靜態編譯。動態編譯表示基於動態連接庫的方式使用庫,靜態編譯表示把調用的庫文件直接編譯進應用程序內部,因此這有兩種情形,它的判斷方式不同:
則表示支持tcp_wrapper控制,不然則表示不支持;
由此,咱們看看系統上有哪些應用程序可以支持這樣的訪問控制機制,以CentOS 7爲例:
先清空iptables規則:
查看sshd是否支持tcp_wrapper規則:
說明它是接受tcp_wrapper控制的。
再看httpd:
未連接至libwrap庫,說明httpd不接受tcp_wrapper控制。
再看vsftpd:
所以它接受tcp_wrapper控制
經過這種方式查看的結果當中,但凡那些連接當中出現了libwrapper的才表示它可以受tcp_wrapper控制。
那麼若是收tcp_wrapper控制,咱們如何實現基於tcp_wrapper對服務作訪問控制呢?其實tcp_wrapper比iptables要簡單太多了,很是容易實現。
要想實現服務訪問控制,它是經過在配置文件中爲各服務分別定義訪問控制規則實現訪問控制:
配置文件:
因此咱們寫在allow或deny文件中就能實現某個服務可以容許可以有哪些客戶端主機進行訪問了,在此直接定義便可。
配置文件語法:
daemon_list(指定是哪個服務,能夠是單個服務也能夠是服務列表,如有多個使用逗號隔開):client_list(容許或拒絕哪些客戶端主機)[:options(其它選項)](此項若是寫在allow文件中表示容許,寫在deny文件中表示拒絕,僅此而已)
若是在兩個文件中寫了同一個條目,事實上,這兩個文件有其檢查次序的概念的。首先咱們檢查hosts.allow,其次纔是hosts.deny,也就是說當一個客戶端來訪問某個服務時,先檢查在allow文件中是否有與之匹配的規則,若是有匹配的規則,就容許訪問即放行。若是allow文件中沒有,則檢查deny文件,若是deny文件中有匹配的,則拒絕訪問,若是hosts.deny也沒有匹配的,那就要取決於默認策略了。
流程大體以下圖所示:
因此說若是咱們僅放行某一個網絡對服務訪問,怎麼辦呢?在allow中allow這個網絡,在deny中deny all便可。因此這就是爲何當前主機上這麼多受libwrap控制的服務默認都沒有拒絕的緣由,由於在這兩個文件中什麼都沒有定義。默認狀況下這兩個文件是空的。那兩個文件是空的就意味着咱們的服務即使是受tcp_wrapper控制它也是被容許的,由於第一個文件匹配第二個文件也沒匹配,那默認是allow的。
能夠看出,上述文件默認都是註釋的,即規則爲空。
接下來,咱們就來試試讓它們來控制服務的訪問了。
咱們先來講一說咱們怎麼在配置文件中去寫這些規則,也就是說咱們給出daemon_list規則的格式是什麼。
daemon_list格式:
必定是應用程序的文件的名字,由於咱們說過它是文件經過連接至libwrap庫文件來完成訪問控制的,因此說應用程序列表中的應用程序給的必須是文件名而不能是服務名,好比咱們要控制named,應用程序叫named而不能寫成DNS;
例如:想要vsftpd和ssh基於一樣法則控制
編寫格式爲:sshd,vsftpd;
ALL表示全部受tcp_wrapper控制的應用程序服務;
client_list格式:
例如:
vsftpd服務不容許192.168.241.1訪問:
注意:這不是一個服務,而是一個庫,而庫在應用程序本身運行時就可能會調用的庫的,所以這也不用重啓任何服務;
192.168.241.6這臺主機上的ftp服務僅容許192.168.241.0網絡訪問的實現:
換一個主機測試:
可是對於telnet服務來講有些特殊:
telnet的服務叫作telnet-server:(在CentOS6上telnet是受超級守護進程控制的,由於超級守護進程是接受tcp_wrapper控制的,因此telnet也受tcp_wrapper控制,但在CentOS7上telnet是做爲一個獨立的進程的,不受tcp_wrapper控制了。所以此處在CentOS 6上實驗)
啓動telnet要先啓動超級守護進程,可是在此以前須要先修改配置文件
它是受xinet.d控制的
改成disable no至關於checkconfig telnet on。
telnet只能使用普通用戶登陸,所以添加用戶:
先在本地鏈接一下:
如今咱們對telnet作訪問控制:
安裝的應用程序名叫in.telnetd。
在本地測試:
再找一臺主機:
這就是如何使用tcp_wrapper來作訪問控制的。
此外,在衆多options中有一個特殊的應用,這種用法就是EXCEPT。
EXCEPT:意爲除了;如在hosts.allow文件中定義:
vsftpd:172.16. EXCEPT 172.16.100.1
表示這個網絡開放給172.16訪問可是這個172.16.100.1不能訪問。另外一個例子:
vsftpd:172.16. EXCEPT 172.16.100.0/255.255.255.0 EXCEPT 172.16.100.1
表示vsftpd開放給172.16.這個網絡,可是不包括172.16.100.0這個網絡,可是又包含172.16.100.1這個主機。
如:
自行測試!
[:options]:
舉例:
/etc/hosts.allow文件中:
vsftpd:192.168.241. :deny
再如,/etc/hosts.allow:
vsftpd:192.168.241. EXCEPT 192.168.241.6 :deny
表示匹配192.168.241.6以外的192.168.241.0網絡中的主機都拒絕(注意:這裏只是不包含192.168.241.6這個主機即未匹配到,這條規則可以匹配到192.168.241.0網絡中的全部主機可是不包含192.168.241.6)。
/etc/hosts.deny:
vsftpd:ALL
(此處拒絕全部,因此剛纔未匹配到的192.168.241.6也被拒絕了,最終的規則表示全部主機都不能訪問)
表示啓動額外應用程序;一旦被匹配到的話它能夠啓動,不作拒絕容許了,意思是你原本是拒絕的文件同樣是拒絕,原本是容許的文件同樣是容許,但額外它還能夠啓動其它應用程序。能夠完成一部分的管理或其它功能。
如在定義某一個服務時,若是說不容許訪問的主機訪問了,或者容許訪問的主機訪問了,均可以將其記錄到日誌裏邊來。
舉例:本地開放了ftp服務,可是不容許任何人訪問,一旦有人訪問了,將其記錄到日誌中:
%c表示client ip,客戶端地址,%s表示server ip,服務器端地址,%d爲daomon name即訪問的是服務器上的哪一個守護進程;
iptables到此就告一段落了,指望把iptables中的網絡防火牆和nat規則當作重點,nat轉換和地址轉換後,哪些容許訪問哪些不容許訪問呢?因此還能夠把filter和nat結合起來使用。因此應該把nat當作重點。