LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 950|回复: 8

高手请指教:zixia的那个proftp动态封IP的脚本[急]

[复制链接]
发表于 2005-7-29 13:54:20 | 显示全部楼层 |阅读模式
就是可以实现类似 "30秒联接超5次封IP" 功能的东东...

原件如下:
#!/usr/bin/perl -w
# proftpd log 文件实时分析,动态封禁/解封
# 用法:
# tail -f /var/log/proftpd | /usr/bin/proftpdeny.pl
#
#
use Time::HiRes qw(gettimeofday);

# 封禁时间,以秒为单位
$DENY_PERIOD=600;
# 对最近多久的日志进行统计
$EVAL_PERIOD=60;

# 在 EVAL_PERIOD 中的最多连接次数
$DENY_TIMES=5;

# 数组,记录 IP/最后登陆时间/重试次数
%BADLIST = ();
%DENIED_IP = ();

init_iptables();

while (<STDIN>){
chomp $_;
$line = $_;

$badip = get_bad_ip($line) ;

if (! $badip ) {
next;
}

#print STDERR "badip: $badip\n";

# 删除 BADLIST 中的过期 IP
refresh_bad_ip();

# 添加multi login的ip到BADLIST
add_bad_ip( $badip );

# 把平均每秒连接次数 > $DENY_RETRY_TIMES_PER_SEC 的 IP 封掉
check_bad_ip();

# 将封禁时间 > $DENY_PERIOD 的ip解封
undeny_bad_ip();
}

exit(0);

##############################
sub get_bad_ip
{
local( $line );
$line = $_[0];
return undef if ( ! $line );

if ( $line =~ /ftp\.zixia\.net \((\d+\.\d+\.\d+\.\d+)\[[^\]]+\]\) -
Connection refused \(max clients per host \d+\)\./ ) {
return $1;
} else {
return undef;
}
}

sub add_bad_ip
{
local ( $badip );
$badip = $_[0];
die "add_bad_ip() take no param err" unless $badip;

($seconds, $microseconds) = gettimeofday;

$BADLIST{$badip}{$seconds . '.' . $microseconds} = 1;
#print STDERR "add_bad_ip: $badip, $seconds\n";
}

sub refresh_bad_ip
{
foreach $ip ( keys %BADLIST ){
foreach $secmic ( keys %{$BADLIST{$ip}} ){
if ( $secmic =~ /^(\d+)\.(\d+)$/ ){
$seconds = $1;

if ( time - $seconds > $EVAL_PERIOD ){
delete $BADLIST{$ip}{$secmic} ;
#print STDERR "refresh_bad_ip: delete badlist $ip $secmic\n";
}
}
}
$num = keys %{$BADLIST{$ip}};
if ( 0==$num ) {
delete $BADLIST{$ip};
}
}
}

sub check_bad_ip
{
foreach $ip ( keys %BADLIST ){
$login_num = keys ( %{$BADLIST{$ip}} );

#print STDERR "check_bad_ip: ip $ip has $login_num times login attampts..\n";


if ( $login_num > $DENY_TIMES ) {
deny_bad_ip ( $ip ) ;
delete $BADLIST{$ip};
}
}
}

sub deny_bad_ip
{
local $ip;
$ip = $_[0];

die "deny_bad_ip no ip err" unless $ip;

foreach ( keys %DENIED_IP ){
return if ( /^$ip$/ )
}

$cmd = "iptables -A ftpDeny -p tcp -s $ip -j REJECT --reject-with
tcp-reset";
#print STDERR "sys cmd: $cmd\n";
system ( $cmd );
$DENIED_IP{$ip} = time;

$date = `date`;#把当前日期赋值给$date
chomp $date;#截去\n,这里也可以这样,chomp($date);
system ( "printf \"%s %-16s denied.\n\" \"$date\" $ip >>/var/log/proft
pd.deny" )
}

sub undeny_bad_ip
{
foreach $ip ( keys %DENIED_IP ){
if ( time - $DENIED_IP{$ip} > $DENY_PERIOD ) {
$line_number = `iptables -nL ftpDeny --line-number |
grep $ip | awk {'print \$1'}`;
chomp $line_number;
$cmd = "iptables -D ftpDeny $line_number";

system ( $cmd );
delete $DENIED_IP{$ip};

$date = `date`; #把当前日期赋值给$date
chomp $date; #截去\n
system ( "printf \"%s %-16s undenied.\n\" \"$date\"
$ip >>/var/log/proftpd.deny" )

}
}
}

sub init_iptables
{
$cmd1 = "iptables -F ftpDeny > /dev/null 2>&1";
$cmd2 = "iptables -X ftpDeny > /dev/null 2>&1";
$cmd3 = "iptables -N ftpDeny > /dev/null 2>&1";
$cmd4 = "iptables -I INPUT -p tcp --dport 59000:60000 -j ftpDeny";
$cmd5 = "iptables -I INPUT -p tcp --dport 20:21 -j ftpDeny";

$exist = `iptables -nL INPUT | grep ftpDeny | wc -l | awk {'print \$1'}`;


system( $cmd1 );
system( $cmd2 );
system( $cmd3 );

if ( 0==$exist ) {
system( $cmd4 ) ;
system( $cmd5 ) ;
}
}

试了好多次,不行.... T_T
"tail -f "后面跟log文件的路径应该就可以吧...
但是运行不起来,说"iptables'有问题...
脚本里到底哪里还要改啊?

谢谢!!!!
发表于 2005-7-29 17:19:46 | 显示全部楼层
首先你用这个脚本分析的日志要有一定的格式
我记得proftpd的conf里面有一个syslog = 路径  (肯定有相关的语句,但是不是这个语法,不确定)
具体可以看proftp的网站
然后用脚本分析你输出的这个syslog



if ( $line =~ /ftp\.zixia\.net \((\d+\.\d+\.\d+\.\d+)\[[^\]]+\]\) -
Connection refused \(max clients per host \d+\)\./ ) {
这个是表示匹配日志里面的特定语句(若匹配则表示重复连接),你看看自己的日志是什么样的,对应的填上,一般来说,匹配Connection refused 就可以了
回复 支持 反对

使用道具 举报

发表于 2005-7-29 17:28:02 | 显示全部楼层
建议使用proftpd 的mod_ban,详见http://www.castaglia.org/proftpd/modules/mod_ban.html
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-29 19:16:38 | 显示全部楼层
Post by xlighting

我记得proftpd的conf里面有一个syslog = 路径  (肯定有相关的语句,但是不是这个语法,不确定)


if ( $line =~ /ftp\.zixia\.net \((\d+\.\d+\.\d+\.\d+)\[[^\]]+\]\) -
Connection refused \(max clients per host \d+\)\./ ) {
这个是表示匹配日志里面的特定语句(若匹配则表示重复连接),你看看自己的日志是什么样的,对应的填上,一般来说,匹配Connection refused 就可以了


是指log信息的记录么?我是这样写的:
SystemLog /usr/local/var/proftpd/syslog   #好像就是找地方把syslog放一下,具体好象有
                                            #参数设定,忘了...

syslog记录的内容格式是:

Jul 29 15:59:13 LY proftpd[5303] LY (10.13.36.5[10.13.36.5]):ANON anonymous : Login successful.
(IP是登陆者的IP)
相应的PERL脚本怎么改呢?

......我是PERL白痴......
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-7-30 13:51:20 | 显示全部楼层
Post by memory
建议使用proftpd 的mod_ban,详见http://www.castaglia.org/proftpd/modules/mod_ban.html


去下载了,按说明cp mod_ban.c了,config了,但是make的时候出了一大堆错误......
回复 支持 反对

使用道具 举报

发表于 2005-7-31 17:56:34 | 显示全部楼层
试了一下,没问题。

我的ban.log文件:
  1. Jul 31 17:58:16 mod_ban/0.4.5[11142]: added MaxLoginAttempts-triggered autoban for host '202.108.185.59'
  2. Jul 31 17:58:16 mod_ban/0.4.5[11142]: MaxLoginAttempts autoban threshold reached, ending session
  3. Jul 31 17:58:24 mod_ban/0.4.5[11143]: login from host '202.108.185.59' denied due to host ban
  4. Jul 31 17:58:30 mod_ban/0.4.5[11144]: login from host '202.108.185.59' denied due to host ban
  5. Jul 31 17:58:38 mod_ban/0.4.5[11145]: login from host '202.108.185.59' denied due to host ban
  6. Jul 31 17:58:44 mod_ban/0.4.5[11146]: login from host '202.108.185.59' denied due to host ban
  7. Jul 31 17:59:35 mod_ban/0.4.5[11138]: ban event MaxLoginAttempts entry '202.108.185.59' has expired (52 seconds ago)
  8. Jul 31 18:00:54 mod_ban/0.4.5[11157]: obtained shmid 163840 for BanTable '/var/run/proftpd/ban.tab'
  9. Jul 31 18:02:42 mod_ban/0.4.5[11171]: obtained shmid 196608 for BanTable '/var/run/proftpd/ban.tab'
  10. Jul 31 18:08:10 mod_ban/0.4.5[11190]: added ban event for MaxLoginAttempts
复制代码


proftpd.conf中加入的部分:
  1.   MaxLoginAttempts 1

  2. <IfModule mod_ban.c>
  3.   BanEngine on
  4.   BanLog /var/log/proftpd/ban.log
  5.   BanTable /var/run/proftpd/ban.tab

  6.   # If the same client reaches the MaxLoginAttempts limit 2 times
  7.   # within 10 minutes, automatically add a ban for that client that
  8.   # will expire after one hour.
  9.   BanOnEvent MaxLoginAttempts 2/00:01:00 00:30:00
  10.   BanOnEvent MaxConnectionsPerHost 4/00:01:00 00:30:00

  11.   # Allow the FTP admin to manually add/remove bans
  12.   BanControlsACLs all allow group ftpadm, root
  13. </IfModule>
复制代码


现在mod_ctrls_admin没搞定,使用ftpdctl时总提示ftpdctl: access denied
怒。。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-1 21:04:04 | 显示全部楼层
555555~~~~~~~~~
就是安装的时候出现很多问题.make不起来.....
error "roFTPD 1.2.10rc1 or later required"
然后就是很多warning...
难道真的要更高的版本?官方页面上不是说1.2.x都能用的么??
实在不形,就只有升级我的proftp了...
回复 支持 反对

使用道具 举报

发表于 2005-8-1 21:42:12 | 显示全部楼层
我用的是debian sarge, 编译还算顺利。不知你用的是什么系统。
proftpd编译时会有一些依赖的包,随你所选modules的不同依赖也有所变化,如mod_tls依赖libssl-dev。因此,不需要的模块尽量不要装。
哦,对了,那各ftpdctl也搞定了,是我配置的问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-1 22:17:30 | 显示全部楼层
忙了好久,终于解决了....果然是版本问题......

实在是要谢谢memory 啊!!!!这个mod_ban好方便的说!!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表