Hi
@francois ,
The implementation is very simple, but bear in mind that this is implemented on my SIP Trunk platform which uses OpenSIPS, not FusionPBX or FreeSWITCH.
An set of iptables rules to implement hit counters could be set up as follows, make sure the counters are above any rule allowing established, related etc.:
Code:
iptables -A INPUT -p tcp --dport 5060 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 5060 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 -j DROP
iptables -A INPUT -p udp --dport 5060 -m state --state NEW -m recent --set
iptables -A INPUT -p udp --dport 5060 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 -j DROP
Then you could use a shell script to add accept rules above (in front of) the hit counters. The shell script will need to create a mutex (lock) so only one instance of it can run at once (I use directories and not files because directory creation is an atomic operation). The shell script will also need to check if the IP address already has an accept rule. Here is an example script, I named it osiptables:
Code:
#!/bin/bash
IPTABLES=/sbin/iptables
IPSUDO=/usr/bin/sudo
GREP=/bin/grep
WORDCOUNT=/usr/bin/wc
RMDIR=/bin/rmdir
MKDIR=/bin/mkdir
SLEEP=/bin/sleep
LOCKDIR=/run/lock/osiptables
LOCKED=0
function getlock {
while [ $LOCKED -eq 0 ]; do
if $MKDIR $LOCKDIR >/dev/null 2>&1; then
LOCKED=1
else
while [ -d "$LOCKDIR" ]; do
$SLEEP 0.2
done
fi
done;
}
getlock
IPCOUNT=`$IPSUDO $IPTABLES -nL INPUT | $GREP -- "$1" | $WORDCOUNT -l`
if [ $IPCOUNT -eq 0 ]; then
$IPSUDO $IPTABLES -I INPUT -s $1 -j ACCEPT
fi
$RMDIR $LOCKDIR
exit 0
Then in the OpenSIPS routing script, you just need to call the shell script when a successful registration occurs, I also log the IP addresses to a database table using the avp_db_query function:
Code:
# add firewall rule to whitelist ip addresses from users that register successfully
exec("/usr/local/bin/osiptables '$si'");
avp_db_query("INSERT INTO ip_register(account, ip_address) VALUES('$(au{s.escape.common})', '$si') ON DUPLICATE KEY UPDATE status='C', created_date=Now()");
I hope that is helpful.