
上一篇博文我們講到了iptables的一些常用的擴充比對子產品以及擴充子產品的一些選項的說明,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/12273755.html;今天再來說說剩下的幾個比較常用的擴充子產品。
1、limit,此子產品主要是基于收發封包的速率來做比對,通俗的講就是來控制通路速率的。其原理是用的令牌桶算法,具體如下圖
上一篇博文我們講到了iptables的一些常用的擴充比對子產品以及擴充子產品的一些選項的說明,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/12273755.html;今天再來說說剩下的幾個比較常用的擴充子產品。
提示:從圖上大概可以了解到它的基本流程,首先令牌桶在第一次會生成一定數量的令牌,然後使用者要通路伺服器需要從令牌桶裡拿令牌才可以通路,這個令牌桶有個特點,就是如果令牌桶裡的令牌是滿的,它就不會生成新的令牌,如果令牌桶裡的令牌不是滿的,它會以一定速率的向令牌桶裡放令牌,這個放令牌的速度是一個恒定的值,它不取決于令牌用的速度,即便令牌桶空了,它也是一定時間生成一定量的令牌來往裡生成令牌;如果令牌桶裡的令牌沒有了,這時又有新的請求,那麼沒有拿到令牌的請求将會丢棄,不予處理其請求。這樣一種控制速率的機制,它有個特點就是在最開始的請求中,也就是令牌桶是滿的狀态,可能存在短時間的瘋搶令牌情況,因為令牌桶裡有足夠的令牌,使得來的一大波請求都能夠拿到令牌。但這種情況一般隻是短時間的,不會太長久,随後它會趨于一定速率的處理請求。
了解了令牌桶控制速率的機制,我們就不難了解下面的limit子產品的選項了
--limit # [/second|/minute/hour|/day] ,次選項用于指定其生成令牌的速率
--limit-burst number ,此選項用于指定令牌桶裡能夠存放的令牌數量,也就是桶的大小
示例:允許所有主機ping 192.168.0.99 ,令牌桶裡的令牌最大容量為5個,生成令牌的速率是每分鐘生成10,來控制用戶端ping服務端
[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 是可以不用加第二條規則
測試:用用戶端ping 192.168.0.99看看其回複封包有什麼特點,是不是起到了控制速率的效果
提示:我們從上面測試結果可以看到,ping請求的回應包序号,最開始它是順序的,過了5個包後,基本上就是6秒一個回應包,這裡的原因就像我們上面說的,最開始令牌桶裡有5個令牌,一開始請求的時候,請求封包能夠拿到令牌,過一段時間後,令牌桶裡的令牌不足了,是以在令牌生成的這一段時間裡的請求封包,防火牆是比對到第二條規則裡,是以給拒絕掉了,當令牌桶裡有新的令牌時,去請求的封包就可以拿到一個令牌,進而得到響應封包,是以我們看到的響應封包,也是基于令牌生成的速率來的。這就是為什麼我們看到的回應封包序列号 是每隔6秒有一個回應包的原因。
2、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檔案中定義,各種狀态的連接配接逾時後會從連接配接追蹤表中删除;當連接配接追蹤表滿了,後續的連接配接可能會逾時,這個時候我們有兩種解決辦法:第一個就是加大連接配接追蹤表容量,前提是我們要有足夠的記憶體去存這個連接配接追蹤表;其次我們還可以把各個狀态的逾時降低,讓其連接配接追蹤表裡的條目能夠很快的騰出空間來記錄新的狀态的連接配接追蹤資訊
1、加大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檔案中即可
2、降低 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子產品的功能的同時,還需要考慮它伺服器的性能。
作者:Linux-1874
出處:https://www.cnblogs.com/qiuhom-1874/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.