顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-SIP安全

介绍

运行在公网的FreeSWITCH服务器,每天都会接收到很多恶意的呼叫请求和注册请求,尝试盗打电话。合理的配置可以降低给盗打的风险,但是每天大量的攻击,会让FS产生很多日志,降低FreeSWITCH的处理能力,cti模块结合fail2ban可以把恶意IP,使用防火墙封堵掉。

注意任意单一的配置都无法完全杜绝盗打风险,做好网络安全配置,使用复杂密码,定期修改密码,可以有效降低盗打风险,需要时时刻刻警惕,一刻也不能麻痹大意。任何暴露在公网的服务(SSH,数据库,redis,SIP等),都需要设置复杂的密码和安全的访问策略,预防破解和攻击。

防盗打配置

非常重要的,不要开通国际长途。其次对于呼出拨号方案和呼入路由要小心配置。

  1. sip配置里面的external默认是可以任意呼入,默认的呼叫路由是public,public这个路由绝对不要启用呼叫外线功能。
  2. sip配置里面如果新加了sip项目也同第一点。
  3. sip配置里面的internal这个是用来分机注册的,auth-calls 必须是勾选,千万不能吧这个勾选去除。
  4. 分机配置里分机密码设置复杂些。不要勾选allow-empty-apssword。
  5. 对于提供给网关注册的分机的呼叫路由改成pulibc。
  6. 呼叫外线的拨号方案要谨慎启用。如果不需要分机拨打外线,千万不要启用呼叫外线的拨号方案,有分机拨打外线的需求是只能在internal路由可以启用呼叫外线的拨号方案。启用了呼叫外线,要确定sip->internal->auth-calls 是勾选的,所有分机密码也要改成足够复杂的,并且要测试一下注册错误的情况下,直接拨号是否可以拨打出去,来验证配置准确无误。
  7. 如果只有浏览器(wss)可以拨打外线,可以把sip->internal->sip-port 配置的 udp的sip端口防火墙封了去,只放开wss端口。

限制呼入

建议external可以设置成只有指定的IP才可以呼入,设置方法如下

  1. sip设置external的apply-inbound-acl设置为inbound,auth-calls 不要勾选,注意internal的auth-calls 必须勾选。

  2. ccadmin的配置文件有acl.conf,就应该ccadmin->配置文件->acl.conf的inbound 添加允许的IP,对应的XML格式如下。

    <list name="inbound" default="deny">
    <node type="allow" cidr="允许呼入的IP1/32"/>
    <node type="allow" cidr="允许呼入的IP2/32"/>
    </list>

封堵原理

cti 模块发现注册失败或者 不规范的SIP报文,或者被叫号码不符合cti.json配置的规范,就写入日志到cti_fail2ban.log,fail2ban通过监视日志把恶意IP加入防火墙,封堵恶意IP。如果使用的是顶顶通发布的fs,不需要fail2ban,也可以直接配置国外IP直接封堵,以及可以根据cti.json配置的规则来封堵。

CTI配置

cti.json 配置被叫号码规范

"fail2ban": {
"password_minimum":6, //密码最小6位
"password_strength": 3, //0:没要求 1:必须包含数字、小写字母、大写字母、特殊符号中的1种以上,2:必须包含2种以上 3(默认值):必须包含3种以上,4:必须4种都包含。

"filename": "cti_fail2ban.log",

/*注册失败(认证失败)的封堵策略*/
"register_failure":[
{
"findtime":60, //分析最近多少秒的失败记录
"maxretry":3, //鉴权最大失败次数,超过就封堵这个IP或者账户
"banmode":1, //封堵方式 0: 根据IP封堵,1:分机和IP都一样才封堵,可以避免只要一个分机错了密码,就直接把这个IP封堵了。
"bantime":180 //封堵时间单位秒,默认180秒
}
],
/*呼入失败(ACL拒绝)的封堵策略*/
"forbidden_call":[
{
"findtime":60, //分析最近多少秒的失败记录
"maxretry":3, //鉴权最大失败次数,超过就封堵这个IP或者账户
"bantime":180 //封堵时间单位秒,默认180秒
}
],
/*状态错误(比如呼入要求认证但是没收到认证请求)的封堵策略*/
"wrong_call_state":[
{
"findtime":60, //分析最近多少秒的失败记录
"maxretry":3, //鉴权最大失败次数,超过就封堵这个IP或者账户
"bantime":180 //封堵时间单位秒,默认180秒
}
]
/*无效呼入(拨号方案1秒内执行完成未接通也没挂机)的封堵策略*/
"invalid_incoming":[
{
"findtime":60, //分析最近多少秒的失败记录
"maxretry":3, //鉴权最大失败次数,超过就封堵这个IP或者账户
"bantime":180 //封堵时间单位秒,默认180秒
}
]
}
  • password_minimum 分机密码最小6位
  • password_strength 分机密码 0:没要求 1:必须包含数字、小写字母、大写字母、特殊符号中的1种以上,2:必须包含2种以上 3(默认值):必须包含3种以上,4:必须4种都包含。
  • filename 恶意访问记录文件名,如果不用绝对路径,默认路径是fs的日志目录。
  • register_failure 注册失败后cti封堵策略
    • findtime 分析最近多少秒的失败记录
    • maxretry 鉴权最大失败次数,超过就封堵这个IP或者账户
    • banmode 封堵方式 0: 根据IP封堵,1:分机和IP都一样才封堵,可以避免只要一个分机错了密码,就直接把这个IP封堵了。
    • bantime 封堵时间单位秒,默认180秒
  • forbidden_call\wrong_call_state\invalid_incoming 这3个配置,需要顶顶通发布的FS1.10.14之后版本才支持。

查看封堵信息和已经加载的配置

fs_cli -x “cti show ban”

forbidden_call_config:  配置
findtime:60 maxretry:1 banmode:0 bantime:60
forbidden_call_bandata: 封堵数据
forbidden_call_history: 触发封堵的历史请求
wrong_call_state_config:
findtime:120 maxretry:10 banmode:0 bantime:120
wrong_call_state_bandata:
wrong_call_state_history:
register_failure_config:
findtime:120 maxretry:30 banmode:0 bantime:60
findtime:60 maxretry:3 banmode:1 bantime:60
register_failure_bandata:
register_failure_history:
invalid_incoming_config:
findtime:120 maxretry:10 banmode:0 bantime:120
invalid_incoming_bandata:
invalid_incoming_history:

查看fs版本是否支持封堵

fs_cli -x “sofia_show_ban”

不支持的版本会显示没有这个命令,支持的版本会输出fs实际已经封堵的Ip,不支持封堵的FS版本需要搭配fail2ban来封堵。

FreeSWITCH安全加强

mod_cti 2.02版本开始已经内置了安全加强。

即使cti.json->fail2ban不包含password_minimum、password_strength、register_failure配置,也会默认加上面的配置,如果需要改变配置参数,把这几个参数加入cti.json->fail2ban段,就可以设置合适你要求的封堵参数。

  1. 如果密码太短了,或者太简单了,直接返回认证失败,预防用户大意了。

  2. 如果同一IP,多次注册一个账户失败,直接让这个IP,指定时间内都不能注册这个账户。预防暴力破解密码。为了尽量减少误杀,影响正常使用,所以默认不是直接根据IP来封杀,是结合IP和账户来封杀。

  3. 给internal强制要求勾选auth-calls。 防止用户配置错误

  4. external必须配置apply-inbound-acl。 防止用户配置错误

  5. external的默认拨号方案,不允许为internal或者default. 防止用户配置错误。

注意:sip配置如果检测到不符合上面要求,会无法加载。

fail2ban配置

以下是安装和配置fail2ban的过程。如果不安装fail2ban,只配置cti.json的规则,只能挂断不符合规范的呼叫,不能杜绝攻击,需要安装配置好fail2ban,把非法Ip加入防火墙黑名单。
为了防止开发测试过程误触发屏蔽规则,导致开发机器连接不上服务器,建议把开发电脑的外网IP加入白名单。

安装fail2ban

yum安装

yum install fail2ban -y

源代码安装

git clone https://github.com/fail2ban/fail2ban.git
或者
wget https://github.com/fail2ban/fail2ban/archive/refs/tags/1.0.2.tar.gz
tar xzvf 1.0.2.tar.gz
cd fail2ban-1.0.2
python setup.py install
cp build/fail2ban.service /usr/lib/systemd/system

编辑jail.conf

cd /etc/fail2ban
mv jail.conf jail.conf.local
vi jail.conf
把以下内容写如 jail.conf

[cti]
enabled = true
filter = cti
action = iptables-allports[name=cti, protocol=all]
logpath = /ddt/fs/log/cti_fail2ban.log
bantime = 86400
maxretry = 5
findtime = 300
ignoreip = 127.0.0.1/8
backend = auto

配置说明:

  • logpath 监视cti记录的异常IP日志。
  • bantime 封堵时间,单位秒,86400秒就是24小时。
  • maxretry findtime(180秒)时间内日志文件出现的IP超过maxretry(5)次就封堵。
  • ignoreip ip白名单

设置日志文件权限

给/ddt/fs/log/目录修改安全上下文
chcon -R -t var_log_t /ddt/fs/log
也可以直接关闭sulinux,如果不修改安全上下文,会导致fail2ban启动失败

设置filter

vi /etc/fail2ban/filter.d/cti.conf
把以下内容写入 /etc/fail2ban/filter.d/cti.conf

[Definition]
failregex = ^ip\[<HOST>\].*
ignoreregex =

设置开机启动fail2ban

systemctl enable fail2ban

启动fail2ban

systemctl start fail2ban

查看fail2ban启动状态

systemctl status fail2ban

查看被ban IP,其中cti为名称

fail2ban-client status cti

如果 File list 看不到文件名,说明fs还没启动,需要先启动fs,然后“systemctl restart fail2ban”重启fail2ban,必须File list 看到了日志文件名才可以。

Status for the jail: cti
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| - File list: /ddt/fs/log/cti_fail2ban.log- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list: 0

手动封堵一个IP

fail2ban-client set cti banip IP地址

手动解封一个IP

fail2ban-client set cti unbanip IP地址

添加白名单

fail2ban-client set cti addignoreip IP地址

删除白名单

fail2ban-client set cti delignoreip IP地址

查看被禁止的IP地址

iptables -L -n