安全的Web主機iptables防火牆指令碼

餘二五發表於2017-11-16

下面以自己的Web伺服器舉例說明之,系統的預設策略是INPUT為DROP,OUTPUT、FORWARD鏈為ACCEPT,DROP設定得比較寬鬆,因為我們知道出去的資料包比較安全;為了驗證指令碼的通用性,我特的檢視了伺服器的核心及iptables版本,命令如下所示:

1
2
3
4
5
6
7
8
9
10
uname -a
Linux ud50041 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:54:53 EST 2006 i686 i686 i386 GNU/Linux
iptables -V
iptables v1.2.11
lsb_release -a
LSB Version:    :core-3.0-ia32:core-3.0-noarch:graphics-3.0-ia32:graphics-3.0-noarch
Distributor ID:    RedHatEnterpriseAS
Description:    Red Hat Enterprise Linux AS release 4 (Nahant Update 3)
Release:    4
Codename:    NahantUpdate3

大家可以發現,此係統為RHEL4_i386系統,系統核心版本為2.6.9-34,iptables版本為1.2.11;另外我在別的Centos5.5 x86_64機器上也成功部署了此指令碼;由於後續的recent安全模組對系統核心有要求(這個作為主機防護指令碼也經常用到),如果大家要採用iptables作為主機防火牆時,建議用Centos5.6 x86_64或更高階版本,不然系統會有如下提示錯誤資訊:

1
2
3
4
5
iptables: Unknown error 18446744073709551615
iptables:Invalid argument
tail -f /var/log/messages時能發下面的的出錯提示
ip_tables: connlimit match: invalid size 32 != 16
ip_tables: connlimit match: invalid size 32 != 24

另外,在生產環境下除錯iptables指令碼前,強烈建議編寫crontab任務,每5分鐘關閉一次iptalbes指令碼,防止將SSH客戶端鎖在外面,命令如下所示:

1
*/5 * * * * root /etc/init.d/iptables stop

指令碼程式碼如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
iptables -F
iptables -F -t nat
iptables -X
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
#load connection-tracking modules
modprobe iptable_nat
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
iptables -A INPUT -f -m limit --limit 100/sec --limit-burst 100 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 10 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 20/sec --limit-burst 200 -j ACCEPT
iptables -A INPUT -s 122.70.x.x -j ACCEPT
iptables -A INPUT -s 122.70.x.x -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 80,22 -j ACCEPT

這裡有一種特殊情況,由於此Web伺服器是置於負載均衡器後面,所以與負載均衡器的連線還是很頻繁的;所以我們要允許資料來源地址為負載均衡器的資料包通過;另外,我的許多基於LNMP的小網站上面也部署了此指令碼,即Web服務和MySQL資料庫同時安裝在一臺機器上,也沒有開放3306埠,這個靠Web呼叫PHP程式實現訪問。

成功執行此指令碼後系統應該是不會報錯的,命令如下:

1
iptables -nv –L

此命令顯示結果如下(此為另一臺LNMP機器的指令碼顯示結果):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Chain INPUT (policy DROP 610 packets, 50967 bytes)
 pkts bytes target     prot opt in     out     source               destination      
    0     0 ACCEPT     all  -f  *      *       0.0.0.0/0            0.0.0.0/0           limit: avg 100/sec burst 100
 6100  314K ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp flags:0x16/0x02 limit: avg 20/sec burst 200
 1052 67637 ACCEPT     all  --  *      *       122.70.x.x        0.0.0.0/0        
  986 58112 ACCEPT     all  --  *      *       122.70.x.x        0.0.0.0/0        
  918  131K ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0        
97056   12M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
 4325  218K ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           multiport dports 80,22
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination      
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 8 limit: avg 1/sec burst 10
Chain OUTPUT (policy ACCEPT 144K packets, 155M bytes)
 pkts bytes target     prot opt in     out     source               destination      
  956  134K ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0

下面我稍為詳細的解釋下此指令碼:

在主機的防護上我們配置了一些安全措施,以防止外部的ping和SYN洪水攻擊,並且考慮到外部的瘋狂埠掃描軟體可能會影響伺服器的入口頻寬,所以在這裡也做了限制。命令如下所示:

1
iptables -A INPUT -p tcp --syn -m limit --limit 100/s --limit-burst 100 -j  ACCEPT

上面的命令每秒鐘最多允許100個新連線,請注意這裡的新連線指的是state為New的資料包,在後面我們也配置了允許狀態為ESTABLISHED和RELATED的資料通過;另外,100這個閥值則要根據伺服器的實際情況來調整,如果是併發量不大的伺服器這個數值就要調小,如果是訪問量非常大且併發數不小的伺服器,這個值則還需要調大。再看以下命令: 

1
2
3
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s –limit-burst 10 -j ACCEPT
這是為了防止ping洪水攻擊,限制每秒的ping包不超過10個。
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 20/sec --limit-burst 200 -j ACCEPT

上面的命令防止各種埠掃描,將SYN及ACK SYN限制為每秒鐘不超過200個,免得把數務器頻寬耗盡了。
iptables防火牆執行後,我們可以執行nmap工具進行掃描,命令如下:

1
nmap -P0 -sS 211.143.6.x

此命令的執行結果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2009-03-29 16:21 CST
Interesting ports on 211.143.6.X:
Not shown: 1668 closed ports
PORT     STATE SERVICE
22/tcp open   ssh
25/tcp open   smtp
80/tcp open   http
110/tcp   open   pop3
111/tcp   open   rpcbind
143/tcp   open   imap
443/tcp   open   https
465/tcp   open   smtps
587/tcp   open   submission
993/tcp   open   imaps
995/tcp   open   pop3s
1014/tcp open   unknown

在這裡,我們發現一個1014端被某個程式開啟了,用lsof -i:1014檢視發現又是rpc.statd開啟的,這服務每次用的埠都不一樣啊!本來想置之不理的,但是如果rpc.statd不能正確處理SIGPID訊號,遠端攻擊者可利用這個漏洞關閉程式,進行拒絕服務攻擊,所以還是得想辦法解決掉,我們發現rpc.statd是由服務nfslock開啟的,進一步查詢得知它是一個可選的程式,它允許NFS客戶端在伺服器上對檔案加鎖。這個程式對應於nfslock服務,於是我們關掉了此服務,命令如下所示:

1
2
service nfslock stop
chkconfig nfslock off

如果沒有硬體防火牆保護的話,置於IDC機房並且有公網的Web伺服器還是很有用iptables保護的必要,如果發現有人用工具惡意頻繁連線我們的Web伺服器,我們可以呼叫recent模組來阻止它們,我們的做法是:儘量在每一臺有公網IP的機器上部署iptables防火牆。

本文轉自 撫琴煮酒 51CTO部落格,原文連結:http://blog.51cto.com/yuhongchun/716016,如需轉載請自行聯絡原作者


相關文章