deserts
大客部
级别: 总版主
精华:
0
发帖: 607
威望: 2 点
金钱: 1061 RMB
贡献值: 0 点
在线时间:1761(小时)
注册时间:2006-01-01
最后登录:2025-02-11
|
linux自动屏蔽IP工具
另存为 firewall.sh 给执行的权限 /DG`Hg nhXp_Z9 #!/bin/sh zju,#% # this program is used to check tcp/ip connections p|9ECdU>; # and block those ip with excessive connections #&2N,M!Q ZLi
o8 # my version X @jYQ. myver="1.0RC1" OD/P*CQ_ >A(?Pn{|a # wake up every 120s if last check found abuse client wR<QeH'V wakeup_time_min=120 x<y[na .6Lhy3x # wake up every 300s if last check found no abuse client $*)(
8Cl wakeup_time_max=300 cLko &Cpxo9- # rule timeout 3600s }!7DF rule_timeout=3600 K#C56k q& t?H;iBrpxd # check port list f,
j(uP portlist="80" )E~\H+FP6 rMg{j
gD # max established connection per ip dVtLYx max_active_conn=8 `::'UfHc 2c`=S5 # iptables chain name +:Q/<^Z iptables_chain_name="RH-Lokkit-0-50-INPUT" B';>Hk {,C8}8a W # log facility ^5 =E`q". log_facility="local0"
kt0{-\
p n zrCOMld # Block policy ;Owu:} ipchains_block_policy="DENY" OQ&D?2r iptables_block_policy="REJECT" s=
Q*| B|$13dHfa # myself Mciq9{8& myself=`basename $0` YeVc,B' 8]MzOGB8 mylogger_info() z'D{:q { 8+cpNX logger -p $log_facility.info -t $myself $@ 2>/dev/null 0THAI } $$f$$ Vg~
kpgB mylogger_debug() ,fJ(.KI0 { D2cIVx3:( logger -p $log_facility.debug -t $myself $@ 2>/dev/null ^o\p|f>f } {u6fa>R&$ Y4!q 1]TGX mylogger_notice() |(v=1#i { _W@Fk)E6N logger -p $log_facility.notice -t $myself $@ 2>/dev/null vK7,O%!S } 5T3>fw2G 4lUE(#kUM dotimeout() Wc>)/y5$ { I/V#[KC mylogger_info "reset firewall when timeout arrives" #LgoKiP!Y case "$firewall" in <@!kR$
Rd ipchains) q$'&RG /etc/init.d/ipchains restart 1>/dev/null 2>/dev/null Jxw:Jk
~ if [ $? = 0 ] ; then )nxIxr0d- mylogger_info "ipchains restarted" A0u:Fm{E else eaP$/U
D? mylogger_notice "ipchains restart failed" k0Yixa fi A1$'[8U~3 ;; =u"|q
D iptables) >&Q. .`q /etc/init.d/iptables restart 1>/dev/null 2>/dev/null n(S-F g if [ $? = 0 ] ; then ;FflEL<7Y mylogger_info "iptables restarted" m48Y1'4 else v 8a mylogger_notice "iptables restart failed" !$#4D&T fi
LfM(DK ;; 3h4"Rv=, *) |T&#"q,i9% mylogger_notice "neither ipchains nor iptables" 4\es@2q ;; xTm&`X
o esac O#Hz5A5 +@7R,8 } ) <~7<.0 !,uw./8@Ku blockclient() =ab}.dWC { ;0q6 bp(<H if [ -z "$1" ] || [ -z "$2" ]; then -~ Q3T9+ mylogger_notice "blockclient() missing client or port to block" tRCd(
Z,WY return d^^>3L!h fi -v@^6bQVp local ip port }cmL{S ')RK(I ip=$1 p?nVPTh port=$2 (6'Hzl^Kp b1!%xdy_T case "$firewall" in 3I(H.u ipchains) xw
Qkk mylogger_notice "blocking $1 to $2 via ipchains" e~dU " found=`ipchains -nL | egrep "^$ipchains_block_policy.*[[:space:]]+$ip[[:space:]]+.*[[:space:]]+\->[[:space:]]+$port"` W>Kn*Dy8~ if [ -z "$found" ] ; then 2Y{9Df cmd="ipchains -I input 1 -p tcp -s $ip -d 0/0 $port -j $ipchains_block_policy 1>/dev/null 2>/dev/null" n\U6oJN mylogger_debug "cmd: $cmd" E;0"1
P|S `ipchains -I input 1 -p tcp -s $ip -d 0/0 $port -j $ipchains_block_policy 1>/dev/null 2>/dev/null` #*@Yil=1 if [ $? != 0 ] ; then G>"[nXmcu mylogger_notice "$cmd call failed" S)?B
I return P)
#rvTDRw fi Dl6zl6q? new_block=1 ><HXd+- sd ever_block=1 FliN@RNo else |kD?^Nx mylogger_info "$ip already blocked to $port" o?
=u#= fi u#QQCgrs ;; e2v,#3Q\ iptables) 'yqp mylogger_notice "blocking $1 to $2 via iptables" U*t`hn-xs found=`iptables -nL | egrep "^$iptables_block_policy.*[[:space:]]+$ip[[:space:]]+.*[[:space:]]+dpt:$port[[:space:]]+"` fpUX
@b if [ -z "$found" ] ; then 89l}
6p/L 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" qSR
%# mylogger_debug "cmd: $cmd" Ghz)=3 `iptables -I $iptables_chain_name 1 -p tcp -m tcp -s $ip --dport $port -j $iptables_block_policy 1>/dev/null 2>/dev/null` ;(A'XA4
6N if [ $? != 0 ] ; then 4*]`s|fbu mylogger_notice "$cmd call failed" X$<?:f-
return Z|.. hZG fi Z(FAQ\7 new_block=1 8u4]@tJ
H ever_block=1 uG<+IT|x else #~Q0s)Ze mylogger_info "$ip already blocked to $port" RV~w+%f fi uAJC Q)@ ;; {=kA8U *) "dt3peH mylogger_notice "neither ipchains nor iptables" /lUb9&yV ;; /[mCK3_ esac \J6T:jeS, } ky*-_ @|M10r9E restartservice() 6@ +
>UZr\ { b'G4KNW local service JprZ6
> if [ -z "$1" ] ; then /OZF3Pft mylogger_notice "no port given to see which service to be restart" 6oC(09 return \Ew2@dF{O fi :f`1 ?qdG)jo= case "$1" in 7eY*Y"GX 80) r"xo9&| service="httpd" 4ed(
DS
N ;; \
2T@]!n 25) z\v\T|C service="postfix" q4VOK
'N ;; =oSv=xY 110) hhwV)Z service="courier-pop3d" sb;81?| ;; ~6
R|
a 21) >RRb8=[J service="muddleftpd" nF05p2Mh ;; aRR*<dY 53) Mk7#qiPo service="named" A|jaWZM- ;; 5gi
`&t` 3306) sz_|py?0 service="mysqld" V\Rbnvq ;; ;/$zBr`' esac \acjv|] if [ ! -z "$service" ] ; then ,xNuc$8Jd /etc/init.d/$service restart 1>/dev/null 2>/dev/null 1S<V,9( if [ $? = 0 ] ; then |eJ4"OPC mylogger_notice "$service restarted" Rj1Z else ?> }bg mylogger_notice "$service restart failed"
Kt9:V, fi 2?#IwT' fi rE EWCt } Ydh]EO0' #"=_GA^.{ docheckport() g*TAaUs|n { $s$z"< mylogger_info "do check port $1" 94LFElE3 local port last_client count client total_count `
A])4q$ 1 f).J if [ -z "$1" ] ; then 5Jlz$]f mylogger_notice "docheckport() port not given" Y]Td+Zi return W/OZ}ky}^ fi 1^TOTY x~rIr#o port=$1 tgKmCI VD#`1g< clientlist=`netstat -an --tcp| grep ESTABLISHED | awk "{ if ( index(\\$4,\":$port\") ) print \\$5}" | awk -F ':' '{print $1}'|sort` s8Xort& if [ $? != 0 ] ; then :%~+&q
S mylogger_notice "netstat call failed" TU&gj1
return O|}97a^ fi <p;cR` %uE #echo $clientlist 9X/c%:)\= # reset new_block 7;ZSeQyC new_block=0 p(f
YpD count=0 "JzQCY^C total_count=0 iqW
T<WY last_client="" GcmN4
0 for client in $clientlist RoFy2A=_ do X`YAJG #echo "client is $client" p)NhV if [ -z "$last_client" ] ; then sN.h>bd count=$((count+1)) C(qqGK{ total_count=$((total_count+1)) ]~iOO
%&R last_client=$client q{?Po;\D else A8Tq2]"* S if [ "$client" = "$last_client" ] ; then Lwm2:_\_b count=$((count+1)) A
6v<+`? total_count=$((total_count+1)) ~OO&%\$k else `],'fT|,S mylogger_debug "$last_client $count connections" >jMq-#*4 if [ $count -ge $max_active_conn ] ; then %9Br mylogger_notice "client $last_client connection $count >= $max_active_conn" Vw0cf; blockclient $last_client $port xO"fg9a fi ?$T!=e" count=1 -F\xZ total_count=$((total_count+1)) /<,LM8n last_client=$client R%B"Gtl) fi hqOy*!8'@ fi Y?G\@6 done @y?<Kv}s # check the last client F=)9z+l# if [ ! -z "$client" ] ; then ,[fn? s r count=$((count+1)) #'m&<g, total_count=$((total_count+1)) gw
[\7 mylogger_debug "$client $count connections" ernZfd{H if [ $count -ge $max_active_conn ] ; then "#Ov!t mylogger_notice "client $client connection $count >= $max_active_conn" 49.
@Uzo blockclient $client $port w;@DcX$] fi d67Q@')00 fi )9LlM2+y mylogger_info "total connections on port $port: $total_count" ~a@O1MB '@OqWdaR if [ $new_block = 1 ] ; then \z'A6@ restartservice $port 1HOYp*{#wP fi ;e~Z:;AR } Fl)p^uUtl ia=eFWt. docheckall() Gd^K,3:. T { Z(g9rz']0 # reset wakeup_time 2(SK}<X wakeup_time=$wakeup_time_max `U:W(\L for port in $portlist 'nH/Z 84 do 2BTFK"=U docheckport $port QUa_gYp0v if [ $new_block = 1 ] ; then Ph[P$: 9 # set wakeup_time shorter cause we found some abuse client m
|mY_t wakeup_time=$wakeup_time_min YbS$D fi 8&?kr/_Vr done hCXSC*; } m$glRs
@ UuDT=_1Sh if [ -z "$firewall" ] && [ -f /etc/sysconfig/ipchains ] ; then ~`J/618 firewall="ipchains" :=
J~t@ fi yO@KjCv" kz4d"bTb if [ -z "$firewall" ] && [ -f /etc/sysconfig/iptables ] ; then jpND"`Q firewall="iptables" &{#4^.Q fi OC)~psQK %EC{O@EAk if [ -z "$firewall" ] ; then %<^B\|d'? echo "Error: This machine does not have ipchains or iptables firewall support" v0pyyUqS exit 1 ^Y mq<*X fi
OC0dAxq Xy_ <Yqx} mylogger_info "firewall.sh v$myver ValueOf.com starting" Dx<">4 mylogger_info "Firewall is: $firewall" 6U{&`8C mylogger_info "Port protected: $portlist" <@;Y.76~ mylogger_info "Max connection per ip: $max_active_conn" :H}a/ x*ur mylogger_info "Min time to check: $wakeup_time_min""s" RI,Z&kXj2o mylogger_info "Max time to check: $wakeup_time_max""s" lZpa)1.tiC mylogger_info "Timeout circle: $rule_timeout""s" Z1V%pg>]* mylogger_info "Output is logged to: $log_facility" Q~/TqG
U Kv**(~FNnH # if new ip blocked at this check run? 3$YgGum new_block=0
tx-HY<
# if new ip blocked at this timeout run? vo'=d"zm ever_block=0 =M]f7lJ # reset wakeup_time _O!)aD wakeup_time=$wakeup_time_max :5/P{Co( zbL!q_wO lasttime=`date +%s` ~b}@*fq c*+yJNm3> while [ 1 ] e}qG
_* do fV[(s7vW curtime=`date +%s` <|= UrG timediff=$((curtime-lasttime)) 3?Ckk{)& #echo "timediff: $timediff" f<.43kv@ if [ $timediff -ge $rule_timeout ] && [ $ever_block = 1 ] ; then 5B+>28G% lasttime=$curtime "tuBfA+f ever_block=0 |RUx)& dotimeout \k?uh+xl fi :r^c_Ui docheckall WBS~e mylogger_info "sleep for $wakeup_time""s" G\8ps~3T sleep $wakeup_time m2o*d$Ke done ["|' f \79KU cP[3p: L(tA~Z"k 1. 说明 -!E))|A firewall.sh是一个shell脚本程序,每隔一段时间检查tcp连接的统计信息,如果来自某个ip对某个端口的活动连接超过规定的最大数量, nBs%k!RR 则自动将该IP对该端口的访问屏蔽,并重新启动相应的服务。再每隔一段时间,会重设防火墙到初始状态。 (yk^% 该程序可以同时保护多个端口 SJY<#_b %mR roR6 2. 安装 =ogzq.+| tar zxf firewall-1.0b.tar.gz }V.Wp6"S cd firewall-1.0b j{,3! install -m 700 firewall.sh /usr/prima/sbin/firewall.sh Kp")
%p# &IGTCTBP 3. 配置 FY%v \`@1* 主要配置项目如下: +5pK[%k # 最小检查周期,缺省为120秒 (fON\)l wakeup_time_min=120 D`]Lm24_] u}u;jTi>2 # 最大检查周期,缺省为300秒 !4uTi [e wakeup_time_max=600 $Xf1|!W%a% r(`;CY]@ # 重设防火墙状态的时间,缺省为3600秒 '| Enc"U rule_timeout=3600 ?qr-t+ /3D!,V, # 保护的端口列表,缺省为80和25,支持的其他端口包括21(ftp), 110(pop3), 53(named), 3306(mysql) `{fqnNJE # 一般的网络攻击都是针对80和25,又以80居多 *<*{gO?Q4 portlist="80 25" T^h;T{H2 7sECbbJT # 每个ip可占用的最大活动(Established)连接数 =ECw' max_active_conn=8 }IvJIr 6'y+Ev$9 # iptables防火墙规则链名称,必须和/etc/sysconfig/iptables中一致 /G$8j$ # 如果用的是ipchains,可以忽略此项 Ws?BAfP iptables_chain_name="RH-Lokkit-0-50-INPUT" G)\s{qk xQ4D| & # 日志输出目标 QjETu log_facility="local0" fq/F
|c ^_b+o **** 关于检查周期 **** >E^?<}E~. 程序定义了两个检查周期,如果上次检查中屏蔽了某个IP,则程序会更频繁地检查连接情况,反之则等待更长时间。通过检查周期 fLK*rK^{" 的动态调整,可以有效调度在遭受攻击和正常状态下程序的运行次数。 U#G[#sd> K :kSA^w8 **** ipchains vs iptables **** hGi"=Oud2 目前该程序支持ipchains和iptables两种软件防火墙,使用何种是由程序启动时自动检测的。如果/etc/sysconfig/ipchains和 QC0^G,9. /etc/sysconfig/iptables都没有检测到,则报错退出。 y
XZZ)i_ 5)4*J. **** 日志输出 **** 3/8o)9f. 程序的输出信息记录在系统日志中,目标是local0。如果没有特殊配置,可以在/var/log/messages中看到。建议在/etc/syslog.conf m`C(y$8fU 中加入一条: ~rEU83 local0.* /var/log/firewall.log Hno@ 然后重新启动syslog ~/1kCZB /etc/init.d/syslog restart yA*~O$~Y 这样,可以将firewall.sh输出的日志单独记到文件/var/log/firewall.log里。 P\;lH"9 {:40Jf
4. 运行 [oOZ6\?HB /usr/prima/sbin/firewall.sh & `L`*jA+_ uRG0}>]|U 范例输出: =-jkp *** firewall.sh v1.0b ValueOf.com*** K^tM$l\ Firewall is: ipchains # 'G/&&< Port protected: 80 25 'qQ 5K
o Max connection per ip: 8 tu6oa[s Min time to check: 120s _Hi;Y
Max time to check: 300s N( E\ Timeout circle: 3600s qa#Fa)g* Output is logged to: local0 t
),~w,7(J o!L1Qrh 察看/var/log/firewall.log,可以看到: Z `O.JE Oct 16 14:08:55 server firewall.sh: do check port 80 // 检查80端口 Yo@>O98 Oct 16 14:08:55 server firewall.sh: 192.168.0.60 2 connections // 有两个来自192.168.0.60的连接 EU]{S=T Oct 16 14:08:55 server firewall.sh: total connections on port 80: 2 // 80端口总共2个连接 w/KHS#~ Oct 16 14:08:55 server firewall.sh: do check port 25 // 检查25端口 W%b<(T;
Oct 16 14:08:55 server firewall.sh: total connections on port 25: 0 // 25端口没有连接 !y$Hr[v Oct 16 14:08:55 server firewall.sh: sleep for 300s // 等待300秒 0F=UZf& +`9
]L]J]4 5. 停止 _1hc^j 先用ps命令察看firewall.sh进程的进程号,然后用kill命令将其终止,如 *c7kB}/ # ps auxww|grep firewall.sh D|Wekhm root 27932 0.0 0.5 2312 1060 pts/2 S 12:38 0:00 /bin/sh /usr/prima/sbin/firewall.sh soW.
root 27967 0.0 0.3 1732 592 pts/2 S 12:39 0:00 grep firewall.sh lxj_(Uo 第一行即firewall.sh的进程,用kill命令: 2_;.iH
6 # kill 27932 fL
ng[& [1] Terminated /usr/prima/sbin/firewall.sh
/XS6X 即将其终止
|
常州电信/网通机房,100M共享/10M独享/1000M共享/100M独享/电信+网通双线路服务器托管
Tel:0519-89991155 企业QQ:4006023839 5y6s Inc.
|
[楼 主]
|
Posted: 2008-01-26 02:12 |
| |