deserts
大客部
级别: 总版主
精华:
0
发帖: 607
威望: 2 点
金钱: 1061 RMB
贡献值: 0 点
在线时间:1761(小时)
注册时间:2006-01-01
最后登录:2025-02-11
|
linux自动屏蔽IP工具
另存为 firewall.sh 给执行的权限 W>s'4C` L[G\+ #!/bin/sh ePpK+E[0Z # this program is used to check tcp/ip connections ba9<(0` # and block those ip with excessive connections ]XGn2U\ =Xjuz:9D~ # my version A]?O&m| myver="1.0RC1" "$IwQ x\hn;i< # wake up every 120s if last check found abuse client W
QLL[{mhS wakeup_time_min=120 0*;9CH=BE ]az}
n(B, # wake up every 300s if last check found no abuse client b#;N!V
X wakeup_time_max=300 UeQ
9G _Q}RElA # rule timeout 3600s 31sgf5 s rule_timeout=3600 Omh&)|Iql KO]?>>5S6 # check port list gqdB!l4 portlist="80" :y-0qzD? _ K+V?-= # max established connection per ip Go+xL/f max_active_conn=8 Ddl% V7 uCP6;~Ns # iptables chain name 1yaIV+_y/ iptables_chain_name="RH-Lokkit-0-50-INPUT" Bx}0E 9 /Ai( # log facility (_&V9vat= log_facility="local0" aC8,Y$>?E` $|cp;~ 1 # Block policy [5p7@6:$u ipchains_block_policy="DENY" [rUh;_b\D iptables_block_policy="REJECT" Xk&F4BJQk< 22Y!u00D # myself Zn<(,e myself=`basename $0` }Uwkef.Q ,+NE:_ mylogger_info() bco[L@6G$ { 5<)gCHa logger -p $log_facility.info -t $myself $@ 2>/dev/null -
l40)^ E} } "x.6W! 2iR:*}5 mylogger_debug() v/aPiFlw { *m| t=9E logger -p $log_facility.debug -t $myself $@ 2>/dev/null g]==!!^<D } i!.I;@ h=K36a) mylogger_notice() w]W`R. { u8<&F`7j logger -p $log_facility.notice -t $myself $@ 2>/dev/null HeT6Dv } Ere?d~8 1Es*=zg dotimeout() }DDVGs[ { TXd5v#_vo mylogger_info "reset firewall when timeout arrives" daA47`+d case "$firewall" in rR,+G%[(=4 ipchains) TbKP8zw{ /etc/init.d/ipchains restart 1>/dev/null 2>/dev/null H)`CncB if [ $? = 0 ] ; then KrdZEi vb mylogger_info "ipchains restarted" 9S:{ else ,>bGbx mylogger_notice "ipchains restart failed" '!j #X_; fi :rz9M@7 ;; p@?7^nIR*u iptables) L,Ao.?j /etc/init.d/iptables restart 1>/dev/null 2>/dev/null S3ab0JM if [ $? = 0 ] ; then !G)mjvEe mylogger_info "iptables restarted" QHHW(InG< else a)3O? Y mylogger_notice "iptables restart failed" _o@(wGeu# fi X+]L-o6I2 ;; ?1GY%- *) 1fz*SIjG mylogger_notice "neither ipchains nor iptables" `ir&]jh.A ;; kZV^F*7 esac fH{9]TU_: 1%$d D
2 } ! (2-(LgA !MZ+-dpK blockclient() G{@C"H[$< { Jt##rVN if [ -z "$1" ] || [ -z "$2" ]; then iP<k1#k mylogger_notice "blockclient() missing client or port to block" j y7 return mND XzT& fi EKqi+T^=F local ip port RY9+ 9i W[@i;f^g ip=$1 k/df(cs
port=$2 FJO"|||Y'| DZ^=*. case "$firewall" in .qSBh
hH\ ipchains) Wm<z?.lS mylogger_notice "blocking $1 to $2 via ipchains" HbNYP/MN3 found=`ipchains -nL | egrep "^$ipchains_block_policy.*[[:space:]]+$ip[[:space:]]+.*[[:space:]]+\->[[:space:]]+$port"` D+f'*| if [ -z "$found" ] ; then G7
1U7 cmd="ipchains -I input 1 -p tcp -s $ip -d 0/0 $port -j $ipchains_block_policy 1>/dev/null 2>/dev/null" CXTt(-FT mylogger_debug "cmd: $cmd" Ee&hG[sx `ipchains -I input 1 -p tcp -s $ip -d 0/0 $port -j $ipchains_block_policy 1>/dev/null 2>/dev/null` '
nMApPl if [ $? != 0 ] ; then p?
;-!TUv mylogger_notice "$cmd call failed" N6h1|_o return (YIhTS
L"] fi
Kaf> new_block=1 gF3TwAr ever_block=1 B]1HS`
*7 else z+jh;!i mylogger_info "$ip already blocked to $port" wa" uFW fi ~uB'3`x ;; qh-[L iptables) \EZ+#3u mylogger_notice "blocking $1 to $2 via iptables" ,*dzJT$k found=`iptables -nL | egrep "^$iptables_block_policy.*[[:space:]]+$ip[[:space:]]+.*[[:space:]]+dpt:$port[[:space:]]+"` \k;U}Te< if [ -z "$found" ] ; then }'lNi^"XL cmd="iptables -I $iptables_chain_name 1 -p tcp -m tcp -s $ip --dport $port -j $iptables_block_policy 1>/dev/null 2>/dev/null" [G
a~%m mylogger_debug "cmd: $cmd" ]c}=5m/ `iptables -I $iptables_chain_name 1 -p tcp -m tcp -s $ip --dport $port -j $iptables_block_policy 1>/dev/null 2>/dev/null` ob'n{T+lZ if [ $? != 0 ] ; then ;W0]66& mylogger_notice "$cmd call failed" MHo1 lrZa+ return =D]
.` fi J='W+=N new_block=1 i&A%"lOI9 ever_block=1 0O~p7D else A:eG5K} mylogger_info "$ip already blocked to $port" J3G
7zu8 fi )r9b:c\ ;; uUG*0Lj *) oEu>}JD mylogger_notice "neither ipchains nor iptables" 0KAj]5nvb ;; ^Dr.DWi{$ esac 6e.v&f7( } F}U5d^!2 JDv-O&] restartservice() $b>}C= gt { :[sOKV i local service TY.FpW if [ -z "$1" ] ; then gi]ZG mylogger_notice "no port given to see which service to be restart"
WJ+>e+ return &[@\f^~ fi S &JJIFftO 7
({=* case "$1" in Bf]$X>d 80) K>1X}ZMdD( service="httpd" hV
P
IHQt ;; ~|lIC !q 25) <\@1Zz@ms service="postfix" ^Y04qeRd ;; :?CQuEv- 110) &Un6ay service="courier-pop3d" :Q@)*kQH ;; G>
\Tbx 21) ?znSx}t service="muddleftpd" [pgZbOIN37 ;; 4nkE IZ 53) 7@~tVxB; service="named" fSA)G$b] ;; 61_f3S(u 3306) !gP0ndRJ= service="mysqld" [@"wd_f{l ;; )1F<6R esac $%2H6Eg0 if [ ! -z "$service" ] ; then 4MW ]EQ- /etc/init.d/$service restart 1>/dev/null 2>/dev/null Q:MhjkOr} if [ $? = 0 ] ; then 'Qn~H[$/p mylogger_notice "$service restarted" 1u}nm;3 else .ve *Vp mylogger_notice "$service restart failed" z4M1D9iPY fi @Doyt{|T fi $.K?N@(W } -_8*41 7}B docheckport() &ak6zM { )\0F7Z mylogger_info "do check port $1" :q+N&j'3 local port last_client count client total_count R+=a`0_S BWUq%o,@g if [ -z "$1" ] ; then g9mG`f mylogger_notice "docheckport() port not given" '$m
7ft} return hW2.8f$ fi `l]j#qshTm v}uJtBG( port=$1 /"#4T^7& ;vp\YIeX1 clientlist=`netstat -an --tcp| grep ESTABLISHED | awk "{ if ( index(\\$4,\":$port\") ) print \\$5}" | awk -F ':' '{print $1}'|sort` ($!KzxF3 if [ $? != 0 ] ; then ZX.TqvK/r mylogger_notice "netstat call failed" sbsu(Sz+ return H;KDZO9W fi 8X7{vN_3K #echo $clientlist &0v.E"0< # reset new_block f_6`tq m% new_block=0 ZoUfQ!2* count=0 B}(YD;7vJ total_count=0 +]6 EkZO last_client="" J+zqu for client in $clientlist K5KN}sRs" do S `[8TZ
#echo "client is $client" uC3$iY:_e if [ -z "$last_client" ] ; then K.%E=^~q count=$((count+1)) HCu1vjU(] total_count=$((total_count+1)) MMf6QxYf last_client=$client <.<Nw6 else !y),| #7P if [ "$client" = "$last_client" ] ; then YMWy5 \ count=$((count+1)) IP >An8+ total_count=$((total_count+1)) <Z&gAqj 2 else }bHpFe mylogger_debug "$last_client $count connections" ]D%[GO//! if [ $count -ge $max_active_conn ] ; then i2*nYd`K mylogger_notice "client $last_client connection $count >= $max_active_conn" [9L(4F20 blockclient $last_client $port @|^Ch+%@ fi (=X16}n:> count=1 ''6"Xi|5 total_count=$((total_count+1)) r1\.Jz last_client=$client o ).pF">jh fi QZ`<+"a0 fi ZLV~It&) done H(X~=r # check the last client T>z@;5C if [ ! -z "$client" ] ; then gK>Vm9rO count=$((count+1)) pif8/e total_count=$((total_count+1)) P~#jvm! mylogger_debug "$client $count connections" / [19ITZ if [ $count -ge $max_active_conn ] ; then s.~SV"
mylogger_notice "client $client connection $count >= $max_active_conn" kju:/kYA blockclient $client $port @@$
_TaI fi cD>o(#x] fi ANNL7Z3C mylogger_info "total connections on port $port: $total_count"
>5j/4Ly 0TNzVsu7 if [ $new_block = 1 ] ; then S\,{qhd restartservice $port gV7o
eZ5 fi
[brrziZ } ^"f i6-K! docheckall() Z\Q7#dl { F&P)mbz1 # reset wakeup_time #-W5$1 wakeup_time=$wakeup_time_max `=*svrmS for port in $portlist ; YRZg|Zw do `MD/CFl4 docheckport $port s6egd%r if [ $new_block = 1 ] ; then {\
e}43^9N # set wakeup_time shorter cause we found some abuse client jyC6:BNust wakeup_time=$wakeup_time_min IF}r%%'Y$ fi n>Ei1 done 26**tB< } EAfSbK3z h(L5MZs if [ -z "$firewall" ] && [ -f /etc/sysconfig/ipchains ] ; then Wama>dy% firewall="ipchains" 4L0LT>'M\ fi pI`Ke" "xOeBNRjV if [ -z "$firewall" ] && [ -f /etc/sysconfig/iptables ] ; then Ixw,$%-]y6 firewall="iptables" )&9RoW()? fi j;3o9!.s: cG?266{g if [ -z "$firewall" ] ; then bo2Od echo "Error: This machine does not have ipchains or iptables firewall support" Ie~~LU exit 1 *E]\l+]J fi 5f5ZfK3<i 4!jHZ<2Z mylogger_info "firewall.sh v$myver ValueOf.com starting" }dz(DPd mylogger_info "Firewall is: $firewall" F0\ry "(t mylogger_info "Port protected: $portlist" "DpQnhvbB mylogger_info "Max connection per ip: $max_active_conn" ry0 =N^ mylogger_info "Min time to check: $wakeup_time_min""s" v4$,Vt:7 mylogger_info "Max time to check: $wakeup_time_max""s" *v+ fkg mylogger_info "Timeout circle: $rule_timeout""s" 8'_Y=7b0Nw mylogger_info "Output is logged to: $log_facility" w(D9' Oq5k4 # if new ip blocked at this check run? v,0DGR~ new_block=0 =Ug_1w # if new ip blocked at this timeout run? q
4{tH ever_block=0 i'<1xd(` # reset wakeup_time m!_ghD{5h wakeup_time=$wakeup_time_max keOW{:^i UZra'+Wb lasttime=`date +%s` }b`*%141 iE(grI3 while [ 1 ] PvwIO_W do SO/]d70HG curtime=`date +%s` ;\+0H$ timediff=$((curtime-lasttime)) $Stu-l1e a #echo "timediff: $timediff" [3R
j?z"S if [ $timediff -ge $rule_timeout ] && [ $ever_block = 1 ] ; then Qs:r@"hE lasttime=$curtime A]$+
`uS\ ever_block=0 T"U t). dotimeout GwBQ
pNjy fi R:N-y."La. docheckall K5&C}Ey1 mylogger_info "sleep for $wakeup_time""s" MFuI&u!g: sleep $wakeup_time .Er/t"Qs; done xQap44KPZ b_yXM QaR.8/xV Xf9%A2 iB 1. 说明 rrYp^xLa` firewall.sh是一个shell脚本程序,每隔一段时间检查tcp连接的统计信息,如果来自某个ip对某个端口的活动连接超过规定的最大数量, ;NE/!! 则自动将该IP对该端口的访问屏蔽,并重新启动相应的服务。再每隔一段时间,会重设防火墙到初始状态。 nD\os[ 3 该程序可以同时保护多个端口 .N
&}<T[ ]xEE7H]\h 2. 安装 p]Zabky tar zxf firewall-1.0b.tar.gz 4&hqeY3 cd firewall-1.0b -oBas4J install -m 700 firewall.sh /usr/prima/sbin/firewall.sh Ba|}C(Ws? Eu.qA9,@U 3. 配置 @;D}=
$x 主要配置项目如下: KxmPL # 最小检查周期,缺省为120秒 1Z8Oh_DC wakeup_time_min=120 Ks2%F&\cE pm@Z
[g # 最大检查周期,缺省为300秒 E(kpK5h{ wakeup_time_max=600 Pl&`&N; KGmc*Jwy # 重设防火墙状态的时间,缺省为3600秒 ^@L
l(? rule_timeout=3600 J?quYlS jI`To%^Y # 保护的端口列表,缺省为80和25,支持的其他端口包括21(ftp), 110(pop3), 53(named), 3306(mysql) 0n
q}SH # 一般的网络攻击都是针对80和25,又以80居多 m$mY<Q
portlist="80 25" 'oZn<c` tr9Y1vxo{ # 每个ip可占用的最大活动(Established)连接数 y<%.wM]-J max_active_conn=8 :#:O(K1PW w+q;dc8 # iptables防火墙规则链名称,必须和/etc/sysconfig/iptables中一致 0!,gT H> # 如果用的是ipchains,可以忽略此项 6
Y_O^f iptables_chain_name="RH-Lokkit-0-50-INPUT" |;u%JW$4 >l< ~Z; # 日志输出目标 +<WRB\
W log_facility="local0" x$?7)F&z G q:4rG| **** 关于检查周期 **** z5&%T}$tJ 程序定义了两个检查周期,如果上次检查中屏蔽了某个IP,则程序会更频繁地检查连接情况,反之则等待更长时间。通过检查周期
2C33;?M 的动态调整,可以有效调度在遭受攻击和正常状态下程序的运行次数。 JlDDM
% acYoOW1G **** ipchains vs iptables **** U]!.~ji3
目前该程序支持ipchains和iptables两种软件防火墙,使用何种是由程序启动时自动检测的。如果/etc/sysconfig/ipchains和 !E
{GcK /etc/sysconfig/iptables都没有检测到,则报错退出。 [mf7>M`p]@ iPY v
ePQ **** 日志输出 **** yg-F
J/
程序的输出信息记录在系统日志中,目标是local0。如果没有特殊配置,可以在/var/log/messages中看到。建议在/etc/syslog.conf HEB/\ 中加入一条: %V<F< local0.* /var/log/firewall.log |
2.e0Z]k 然后重新启动syslog Ld}(*-1i /etc/init.d/syslog restart N?=qEX|R 这样,可以将firewall.sh输出的日志单独记到文件/var/log/firewall.log里。 uO_,n A|taP$% 4. 运行 8>VI$
/usr/prima/sbin/firewall.sh & >^H'ZYzw Ck3QrfM 范例输出: 3Z
aq#uA *** firewall.sh v1.0b ValueOf.com*** E)80S.V Firewall is: ipchains RQo$iISwy Port protected: 80 25 yxG:\y
b Max connection per ip: 8 X"TUe>cM Min time to check: 120s z{`6# Max time to check: 300s $#G6m`V Timeout circle: 3600s z)&naw. Output is logged to: local0 D%;wVnUw wuIsO;}/9 察看/var/log/firewall.log,可以看到: rq<`(V'2 Oct 16 14:08:55 server firewall.sh: do check port 80 // 检查80端口 @)OnIQN~ Oct 16 14:08:55 server firewall.sh: 192.168.0.60 2 connections // 有两个来自192.168.0.60的连接 h9<mThvgn Oct 16 14:08:55 server firewall.sh: total connections on port 80: 2 // 80端口总共2个连接 UzU-eyA Oct 16 14:08:55 server firewall.sh: do check port 25 // 检查25端口 i>tW|N Oct 16 14:08:55 server firewall.sh: total connections on port 25: 0 // 25端口没有连接 a9D gy_!Y Oct 16 14:08:55 server firewall.sh: sleep for 300s // 等待300秒 /FP~jV!z qPXANx<^ 5. 停止 I;kf
#nvao 先用ps命令察看firewall.sh进程的进程号,然后用kill命令将其终止,如 #$rf-E5g-K # ps auxww|grep firewall.sh kZU
"Xn root 27932 0.0 0.5 2312 1060 pts/2 S 12:38 0:00 /bin/sh /usr/prima/sbin/firewall.sh o{{:|%m3Q root 27967 0.0 0.3 1732 592 pts/2 S 12:39 0:00 grep firewall.sh ;f".'9 l^ 第一行即firewall.sh的进程,用kill命令: yfSiByU # kill 27932 <S\;k@f [1] Terminated /usr/prima/sbin/firewall.sh )3]83:lD2 即将其终止
|
常州电信/网通机房,100M共享/10M独享/1000M共享/100M独享/电信+网通双线路服务器托管
Tel:0519-89991155 企业QQ:4006023839 5y6s Inc.
|
[楼 主]
|
Posted: 2008-01-26 02:12 |
| |