Integrating apiban.org with FreePBX

The last few Open Source Lounge sessions have seen conversation around apiban.org, with last night’s session getting a detailed presentation by Fred Posner on how it all works. The apiban.org project is a SIP blacklist compiled from honeypots with a simple API that allows you to dynamically update iptables rules with known current attackers. Generally I’m not a fan of blacklists on principle, but there are obviously situations where whitelisting won’t work. If one is working with this constraint, a good strategy is to be proactive (blacklist) in addition to being reactive (fail2ban/responsive).

While last night’s session was in progress, I applied for an API key and did some basic API queries using a browser to get a sense of how it all worked. This morning I stopped fail2ban and opened the SIP ports to the internet on a test system (FreePBX 15, fail2ban stopped, firewall running, responsive disabled, sip services enabled for INTERNET zone) and started getting a flood of intrusion attempts almost immediately. I let the attackers have fun for most of the day, and periodically checked the offending IPs against the current apiban blacklist. All of the bad guys I was seeing were already present on the apiban blacklist; thing are looking good.

Set up the free apiban client on my FreePBX 15 Distro and created a cron task to run every 5 min. Instantly all of the offending IPs got blocked. I’ve restarted fail2ban and will continue to monitor for the next short while to make sure there are no surprise interactions with the FreePBX firewall or iptables, but initial success looks promising.

Steps to Setup apiban on FreePBX Distro

Step 1 - Browse to https://apiban.org/ and request an api key by email. Response is immediate

Step 2 - Browse to apiban clients github page https://github.com/palner/apiban/tree/master/clients and review the instructions there. At the time of this writing, this is:

Login as root, download and chown the files:

[root@pbx ~]# mkdir /usr/local/bin/apiban
[root@pbx ~]# cd /usr/local/bin/apiban
[root@pbx apiban]# wget https://github.com/palner/apiban/raw/master/clients/go/apiban-iptables-client
   **** snip ****
[root@pbx apiban]# chmod +x apiban-iptables-client
[root@pbx apiban]# wget https://raw.githubusercontent.com/palner/apiban/master/clients/go/apiban-iptables/config.json
   **** snip ****
[root@pbx apiban]# ls -l
total 7700
-rwxr-xr-x 1 root root 7878161 Aug 21 16:53 apiban-iptables-client
-rw-r--r-- 1 root root      59 Aug 21 16:54 config.json

Edit config.json and add your API key. API calls are limited to a small number per minute, so one key per PBX is recommended. Then run the client for the first time:

[root@pbx apiban]# ./apiban-iptables-client

Nothing appears to happen, but if you check the log:

[root@pbx apiban]# cat /var/log/apiban-client.log
2020/08/21 16:55:33 ** Started APIBAN CLIENT
2020/08/21 16:55:33 Licensed under GPLv2. See LICENSE for details.
2020/08/21 16:55:33 no command line arguments received
2020/08/21 16:55:33 IPTABLES doesn't contain APIBAN. Creating now...
2020/08/21 16:55:33 APIBAN chain was created - Resetting LKID
2020/08/21 16:55:34 failed to get banned list: unauthorized
2020/08/21 16:55:50 ** Started APIBAN CLIENT
2020/08/21 16:55:50 Licensed under GPLv2. See LICENSE for details.
2020/08/21 16:55:50 no command line arguments received
2020/08/21 16:55:51 Blocking 185.53.88.78/32
2020/08/21 16:55:51 Blocking 163.172.207.104/32
2020/08/21 16:55:51 Blocking 62.210.149.30/32
2020/08/21 16:55:51 Blocking 104.37.175.137/32
2020/08/21 16:55:51 Blocking 77.247.110.58/32
2020/08/21 16:55:51 Blocking 146.88.240.4/32
2020/08/21 16:55:51 Blocking 62.210.162.99/32
2020/08/21 16:55:51 Blocking 51.158.25.170/32
2020/08/21 16:55:51 Blocking 45.176.240.44/32
2020/08/21 16:55:51 Blocking 62.210.151.21/32
2020/08/21 16:55:51 Blocking 45.143.220.163/32
2020/08/21 16:55:51 Blocking 212.129.17.32/32
  ** snip **

And finally check iptables for the new rules:

[root@pbx apiban]# iptables-save | grep API
:APIBAN - [0:0]
-A INPUT -j APIBAN
-A FORWARD -j APIBAN
-A APIBAN -s 185.53.88.78/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 163.172.207.104/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 62.210.149.30/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 104.37.175.137/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 77.247.110.58/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 146.88.240.4/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 62.210.162.99/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 51.158.25.170/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 45.176.240.44/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 62.210.151.21/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 45.143.220.163/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 212.129.17.32/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 185.53.88.113/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 188.165.222.17/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 95.216.117.54/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 163.172.7.215/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 51.79.57.12/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 50.234.173.102/32 -j REJECT --reject-with icmp-port-unreachable
-A APIBAN -s 113.141.70.184/32 -j REJECT --reject-with icmp-port-unreachable
  ** snip **

Step 3 - create a cron task to automate everything

Edit the file /etc/crontab and add the following lines at the end

# update apiban iptables
*/5 * * * * root /usr/local/bin/apiban/apiban-iptables-client >/dev/null 2>&1
7 Likes

How many IPs did it end up actually generated rules for?

Current rules just under 400 IPs. Full log is here:
https://pastebin.freepbx.org/view/cc1d7ee1

Two days into this experiment, and I’m even more impressed than when I started. I’ve relaxed security on this test system to an unreasonable degree (allow SIP guests and allow anon calls so I can see everything logged) to see how much gets blocked just by the apiban blacklist. The first full day of operation was yesterday, and ZERO attempts made it inbound. We are 3/4 thru today, and I have exactly one anonymous call that made it through:

[2020-08-23 15:42:51] VERBOSE[3970][C-00000286] pbx.c: Executing [s@from-sip-external:7] Log("PJSIP/anonymous-00000285", "WARNING,"Rejecting unknown SIP connection from 104.140.53.83:5106"") in new stack

That call was logged today at 15:42, and within 13 minutes apiban had added the IP and it propagated to my system:

2020/08/22 15:55:01 ** Started APIBAN CLIENT
2020/08/22 15:55:01 Licensed under GPLv2. See LICENSE for details.
2020/08/22 15:55:01 no command line arguments received
2020/08/23 15:55:01 ** Started APIBAN CLIENT
2020/08/23 15:55:01 Licensed under GPLv2. See LICENSE for details.
2020/08/23 15:55:01 no command line arguments received
2020/08/23 15:55:01 Blocking 104.140.53.83/32
2020/08/23 15:55:01 ** Done. Exiting.

With no more intrusions.

2 Likes

What would it take to make it an official module of FreePBX?

Such a module would have to work in conjunction with the FreePBX firewall in order to get around the problem of the GUI user not having permission to alter iptables directly. The firewall module lacks a formal API endpoint to manage a list like this, but IPs could be added to the Firewall module blacklist using a script.

A better solution might be something more generic that would allow the PBX Firewall module blacklist to be populated by any blacklist service.

2 Likes

Day 3 - Hit a snag early this morning. At around 1:30am more than a thousand anonymous calls got through the firewall over the span of a few minutes. Anonymous calls are not intrusion attempts, but in the quantity I was seeing, they may have caused a DOS. An example:

[2020-08-24 01:29:06] VERBOSE[15458][C-00000711] pbx.c: Executing [s@from-sip-external:7] Log("PJSIP/anonymous-0000070b", "WARNING,"Rejecting unknown SIP connection from 103.145.13.184:45449"") in new stack
[2020-08-24 01:29:06] WARNING[15458][C-00000711] Ext. s: "Rejecting unknown SIP connection from 103.145.13.184:45449"

About 9 hours after this event, the offending IP 103.145.13.184 has still not been added to the apiban list.

This underscores what common sense already tells us, that a blacklist alone is not sufficient to secure a system.

@BlazeStudios IP ban list has grown to 468 IPs.

Monitoring continues.

cat /var/log/apiban-client.log|grep Blocking|grep 103.145.13

also supports my more aggressive policy of blocking the underlying network of the offending host (especially from high risk locations)

Obviously you need to be aware of things like apple and cox, and current extentions in that network, but /20 or smaller works

(that address is in VOIPBL though)

Yeah, this is why I just block pretty much everything but ARIN spaces and deal with only those spaces hitting the servers.

No need for anyone from Asia, etc. to be making SIP requests to my network.

This is an interesting project. A few years ago I worked with a European company that did this same thing using monitoring scripts on all their customers. Basically any customer that got junk traffic would block that traffic with fail2ban and then the IP would be propagated up to a central server where it would then be sent down to all other customers for blocking. There are some obvious holes in this plan but the “herd inoculation” seemed to block quite a lot.

I don’t know what the practical limits are on iptables but given the amount of junk SIP crossing the internet, I expect this project to hit those limits at some point.

I’ve been wondering this as well. One of the strengths of apiban is that it’s a current list of active SIP offenders, and it’s only pulling IPs from secret honeypots. The devs are concerned about malicious users poisoning their blacklist. Other blacklist projects are less selective about how they gather IPs. The one @dicko noted above appears to accept IPs submitted anonymously via their home page, tho I am sure they must be validating those somehow before publishing.

http://www.voipbl.org and http://www.voipbl.org/#advanced

make for good reading, They covers ipsets, asterisk, fail2ban , filtering by country and by network (ARIN et al) The list approaches 100000 so it definitely need ipsets as iptables will grind to a halt.

I can only say that of all the machines I am involved with that listen on 5060, none have suffered from a false positive from that list.

1 Like

The script looks like it is using individual iptables rules for each IP(and apparently without aggregation), so yes, at some point thousands of rules will have a negative impact from a performance and memory perspective. The better option would be to use ipset, then a single rule can efficiently handle hundreds of thousands addresses.

I use multiple blacklists and geoblocking, but mainly to cut down on what I log. My rulest is otherwise secure and I would be comfortable without any of the blacklists.

Blacklist and geo-blocked traffic is dropped early and logged to a separate “just in case I need it” file. It keeps the “real” log file clean and easier to parse. Makes it much easier to see if there is a real problem.

1 Like

What is a good use case for any of these blacklists? If you just need (for example) UDP SIP access from previously unknown IP addresses (mobile data, residential dynamic IP), whitelisting a ‘secret’ domain name is IMO greatly superior. It’s very simple, requires no maintenance and doesn’t depend on any third parties (other than your DNS provider). But most importantly, it blocks 100% of random attacks, so you can have fail2ban (or other IDS) alert you to even one banned IP, whether from a targeted attack or a misconfigured client.

A blacklist would make sense if you intentionally allow access from the public, for example with a ‘call me’ button on your website or by publishing a SIP URI. Although IMO both of these are bad ideas for reasons unrelated to security, they are popular so we should explore how to secure them. It’s a huge risk to expose a PBX directly to such traffic; a SIP proxy that forwards only the ‘public’ service to the PBX is a must. It’s the proxy that needs the blacklist to keep the swarm of bots from hammering it and DoS-ing the service. The PBX just needs to whitelist the proxy’s address.

Does this work regardless of the SIP client in use to randomly connect from wherever the users are?

AFAIK any SIP device or app less than 20 years old will accept a domain name for the server/proxy.

Ah, you mean to use SIP Domains?

What is the pjsip equivalent to the chan_sip domain = syntax?

hi, What´s diffenrent apiban vs geoip.

apiban cpu working?

No, I mean iptables is set up so SIP packets other than established/related are dropped if they don’t contain the domain name. A simplified example:

Combined with Apache configuration that rejects requests without the proper domain (admin GUI, UCP, provisioning, etc.) an attacker that doesn’t know the name will not even be able to discover that you have a PBX.

1 Like

Do you have another strategy for TLS connections or not use them?