Skip to content

Instantly share code, notes, and snippets.

@xopr xopr/autoblock.pl
Last active Apr 16, 2020

Embed
What would you like to do?
auto block IP based registrations and invites in FreeSWITCH
#!/usr/bin/env perl
# Blocks IP adresses in 3 steps:
# * unknown REGISTER (Can't find user) is blocked immediately
# * unauthorized INVITE is flagged (and blocked after 3 strikes)
# * authorized INVITES are unflagged (and the IP block is removed when the counter hits 0 (or less))
# * IP based incoming call which is not from a trunk (defined in ACL) is blocked immediately
# this needs some adjustments in the FS config:
# An ACL list of ip adresses of trunks that setup calls to you: <list name="trunks" default="deny">
# Log entry before any public.xml include
# <extension name="IP based call">
# <condition field="${acl(${network_addr} trunks)}" expression="false"/>
# <condition field="${sip_to_host" expression="${local_ip_v4}">
# <action application="log" data="WARNING IP based INVITE not from trunk ${network_addr}"/>
# <action application="respond" data="403"/>
# </condition>
#</extension>
# Mofified auth+flag entry after the public.xml includes
#<extension name="check_auth" continue="true">
# <condition field="${sip_authorized}" expression="^true$" break="never">
# <anti-action application="log" data="WARNING flag unauthorized: ${network_addr} (from ${sip_from_uri} to ${sip_to_uri})"/>
# <anti-action application="respond" data="407"/>
# </condition>
#</extension>
# unflag entry after the default.xml unloop part
#<extension name="authorized" continue="true">
# <condition>
# <action application="log" data="WARNING unflag unauthorized: ${network_addr} (from ${sip_from_uri} to ${sip_to_uri})"/>
# </condition>
#</extension>
use strict;
use warnings;
my %hits = ();
open(my $fd, "<", "/var/log/freeswitch/freeswitch.log") or die "Can't open log";
while(1)
{
if(eof $fd)
{
sleep 1;
$fd->clearerr;
next;
}
my $line = <$fd>;
chomp($line);
if( $line =~ /^.*?Can\'t find user \[.+@\d+\.\d+\.\d+\.\d+\] from (\d+\.\d+\.\d+\.\d+).*?$/ )
{
if ( exists $hits{$1} )
{
$hits{$1}++;
}
else
{
print "Blocking $1..\n";
$hits{$1} = 1;
system("/sbin/iptables -A INPUT -s $1 -j DROP -m comment --comment \"AUTOBLOCK\"");
}
print ( "Register error: $1 ($hits{$1} hits)\n" );
}
elsif( $line =~ /^.*? flag unauthorized: (\d+\.\d+\.\d+\.\d+) \(from .*?$/ )
{
if ( exists $hits{$1} )
{
$hits{$1}++;
}
else
{
#print "Marking $1..\n";
$hits{$1} = 1;
}
print ( "Unauthorized: $1 ($hits{$1} hits)\n" );
if ( $hits{$1} == "3" )
{
print "marking $1\n";
system("/sbin/iptables -A INPUT -s $1 -j DROP -m comment --comment \"AUTOBLOCK\"");
}
}
elsif( $line =~ /^.*? unflag unauthorized: (\d+\.\d+\.\d+\.\d+) \(from .*?$/ )
{
if ( exists $hits{$1} )
{
$hits{$1}--;
}
else
{
#print "Unmarking $1..\n";
$hits{$1} = 0;
}
print ( "Authorized: $1 ($hits{$1} hits)\n" );
if ( $hits{$1} <= "0" )
{
$hits{$1} = 0;
print "unmarking $1\n";
system("/sbin/iptables -D INPUT -s $1 -j DROP -m comment --comment \"AUTOBLOCK\"");
}
}
elsif( $line =~ /^.*? IP based INVITE not (?:from trunk|in ACL) (\d+\.\d+\.\d+\.\d+).*?$/ )
{
if ( exists $hits{$1} )
{
$hits{$1}++;
}
else
{
print "Blocking $1..\n";
$hits{$1} = 1;
system("/sbin/iptables -A INPUT -s $1 -j DROP -m comment --comment \"AUTOBLOCK\"");
}
print ( "Invite error: $1 ($hits{$1} hits)\n" );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.