Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1389416
  • 博文数量: 140
  • 博客积分: 8518
  • 博客等级: 中将
  • 技术积分: 1822
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-01 22:23
个人简介

嘿嘿!

文章分类
文章存档

2016年(2)

2015年(5)

2014年(6)

2013年(11)

2012年(11)

2011年(3)

2010年(4)

2009年(4)

2008年(8)

2007年(23)

2006年(26)

2005年(37)

分类: LINUX

2012-01-10 16:49:50

Automatically Block Failed SIP Peer Registrations

Previously we posted a little script for quickly checking your asterisk log for failed peer registrations. Building on that script, and with the use of iptables and cron, you can easily (and automatically) block flooding traffic from your system. Iptables, a linux command line program to filter IP traffic, provides high level packet filtering before the traffic can be used to corrupt a program. Cron, the linux time scheduler, enables you to automatically run commands at scheduled time periods.

Set up IP Tables

We will not be discussing the intricacies of iptables in this post. There are excellent tutorials on iptables, and with most things linux, help is only a google away. To help identify the traffic blocked as asterisk related, a new chain will be created appropriately called… asterisk.

Here’s how to add the new chain:

1
2
3
iptables -N asterisk
iptables -A INPUT -j asterisk
iptables -A FORWARD -j asterisk

This will help identify hosts blocked for failed registrations.

Asterisk’s Log for Failed Registrations

In most cases of a sip flood attack, the host attempts registration to Asterisk. These hosts are identified in the Asterisk log (/var/log/messages) as “No matching peer found.” The following perl script scans /var/log/messages for these patterns, strips the IP address, and puts the IP address into an array.

After the file has been read, the IP addresses are counted (each count is a failed attempt), compared against the existing blocked hosts, and new occurrences are blocked. With this script we are blocking any host after the 4th failed attempt.

Here’s the script (last updated 05 SEP 2010):

#!/usr/bin/perl -w
use strict;
use warnings;
my (@failhost);
my %currblocked;
my %addblocked;
my $action;
 
open (MYINPUTFILE, "/var/log/asterisk/messages") or die "\n", $!, "Does log file file exist\?\n\n";
 
while () {
    my ($line) = $_;
    chomp($line);
    if ($line =~ m/\' failed for \'(.*?)\' - No matching peer found/) {
        push(@failhost,$1);
    }
    if ($line =~ m/\' failed for \'(.*?)\' – Wrong password/) {
        push(@failhost,$1);
    }
}
 
my $blockedhosts = `/sbin/iptables -n -L asterisk`;
 
while ($blockedhosts =~ /(.*)/g) {
    my ($line2) = $1;
    chomp($line2);
    if ($line2 =~ m/(\d+\.\d+\.\d+\.\d+)(\s+)/) {
        $currblocked{ $1 } = 'blocked';
    }
}
 
while (my ($key, $value) = each(%currblocked)){
    print $key . "\n";
}
 
if (@failhost) {
    &count_unique(@failhost);
    while (my ($ip, $count) = each(%addblocked)) {
        if (exists $currblocked{ $ip }) {
            print "$ip already blocked\n";
        } else {
            $action = `/sbin/iptables -I asterisk -s $ip -p udp --dport 5060 -j DROP`;
            print "$ip blocked. $count attempts.\n";
        }
    }
} else {
    print "no failed registrations.\n";
}
 
sub count_unique {
    my @array = @_;
    my %count;
    map { $count{$_}++ } @array;
    map {($addblocked{ $_ } = ${count{$_}})} sort keys(%count);
}
Schedule the script with cron

The final step is to schedule your script to run every X minutes in cron. We’ve chosen to run our script every 2 minutes, but you can change this to 1 minute or any other time period you choose. Just remember… you can receive thousands of attempts within 2 minutes.

If you have named your script check-failed-regs.pl and placed it in your /usr/local/bin directory, your cron statement would look like this:

1
*/2 * * * * perl /usr/local/bin/check-failed-regs.pl &> /dev/null
阅读(1250) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

chicol2012-01-20 10:24:37

,哈哈,bob。你博客注册的好早哦