Sometimes it's impossible to put Kamailio in a front of third-party SIP software and it's nice to have sort of SIP firewall upfront.
One of solutions - use iptables (like I did a long ago here), but overall, IPTables is not a SIP processing engine. But Kamailio is.
So, idea is quite simple. We have our main PBX software sitting on ethX (or ensXX), port 5060. We're mirroring SIP traffic on this interface:port to localhost, where Kamailio is listens to them in promiscuous mode. And writing a log file, Fail2Ban can analyze.
Target here - is to protect main PBX software from consuming a lot of resources on fake INVITE's and REGISTER's from not-too-friendly-scanners.
First - install Kamailio.
I prefer to put syslog messages to separate file.
Configure Kamailio with file
/etc/kamailio/kamailio.cfg
#!KAMAILIO
#!define WITH_ANTIFLOOD
#!define WITH_DOMAIN_NAMES
#!define WITH_SANITY_CHECK
#!define WITH_SCANNER_BODY
#!define WITH_SCANNER_MESSAGE
debug=2
log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL7
children=6
auto_aliases=no
listen=udp:127.0.0.1:5060
loadmodule "sl.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "regex.so"
loadmodule "sipcapture.so"
loadmodule "db_text.so"
# ----------------- setting module-specific parameters ---------------
modparam("sipcapture", "db_url", "text:///tmp/")
modparam("sipcapture", "raw_socket_listen", "127.0.0.1:5060")
modparam("sipcapture", "raw_moni_capture_on", 1)
modparam("sipcapture", "raw_interface", "lo")
modparam("sipcapture", "promiscious_on", 1)
#!ifdef WITH_ANTIFLOOD
loadmodule "pike.so"
# ----- pike params -----
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 16)
modparam("pike", "remove_latency", 4)
loadmodule "htable.so"
# ----- htable params -----
/* ip ban htable with autoexpire after 5 minutes */
modparam("htable", "htable", "ipban=>size=8;autoexpire=300;")
#!endif
####### Routing Logic ########
request_route {
#!ifdef WITH_ANTIFLOOD
# flood detection from same IP and traffic ban for a while
# be sure you exclude checking trusted peers, such as pstn gateways
# - local host excluded (e.g., loop to self)
if(src_ip!=myself) {
if($sht(ipban=>$si)!=$null) {
# ip is already blocked
xlog("L_NOTICE", "[SIP-FIREWALL][ANTIFLOOD-BANNED] [F=$fu R=$ru D=$du M=$rm IP=($si:$sp $Ri:$Rp) ID=$ci]\n");
exit;
}
if (!pike_check_req()) {
$sht(ipban=>$si) = 1;
xlog("L_NOTICE", "[SIP-FIREWALL][ANTIFLOOD-ADD] [F=$fu R=$ru D=$du M=$rm IP=($si:$sp $Ri:$Rp) ID=$ci]\n");
xlog("L_ALERT", "[SIP-FIREWALL][FAIL2BAN] $si\n");
exit;
}
}
#!endif
#!ifdef WITH_SCANNER_MESSAGE
if (search("friendly-scanner|sipvicious|sipcli*|vaxasip|sip-scan|iWar|sipsak")) {
xlog("L_NOTICE", "[SIP-FIREWALL][FRIENDLYSCANNER_MESSAGE]: [F=$fu R=$ru D=$du M=$rm IP=($si:$sp $Ri:$Rp) ID=$ci]");
xlog("L_ALERT", "[SIP-FIREWALL][FAIL2BAN] $si\n");
exit;
}
#!endif
#!ifdef WITH_SCANNER_BODY
if (search_body("friendly-scanner|sipvicious|sipcli*|vaxasip|sip-scan|iWar|sipsak")) {
xlog("L_NOTICE", "[SIP-FIREWALL][FRIENDLYSCANNER_BODY]: [F=$fu R=$ru D=$du M=$rm IP=($si:$sp $Ri:$Rp) ID=$ci]");
xlog("L_ALERT", "[FAIL2BAN] $si\n");
exit;
}
#!endif
#!ifdef WITH_SANITY_CHECK
if(!sanity_check("17895", "7")) {
xlog("L_NOTICE", "[SIP-FIREWALL][MALFORMED] [F=$fu R=$ru D=$du M=$rm IP=($si:$sp $Ri:$Rp) ID=$ci]\n");
xlog("L_ALERT", "[SIP-FIREWALL][FAIL2BAN] $si\n");
exit;
}
#!endif
#!ifdef WITH_DOMAIN_NAMES
if (!is_method("INVITE|REGISTER")) {
exit;
}
if (pcre_match("$rd", "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$$")) {
if (pcre_match("$fd", "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$$")) {
xlog("L_NOTICE", "[SIP-FIREWALL][NOT_DOMAIN_BASED_URI]: [F=$fu R=$ru D=$du M=$rm IP=($si:$sp $Ri:$Rp) ID=$ci]");
xlog("L_ALERT", "[SIP-FIREWALL][FAIL2BAN] $si\n");
exit;
}
}
#!endif
}
It's actually my file, but you can adopt rules to yours.
Next - set up Fail2Ban
/etc/fail2ban/filter.d/kamailio.conf
[Definition]
# filter for kamailio messages
failregex = [SIP-FIREWALL][FAIL2BAN] <HOST>
/etc/fail2ban/jail.conf
...
[kamailio-iptables]
enabled = true
filter = kamailio
action = iptables-allports[name=KAMAILIO, protocol=all]
logpath = /var/log/kamailio.log
maxretry = 5
bantime = 1800
findtime = 60
Next - make sure you don't have net.ipv4.ip_forward set to 1. You will run into infinite loops in this case
# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
And last - use iptables TEE target to mirror traffic to localhost
# iptables -A PREROUTING -t mangle -i eth0 -p udp --dport 5060 -j TEE --gateway 127.0.0.1
That's it.
Showing posts with label iptables. Show all posts
Showing posts with label iptables. Show all posts
Monday, October 28, 2019
Monday, June 23, 2014
Примитивный L7 DPI на iptables
Оказывается, начиная с ядра 2.6.14 в Debian (Ubuntu) iptables умеет анализировать пакет текстово с помощью модуля string.
Поэтому можно сделать некий примитивный DPI. У меня есть задача не пропускать на сервер только пакеты SIP REGISTER и INVITE (INVITE допускается только с определенных адресов). Поэтому родилось что-то типа
iptables -A INPUT -m string --string "INVITE sip:" --algo bm -i eth0 -s X.X.X.X/255.255.255.255 -p udp --dport 5060 -j ACCEPT
iptables -A INPUT -m string --string "INVITE sip:" --algo bm -i eth0 -p udp --dport 5060 -j DROP
iptables -A INPUT -m string --string "INVITE sip:" --algo bm -i eth0 -p tcp --dport 5060 -j DROP
iptables -A INPUT -m string --string "REGISTER sip:" --algo bm -i eth0 -p udp --dport 5060 -j DROP
iptables -A INPUT -m string --string "REGISTER sip:" --algo bm -i eth0 -p tcp --dport 5060 -j DROP
По мотивам: http://www.linuxquestions.org/questions/linux-networking-3/iptables-rules-against-udp-flood-and-ddos-attack-789950/
Поэтому можно сделать некий примитивный DPI. У меня есть задача не пропускать на сервер только пакеты SIP REGISTER и INVITE (INVITE допускается только с определенных адресов). Поэтому родилось что-то типа
iptables -A INPUT -m string --string "INVITE sip:" --algo bm -i eth0 -s X.X.X.X/255.255.255.255 -p udp --dport 5060 -j ACCEPT
iptables -A INPUT -m string --string "INVITE sip:" --algo bm -i eth0 -p udp --dport 5060 -j DROP
iptables -A INPUT -m string --string "INVITE sip:" --algo bm -i eth0 -p tcp --dport 5060 -j DROP
iptables -A INPUT -m string --string "REGISTER sip:" --algo bm -i eth0 -p udp --dport 5060 -j DROP
iptables -A INPUT -m string --string "REGISTER sip:" --algo bm -i eth0 -p tcp --dport 5060 -j DROP
По мотивам: http://www.linuxquestions.org/questions/linux-networking-3/iptables-rules-against-udp-flood-and-ddos-attack-789950/
Subscribe to:
Posts (Atom)