- # 使用`Fail2Ban`防止sip攻击`FreeSWITCH`
- `FreeSWITCH`在公网运行容易遭受sip攻击,解决的办法有很多种,而`Fail2Ban`安装配置以及调试比较简单,不失为一种好的选择。
- `Fail2Ban`版本很多,配置方式略有差别。
- 本次测试是基于`Fail2Ban 0.9.`版本,其他相关信息如下:
- - Debian9
- - FreeSWITCH 1.10.,`base_dir`是`/usr/local/freeswitch`
- ## 安装`Fail2Ban`
- ```shell
- cd /usr/src; git clone https://github.com/fail2ban/fail2ban.git -b 0.9.6
- cd /usr/src/fail2ban; python3 setup.py install
- #配置成服务
- cp files/debian-initd /etc/init.d/fail2ban
#centos
cp files/redhat-initd /etc/init.d/fail2ban
- https://github.com/fail2ban/fail2ban/blob/0.11/files/redhat-initd
- update-rc.d fail2ban defaults
- service fail2ban start
- ```
- ## 配置`iptables`
- ```shell
- iptables -A INPUT -i lo -j ACCEPT
- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- iptables -A INPUT -p tcp --dport -j ACCEPT
- iptables -A INPUT -p tcp --dport -j ACCEPT
- iptables -A INPUT -p tcp --dport -j ACCEPT
- iptables -A INPUT -p tcp --dport -j ACCEPT
- iptables -A INPUT -p tcp --dport -j ACCEPT
- iptables -A INPUT -p tcp --dport : -j ACCEPT
- iptables -A INPUT -p udp --dport -j ACCEPT
- iptables -A INPUT -p tcp --dport -j ACCEPT
- iptables -A INPUT -p udp --dport -j ACCEPT
- iptables -A INPUT -p udp --dport : -j ACCEPT
- iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
- iptables -P INPUT DROP
- iptables -P FORWARD DROP
- iptables -P OUTPUT ACCEPT
- ```
- ## 配置 `FreeSWITCH`
- . sip_profiles/internal.xml
- ```
- <param name="log-auth-failures" value="true"/>
- ```
- . autoload_configs/switch.conf.xml 要修改一个配置项目
- ```
- <param name="threaded-system-exec" value="true"/>
- ```
- ## 配置 fail2ban
- ### 配置 freeswitch jail
- 找到 `/etc/fail2ban/jail.conf` 的 freeswitch 段,修改成下面这样:
- ```
- [freeswitch]
- enabled = true
- port = ,,
- action = iptables-allports[name=freeswitch, protocol=all]
- logpath = /usr/local/freeswitch/log/freeswitch.log
- filter = freeswitch
- maxretry =
- bantime = -
- findtime =
- ignoreip = 127.0.0.1/ 192.168.0.0/ 10.0.0.0/ 172.16.0.0/
- ```
- 其中:
- * port = ,, # sip profile 的端口
- * action = iptables-allports[name=freeswitch, protocol=all] # 这里不用改动
- * logpath = /usr/local/freeswitch/log/freeswitch.log # freeswitch.log的全路径
- * filter = freeswitch #这里不用改动
- * maxretry = # 尝试次数
- * bantime = - # - 永久 ban(禁止)
- * findtime = # 发现的时间,这几个参数合起来的意思就是,如果 小时内检查到 哪个 IP 地址,做了 次尝试,那么永久禁止他
- * ignoreip = 127.0.0.1/ 192.168.0.0/ 10.0.0.0/ 172.16.0.0/ # ip 白名单
- ### 配置 freeswitch filter
- 修改`/etc/fail2ban/filter.d/freeswitch.conf`,改成下面这样:
- ```
- # Fail2Ban configuration file
- #
- # Enable "log-auth-failures" on each Sofia profile to monitor
- # <param name="log-auth-failures" value="true"/>
- # -- this requires a high enough loglevel on your logs to save these messages.
- #
- # In the fail2ban jail.local file for this filter set ignoreip to the internal
- # IP addresses on your LAN.
- #
- [Definition]
- #failregex = ^\.\d+ \[WARNING\] sofia_reg\.c:\d+ SIP auth (failure|challenge) \((REGISTER|INVITE)\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>$
- # ^\.\d+ \[WARNING\] sofia_reg\.c:\d+ Can't find user \[\d+@\d+\.\d+\.\d+\.\d+\] from <HOST>$
- failregex = ^\.\d+ \[WARNING\] sofia_reg\.c:\d+ SIP auth failure \((REGISTER|INVITE)\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>$
- ^\.\d+ \[WARNING\] sofia_reg\.c:\d+ Can't find user \[\d+@\d+\.\d+\.\d+\.\d+\] from <HOST>$
- ignoreregex =
- # Author: Rupa SChomaker, soapee01, Daniel Black
- # https://freeswitch.org/confluence/display/FREESWITCH/Fail2Ban
- # Thanks to Jim on mailing list of samples and guidance
- #
- # No need to match the following. Its a duplicate of the SIP auth regex.
- # ^\.\d+ \[DEBUG\] sofia\.c:\d+ IP <HOST> Rejected by acl "\S+"\. Falling back to Digest auth\.$
- ```
- 现在运行`systemctl restart fail2ban`重启服务
- 再运行 `fail2ban-client status`,输出如下:
- ```
- Status
- |- Number of jail:
- `- Jail list: freeswitch
- ```
- 运行`fail2ban-client status freeswitch`,输出如下:
- ```
- Status for the jail: freeswitch
- |- Filter
- | |- Currently failed:
- | |- Total failed:
- | `- File list: /usr/local/freeswitch/log/freeswitch.log
- `- Actions
- |- Currently banned:
- |- Total banned:
- `- Banned IP list:
- ```
- 现在试着ban一个ip,执行这个命令:
- ```
- fail2ban-client set freeswitch banip 113.113.113.113
- ```
- 然后用`fail2ban-client status freeswitch`查看
- ```
- Status for the jail: freeswitch
- |- Filter
- | |- Currently failed:
- | |- Total failed:
- | `- File list: /usr/local/freeswitch/log/freeswitch.log
- `- Actions
- |- Currently banned:
- |- Total banned:
- `- Banned IP list: 113.113.113.113
- ```
- 可以看到, `113.113.113.113` 这个地址已经被ban
- 执行这个命令`iptables -nvL --line-numbers`
- 输出如下:
- ```
- Chain INPUT (policy DROP packets, bytes)
- num pkts bytes target prot opt in out source destination
- 132K f2b-freeswitch all -- * * 0.0.0.0/ 0.0.0.0/
- ACCEPT all -- lo * 0.0.0.0/ 0.0.0.0/
- ACCEPT all -- * * 0.0.0.0/ 0.0.0.0/ state RELATED,ESTABLISHED
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpt:
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpt:
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpt:
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpt:
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpt:
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpts::
- ACCEPT udp -- * * 0.0.0.0/ 0.0.0.0/ udp dpt:
- ACCEPT tcp -- * * 0.0.0.0/ 0.0.0.0/ tcp dpt:
- ACCEPT udp -- * * 0.0.0.0/ 0.0.0.0/ udp dpt:
- ACCEPT udp -- * * 0.0.0.0/ 0.0.0.0/ udp dpts::
- ACCEPT icmp -- * * 0.0.0.0/ 0.0.0.0/ icmptype
- Chain FORWARD (policy DROP packets, bytes)
- num pkts bytes target prot opt in out source destination
- Chain OUTPUT (policy ACCEPT packets, bytes)
- num pkts bytes target prot opt in out source destination
- Chain f2b-freeswitch ( references)
- num pkts bytes target prot opt in out source destination
- REJECT all -- * * 113.113.113.113 0.0.0.0/ reject-with icmp-port-unreachable
- 132K RETURN all -- * * 0.0.0.0/ 0.0.0.0/
- ```
- 用这个命令解除,`fail2ban-client set freeswitch unbanip 113.113.113.113`
- ## 把 FreeSWITCH 运行起来,运行`tail -f /var/log/fail2ban.log`进行观察,再结合`/usr/local/freeswitch/log/freeswitch.log`的日志内容,进行调试,不断优化。
- ## fail2ban.lua
- 一般情况下`Fail2Ban`工作的很好,但还是有特殊的呼叫流程`Fail2Ban`抓不到。为此,笔者写了个`fail2ban.lua`,弥补`Fail2Ban`的不足
- . 修改`lua.conf.xml`,增加下面俩个配置项目:
- ```
- <hook event="CUSTOM" subclass="sofia::wrong_call_state" script="fail2ban.lua"/>
- <hook event="CUSTOM" subclass="sofia::register_failure" script="fail2ban.lua"/>
- ```
- 下面是`fail2ban.lua`的内容(代码比较简单,不再解释了):
- ```
- function OnEvent(e)
- local subclass = e:getHeader("Event-Subclass") or ""
- if string.find(subclass, "sofia::") ~= then return end
- local ip = e:getHeader("network_ip") or e:getHeader("network-ip")
- if not ip then return end
- local ua = e:getHeader("user-agent") or ""
- local to_user = e:getHeader("to-user") or ""
- local from_user = e:getHeader("from-user") or ""
- local auth_result = e:getHeader("auth-result") or ""
- local registration_type = e:getHeader("registration-type") or ""
- local s = string.format("*** %s, ip = %s, ua = %s, to = %s, from = %s, result = %s, type = %s\n", subclass, ip, ua, to_user, from_user, auth_result, registration_type)
- freeswitch.consoleLog("NOTICE", s)
- if subclass == "sofia::wrong_call_state" or subclass == "sofia::register_failure" then
- local cmd = "fail2ban-client set freeswitch banip " .. ip
- freeswitch.consoleLog("ERR", cmd .. "\n")
- os.execute(cmd)
- end
- end
- freeswitch.consoleLog("INFO", "fail2ban.lua, ===\n" .. event:serialize() .. "===\n")
- OnEvent(event)
- ```
- ## 参考资料:
- <https://docs.fusionpbx.com/en/latest/firewall/fail2ban.html>
- <https://docs.fusionpbx.com/en/latest/firewall/iptables.html>
- <https://freeswitch.org/confluence/display/FREESWITCH/Fail2Ban>
- https://blog.csdn.net/weixin_43103905/article/details/95060220
- 注意:
如果遇到报错“no directory /var/run/fail2ban to contain the socket file /var/run/fail2ban/fail2ban.sock”, 请手动创建相关文件夹:
mkdir /var/run/fail2ban
#开机启动
$ systemctl enable fail2ban
$ systemctl start fail2ban
以上就是centos配置Fail2Ban防止sip攻击`FreeSWITCH`的详细内容,更多关于centos配置Fail2Ban防止sip攻击`FreeSWITCH`的资料请关注九品源码其它相关文章!