Don't take it wrong, Fail2ban is an excellent tool to prevent brute-force attacks. However, sometimes there are production scenarios where you need to keep your door slightly open. It is the classic dilemma security vs utilization; in pro fo the security, you may have a lot of countermeasures that will block many things, depending your paranoia, you may close as much as you want to a point that you may start to have false positives; in pro of the production you may need to keep up and running your service no matter what, you even will need to accept some brute-force attacks from "clean" IPs.
As I have described in my Hardening your PBX article, the importance of PBX is to be there when you need it. In order to archive that, I had to keep half-open a door. What I mean is that all IP's where people are registered are automatically whitelisted. This will allow being sure that the service is up, even when another phone is trying to register with a wrong IP; think on the NAT cases, when more than one phone registered using the same IP, if one phone tries three times the wrong password, all the customer's phones could be banned because of that. Remember Fail2ban only sees public IP's in a hosted PBX environment.
In this picture, the red lines are bad traffic, the blue lines are good traffic and the purple lines are the mix of good and bad traffic.
As your VoIP business comes popular, your domain as well. Users will change passwords through your PBX web interface, phones are going to be recycled and sooner than later you will have some "orphan" IP phones trying to register to an inexistent extension or domain. The problem is not that the hit will succeed, it won't. The problem is that that hit waste a lot of resources. Because it doesn't exist, it is not in the FreeSWITCH cache (Memcached), then it will need to do some database queries and expend some I/O writing in the log. The resources used to query the database are expensive for the PBX, writing the log it is not a big deal since Linux can handle that correctly, but if you are using Fail2ban, you will realize that Fail2ban CPU and memory utilization increase as the log activity does as well. One extension using a whitelisted IP and trying to register to an inexistent user or domain is not a big deal but now think on 100 telephones doing that. Your PBX will be struggling hard.
If you wonder if you are in this scenario, check your FreeSWITCH log and look for lines like the following:
If you have this kind of lines, and the given IP is whitelisted (regardless if it is flagged by a dynamic or a static method) it is very likely you are in the situation described by this article.
My proposal is easy, a service that blocks any SIP signal that identifies itself using an inexistent user or domain. So, how would you do that? You will need to parse in real time the FreeSWITCH log. The good thing is that FreeSWITCH will complain if the user or domain is inexistent. Once you have the right combination of user and domain, you just need to verify the iptables rules, if the rule does not exist, you just insert it (tip: use the string module).
This approach will only allow one hit per combination, the following won't hit the PBX. Your database will be less busy, you will have a better PBX performance and your CPU will be doing PBX work (Fail2ban won't be using a lot of I/O and CPU). See in the picture, the line between the firewall and the FreeSWITCH is blue, which means it is only valid traffic.
Take the following example:
iptables -A INPUT -p udp -m udp --dport 5060 -m string --string "Authorization: Digest username=\"101\", realm=\"mydomain.pbx.to-call.me\"" --algo bm --to 65535 -j LOG --log-prefix "[unexistant-registration]"
Unfortunately, these scripts are not public. If you need them you will need to hire my services. If you are a seasoned sysadmin, you know what to do.
At this moment, if the IP phone configuration is fixed (let's say, someone has changed the password in the PBX but forgot to update their IP Phone), you will need to flush manually or with a crontab the iptables rules.
I will be working on a Fail2ban approach, which I think it would be better as the combination would be automatically unbanned. I will update this article as this gets better.
UPDATE: After some research, I found no way to send a parameter fo the action definition from the regular expression. You can send static parameters to actions, but a dynamic value taken from the regular expression not. Not at least in Fail2ban 0.10 where I did research. If someone knows how I would appreciate an explanation.
Because of this, the way to do it is by using the at command. Just add an at now + 1 hour command to remove the iptables rule.
Good luck!blog comments powered by Disqus