上一篇博文咱們講到了iptables的一些經常使用的擴展匹配模塊以及擴展模塊的一些選項的說明,回顧請參考http://www.javashuo.com/article/p-wnalgzdi-eu.html;今天再來講說剩下的幾個比較長用的擴展模塊。html
一、limit,此模塊主要是基於收發報文段速率來作匹配,通俗的將就是來控制訪問速率的。其原理是用的令牌桶算法,具體以下圖算法
提示:從圖上大概能夠了解到它的基本流程,首先令牌桶在第一次會生成必定數量的令牌,而後用戶要訪問服務器,須要從令牌桶裏拿令牌才能夠訪問,這個令牌桶有個特色,就是若是令牌桶裏的令牌是滿的,它就不會生成新的令牌,若是令牌桶裏的令牌不是滿的,它會以必定速率的向令牌桶裏放令牌,這個放令牌的速度是一個恆定的值,它不取決於令牌用的速度,即使令牌桶空了,它也是必定時間生成必定量的令牌來往裏生成令牌;若是令牌桶裏的令牌沒有了,這時又有新的請求,那麼沒有拿到令牌的請求將會丟棄,不予處理其請求。這樣一種控制速率的機制,它有個特色就是在最開始的請求中,也就是令牌桶是滿的狀態,可能存在短期的瘋搶令牌狀況,由於令牌桶裏有足夠的令牌,使得來的一大波請求都可以拿到令牌。但這種狀況通常只是短期的,不會太長久,隨後它會趨於必定速率的處理請求。bash
瞭解了令牌桶控制速率的機制,咱們就不難理解下面的limit模塊的選項了服務器
--limit # [/second|/minute/hour|/day] ,次選項用於指定其生成令牌的速率cookie
--limit-burst number ,此選項用於指定令牌桶裏可以存放的令牌數量,也就是桶的大小app
示例:容許全部主機ping 192.168.0.99 ,令牌桶裏的令牌最大容量爲5個,生成令牌的速率是每分鐘生成10,來控制客戶端ping服務端tcp
[root@test ~]# iptables -F [root@test ~]# iptables -nvL Chain INPUT (policy ACCEPT 6 packets, 396 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 4 packets, 384 bytes) pkts bytes target prot opt in out source destination [root@test ~]# iptables -A INPUT -d 192.168.0.99 -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT [root@test ~]# iptables -A INPUT -d 192.168.0.99 -p icmp -j DROP [root@test ~]# iptables -nvL Chain INPUT (policy ACCEPT 19 packets, 1332 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT icmp -- * * 0.0.0.0/0 192.168.0.99 icmptype 8 limit: avg 10/min burst 5 0 0 DROP icmp -- * * 0.0.0.0/0 192.168.0.99 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 13 packets, 1212 bytes) pkts bytes target prot opt in out source destination [root@test ~]#
提示:本人之因此要加一條拒絕全部icmp的請求規則,是由於個人INPUT鏈默認策略是ACCEPT,若是默認規則是REJECT或者DROP 是能夠不用加第二條規則ide
測試:用客戶端ping 192.168.0.99看看其回覆報文有什麼特色,是否是起到了控制速率的效果工具
提示:咱們從上面測試結果能夠看到,ping請求的迴應包序號,最開始它是順序的,過了5個包後,基本上就是6秒一個迴應包,這裏的緣由就像咱們上面說的,最開始令牌桶裏有5個令牌,一開始請求的時候,請求報文可以拿到令牌,過一段時間後,令牌桶裏的令牌不足了,因此在令牌生成的這一段時間裏的請求報文,防火牆是匹配到第二條規則裏,因此給拒絕掉了,當令牌桶裏有新的令牌時,去請求的報文就能夠拿到一個令牌,從而獲得響應報文,因此咱們看到的響應報文,也是基於令牌生成的速率來的。這就是爲何咱們看到的迴應報文序列號 是每隔6秒有一個迴應包的緣由。性能
二、state擴展
state模塊是根據鏈接追蹤機制去檢查鏈接的狀態,使用這個模塊去匹配報文時比較消耗防火牆資源的,由於防火牆要在其內存維護一張鏈接追蹤表,這個表記錄着請求本機和響應之間的關係。每檢查一次請求報文,它都會去這個表裏看一看,是否是以前來過的,基於某一狀態來追蹤報文的合法性。
state狀態有以下幾種:
NEW:這種狀態表示新發出的請求報文;鏈接追蹤信息表中不存在此連接的相關信息條目,所以會識別成第一次發出的請求;
ESTABLISHED:此狀態表示,NEW狀態以後,鏈接追蹤信息表中爲其創建的條目失效以前期間內所進行的通訊狀態
RELATED:此狀態表示新發起的請求,但與已鏈接相關聯的鏈接,好比FTP協議的數據鏈接與命令鏈接之間的關係
INVALID:此狀態表示無效的鏈接,如flag標記不正確的鏈接
UNTRACKED:此狀態表示未進行追蹤的鏈接,如raw表中關閉追蹤的鏈接
[!] --state state,此選項表示指定其鏈接追蹤狀態,這個選項指定的值就是上面幾種狀態的一種或多種。
示例:在INPUT鏈上添加對其指定端口的指定狀態鏈接給予放行
[root@test ~]# iptables -F [root@test ~]# iptables -nvL Chain INPUT (policy ACCEPT 9 packets, 620 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 6 packets, 712 bytes) pkts bytes target prot opt in out source destination [root@test ~]# iptables -A INPUT -p tcp -m multiport --dports 23,41319 -m state --state NEW,ESTABLISHED -j ACCEPT [root@test ~]# iptables -A INPUT -j DROP [root@test ~]# iptables -A OUTPUT -p tcp -m multiport --sports 23,41319 -m state --state ESTABLISHED -j ACCEPT [root@test ~]# iptables -A OUTPUT -j DROP [root@test ~]# iptables -nvL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 364 27040 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 23,41319 state NEW,ESTABLISHED 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 59 5460 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport sports 23,41319 state ESTABLISHED 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 [root@test ~]#
提示:以上規則表示放行INPUT鏈上鍊接狀態爲NEW,ESTABLISHED的鏈接,在OUTPUT鏈上容許放行狀態爲ESTABLISHED的鏈接
測試:用客戶端去鏈接服務器
提示:能夠看到咱們用客戶端去鏈接服務端是沒有問題的。
提示:在服務端查看防火牆規則,也看到了對應的規則上匹配到了響應的數據報文
在服務端咱們能夠查看/proc/net/conntrack文件,這個文件中就是咱們說到的鏈接追蹤信息表
[root@test ~]# cat /proc/net/nf_conntrack ipv4 2 tcp 6 299 ESTABLISHED src=192.168.0.232 dst=192.168.0.99 sport=8004 dport=41319 src=192.168.0.99 dst=192.168.0.232 sport=41319 dport=8004 [ASSURED] mark=0 zone=0 use=2 ipv4 2 tcp 6 431993 ESTABLISHED src=192.168.0.151 dst=192.168.0.99 sport=39715 dport=23 src=192.168.0.99 dst=192.168.0.151 sport=23 dport=39715 [ASSURED] mark=0 zone=0 use=2 ipv4 2 tcp 6 235 ESTABLISHED src=192.168.0.99 dst=192.168.0.99 sport=36426 dport=3306 src=192.168.0.99 dst=192.168.0.99 sport=3306 dport=36426 [ASSURED] mark=0 zone=0 use=2 [root@test ~]#
提示:能夠看到咱們指定放行的狀態鏈接的主機信息都在裏面。咱們前面說過這個鏈接追蹤信息表它是有大小和時效的,咱們怎麼看本機的鏈接追蹤最大值和失效呢,在/proc/sys/net/nf_conntrack_max 文件中就記錄了最大鏈接追蹤的條目個數,在/proc/sys/net/netfilter/這個目錄裏就定義了各類協議的鏈接追蹤時長,接下來咱們來看看這些文件
[root@test ~]# cat /proc/sys/net/nf_conntrack_max 65536 [root@test ~]# ls /proc/sys/net/netfilter/ nf_conntrack_acct nf_conntrack_helper nf_conntrack_tcp_timeout_close nf_conntrack_buckets nf_conntrack_icmp_timeout nf_conntrack_tcp_timeout_close_wait nf_conntrack_checksum nf_conntrack_log_invalid nf_conntrack_tcp_timeout_established nf_conntrack_count nf_conntrack_max nf_conntrack_tcp_timeout_fin_wait nf_conntrack_dccp_loose nf_conntrack_sctp_timeout_closed nf_conntrack_tcp_timeout_last_ack nf_conntrack_dccp_timeout_closereq nf_conntrack_sctp_timeout_cookie_echoed nf_conntrack_tcp_timeout_max_retrans nf_conntrack_dccp_timeout_closing nf_conntrack_sctp_timeout_cookie_wait nf_conntrack_tcp_timeout_syn_recv nf_conntrack_dccp_timeout_open nf_conntrack_sctp_timeout_established nf_conntrack_tcp_timeout_syn_sent nf_conntrack_dccp_timeout_partopen nf_conntrack_sctp_timeout_heartbeat_acked nf_conntrack_tcp_timeout_time_wait nf_conntrack_dccp_timeout_request nf_conntrack_sctp_timeout_heartbeat_sent nf_conntrack_tcp_timeout_unacknowledged nf_conntrack_dccp_timeout_respond nf_conntrack_sctp_timeout_shutdown_ack_sent nf_conntrack_timestamp nf_conntrack_dccp_timeout_timewait nf_conntrack_sctp_timeout_shutdown_recd nf_conntrack_udp_timeout nf_conntrack_events nf_conntrack_sctp_timeout_shutdown_sent nf_conntrack_udp_timeout_stream nf_conntrack_events_retry_timeout nf_conntrack_tcp_be_liberal nf_log nf_conntrack_expect_max nf_conntrack_tcp_loose nf_log_all_netns nf_conntrack_generic_timeout nf_conntrack_tcp_max_retrans [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_icmp_timeout 30 [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_udp_timeout 30 [root@test ~]#
提示:能夠看到/proc/sys/net/netfilter/這個目錄下的文件都記錄了對應協議的超時時間。而/proc/sys/net/nf_conntrack_max這個文件中記錄了鏈接追蹤表裏最大記錄鏈接追蹤信息的條目個數。咱們能夠經過修改對應的文件來調節鏈接追蹤表的大小和個協議失效時長。
iptables的鏈接追蹤表最大容量由/proc/sys/net/nf_conntrack_max文件中定義,各類狀態的鏈接超時後會從鏈接追蹤表中刪除;當鏈接追蹤表滿了,後續的鏈接可能會超時,這個時候咱們有兩種解決辦法:第一個就是加大鏈接追蹤表容量,前提是咱們要有足夠的內存去存這個鏈接追蹤表;其次咱們還能夠把各個狀態的超時下降,讓其鏈接追蹤表裏的條目可以很快的騰出空間來記錄新的狀態的鏈接追蹤信息
一、加大nf_conntrack_max值
編輯/etc/sysctl.conf 把以下內容添加到該文件中,而後保存
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216
固然後面的值能夠根據狀況本身定義一個合適大小的值
[root@test ~]# cat /etc/sysctl.conf # sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). net.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_max = 393216 [root@test ~]# sysctl -p net.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_max = 393216 [root@test ~]# cat /proc/sys/net/nf_conntrack_max 393216 [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_max 393216 [root@test ~]#
提示:固然把對應的值寫到文件中是永久更改的方式,也就是下一次從新開機,這個值不會變。若是想臨時測試下,咱們能夠用echo 命令 echo 一個值到/proc/sys/net/nf_conntrack_max文件中便可
二、下降 nf_conntrack timeout時間
編輯/etc/sysctl.conf 把如下內容寫入其中,而後保存
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 1
[root@test ~]# cat /etc/sysctl.conf # sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). net.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_tcp_timeout_established = 300 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 1 [root@test ~]# sysctl -p net.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_tcp_timeout_established = 300 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 1 [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established 300 [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait 120 [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait 60 [root@test ~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_fin_wait 1 [root@test ~]#
提示:咱們把對應的參數和值寫到/etc/sysctl.conf文件中,而後用sysctl -p 去重讀配置文件,讓其對應的文件中的值發生變化。這種方式是修改內核參數常規的方式。一樣咱們只是想測試下,不想永久的修改,能夠選擇用echo命令往對應文件中寫入對應的值
開放被動模式的ftp服務
衆所周知ftp被動模式下,其數據端口是隨機的,也就是說咱們在防火牆上配置是至關麻煩的,能夠說無法用匹配端口的方式去配置防火牆,咱們須要用到鏈接追蹤功能,咱們知道FTP 的數據端口是經過命令端口21去協商出來的一個端口,客戶端和服務端協商好一個隨機端口,而後開始傳輸數據,在防火牆上咱們須要配置只要和21號端口有關聯的咱們都給開放,這樣一來咱們防火牆匹配報文就能夠匹配到和21號端口相關的數據端口,從而實現放行FTP數據端口的目的。默認狀況下Linux系統默認裝載的鏈接追蹤模塊對於FTP是不生效的,針對FTP鏈接追蹤咱們須要從新加載專用的鏈接追蹤模塊nf_conntrack_ftp 接下來咱們來看看系統是否有這個模塊。
[root@test ~]# ls /lib/modules/3.10.0-693.el7.x86_64/kernel/net/netfilter/|grep -E *.ftp nf_conntrack_ftp.ko.xz nf_conntrack_tftp.ko.xz nf_nat_ftp.ko.xz nf_nat_tftp.ko.xz [root@test ~]#
提示:能夠看到咱們內核模塊目錄裏有nf_conntrack_ftp這個模塊。有這個模塊但不必定裝載了,接下來還要檢查系統是否轉載了
[root@test ~]# lsmod |grep -E *.ftp [root@test ~]#
提示:能夠看到系統沒有裝載任何和FTP有關的模塊
[root@test ~]# modprobe nf_conntrack_ftp [root@test ~]# lsmod |grep -E *.ftp nf_conntrack_ftp 18638 0 nf_conntrack 137239 9 ip_vs,nf_nat,xt_connlimit,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ftp,nf_conntrack_ipv4 [root@test ~]#
提示:modprobe命令是用來裝載指定模塊的,這種方式是臨時裝載,若是咱們重啓系統後,這個模塊它不會從新去裝載,要想開機自動裝載對應的模塊,咱們能夠選擇把要裝載的模塊名稱寫到/etc/sysconfig/iptables-config配置文件中,以下所示
[root@test ~]# head /etc/sysconfig/iptables-config # Load additional iptables modules (nat helpers) # Default: -none- # Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which # are loaded after the firewall rules are applied. Options for the helpers are # stored in /etc/modprobe.conf. IPTABLES_MODULES="nf_conntrack_ftp" # Unload modules on restart and stop # Value: yes|no, default: yes # This option has to be 'yes' to get to a sane state for a firewall [root@test ~]#
提示:若是有多個模塊須要加載,能夠用空格把多個模塊名稱隔開
加載了專用的模塊後,咱們就能夠寫防火牆規則,來放行被動模式下的FTP
測試:在寫規則前,咱們先測試下,FTP是否可以經過客戶端訪問
提示:防火牆INPUT和OUTPUT鏈上默認規則是DROP,而後對應的規則上沒有開放其21號端口,因此咱們用客戶端鏈接21號端口是無法鏈接的,接下來咱們在防火牆上配置規則,放行其21號端口的報文
[root@test ~]# iptables -P INPUT ACCEPT [root@test ~]# iptables -P OUTPUT ACCEPT [root@test ~]# iptables -F [root@test ~]# iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT [root@test ~]# iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT [root@test ~]# iptables -A INPUT -p tcp -m multiport --dports 21,41319 -m state --state NEW -j ACCEPT [root@test ~]# iptables -P INPUT DROP [root@test ~]# iptables -P OUTPUT DROP [root@test ~]# iptables -nvL Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 412 29132 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 21,41319 state NEW Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 165 15340 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED [root@test ~]#
提示:咱們把INPUT和OUTPUT鏈上的默認規則配置成ACCEPT,而後在清楚以前配置的規則,而後在INPUT鏈上容許放行狀態爲ESTABLISHED和RELATED的報文,在OUTPUT鏈上容許放行狀態爲ESTABLISHED的數據報文,而後在INPUT鏈上放行21號端口和SSH鏈接端口的狀態爲NEW的數據報文,最後咱們把INPUT和OUTPUT鏈上的默認策略更改成DROP,這樣配置後,在OUTPUT鏈上,只要報文狀態是ESTABLISHED的都給予放行處理,在INPUT鏈上,若是是請求的目標端口是21號且狀態爲NEW的都給予放行,這樣一來首先客戶端登陸FTP是沒有問題的,其次是數據鏈鋸,在INPUT鏈上咱們配置了狀態爲RELATED的數據報文是容許放行,這樣一來FTP的數據鏈路應該是沒有問題。接下來咱們在客戶端鏈接FTP服務器,看看其數據鏈路的報文是否都被容許了
測試:在客戶端用FTP工具鏈接FTP服務器,看看其數據鏈路是否超時
提示:能夠看到在客戶端鏈接FTP服務器是能夠正常的登陸和下載文件,充分說明了咱們配置的防火牆規則是沒有問題的
提示:在服務端咱們也能夠看到INPUT鏈上的第二條規則就匹配到4個包,而其餘規則匹配了大量的包,爲何第二條規則匹配的報文這麼少呢?這時由於第二條規則只有新客戶端最開始去鏈接FTP服務器時 它才能匹配獲得,後續的報文狀態要麼是ESTABLISHED的狀態,要麼是RELATED狀態的報文。因此在INPUT和OUTPUT鏈上的第一條規則至關於一個萬能的規則,只要其狀態符合通行的條件報文就能夠經過。有了state這個擴展模塊,咱們發現咱們寫的規則能夠大大的減小不少,不少規則能夠用一條就能夠代替。這裏還須要注意一點的是,用state擴展匹配條件,對服務器的性能有影響,咱們在使用state模塊的功能的同時,還須要考慮它服務器的性能。