在Internet上部署sip服务器的学生都知道,各种各样的服务器scanner不停的探测,尝试各种呼叫规则,尝试各类国际呼叫,如果没有前置防火墙,会被烦死,笔者就亲见因sip由于国际长途费用巨大,用户密码设置过于简单,被恶意盗打国际长途案件也被报警。作者今天就做FreeSWITCH CentOS7.9 firewalld fail2ban单机在internet以部署为例,实战讲解sip安全加固。
假设你已经安装并理解了这篇文章的内容firewalld和fail2ban,否则,你应该先回头看看这两个,否则很难理解配置。此外,操作系统加固和sip本文不讨论用户密码加固。
本文的本质在于firewalld其中使用的理解PREROUTING_direct链条已内置firewalld中。不能使用永久禁止PREROUTING_direct,只使用PUBLIC_direct,但对于临时检测sip攻击,要有效配合fail2ban封禁,最好使用PREROUTING_direct,否则,你会发现临时禁令可能会失效,至于为什么,有赖于您对firewalld和iptables的理解。
实战前,先在firewalld上放行sip,注意,没用sip service方法,主要是不想用 系统的nf_conntrack_sip。
#FreeSWITCH端口设置为5060 firewall-cmd --permanent --zone=public --add-port=5060/udp #FreeSWITCH RTP端口范围为16000-32000 firewall-cmd --permanent --zone=public --add-port=16000-32000/udp
一、永久封禁已知的几种sip scanner,如下:
firewall-cmd --permanent --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5060 -m string --string "VaxSIPUserAgent" --algo bm -j DROP firewall-cmd --permanent --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5060 -m string --string "friendly-scanner" --algo bm -j DROP firewall-cmd --permanent --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5060 -m string --string "sipcli" --algo bm -j DROP firewall-cmd --permanent --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5080 -m string --string "VaxSIPUserAgent" --algo bm -j DROP firewall-cmd --permanent --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5080 -m string --string "friendly-scanner" --algo bm -j DROP firewall-cmd --permanent --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5080 -m string --string "sipcli" --algo bm -j DROP
在信令中sip agent,直接禁止。按照这个模板,你也可以在项目中遇到其他事情。sip scanner加入其中直接禁掉,请注意用到了firewalld内置的PREROUTING_direct链。
二、配置fail2ban对检测到的sip攻击ip临时封禁。
1、安装fail2ban后,在centos7.9 firewalld在/环境中etc/fail2ban/jail.d/下增加freeswitch.conf,内容如下:
[freeswitch] enabled = true port = 5060,5061 action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"] %(default/action_)s[name=%(__name__)s-udp, protocol="udp"] logpath = /opt/freeswitch/log/freeswitch.log findtime = 5m bantime = 240h maxretry = 5
其中的logpath根据自己的实际目录配置路径。
2.此时可查看/etc/fail2ban/jail.d/00-firewalld.conf,fail2ban使用的默认ban/unban动作是firewall-rich-rules:
[DEFAULT] banaction = firewallcmd-rich-rules[actiontype=<multiport>] banaction_allports = firewallcmd-rich-rules[actiontype=<allports>]
启动fail2ban,用测试工具故意向FreeSWITCH虽然恶意用户注册,虽然fail2ban这次检测到了scanner攻击,也针对scanner ip进行了ban但实际上,操作FreeSWITCH大量的日志仍然显示在日志中scanner存在,意即scanner发的sip包仍到达了FreeSWITCH,封禁失败。
使用firewall-cmd查看active zone(public)的rich rules,可见添加剂rich-rules:
rich rules: rule family="ipv4" source address="192.168.1.12" port port="5060" protocol="tcp" drop rule family="ipv4" source address="192.168.1.12" port port="5061" protocol="tcp" drop rule family="ipv4" source address="192.168.1.12" port port="5060" protocol="udp" drop rule family="ipv4" source address="192.168.1.12" port port="5061" protocol="udp" drop
使用iptables查看对应的规则如下:
Chain IN_public_deny (1 references) target prot opt source destination DROP tcp -- 192.168.1.12 0.0.0.0/0 tcp dpt:5060 ctstate NEW,UNTRACKED DROP tcp -- 192.168.1.12 0.0.0.0/0 tcp dpt:5061 ctstate NEW,UNTRACKED DROP udp -- 192.168.1.12 0.0.0.0/0 udp dpt:5060 ctstate NEW,UNTRACKED DROP udp -- 192.168.1.12 0.0.0.0/0 udp dpt:5061 ctstate NEW,UNTRACKED
iptables列出的规则可以很好地解释这个问题配置是不可能的ban scanner ip是的,因为默认没有untrack、正在scan,不满足ctstate条件。
3、既然rich-rule模式不好,根据百度搜索结果,很多人建议使用ipset模式。所以重用firewallcmd-ipset来进行ban/unban修改/etc/fail2ban/jail.d/00-firewalld.conf
[DEFAULT] banaction = firewallcmd-ipset[actiontype=<multiport>] banaction_allports = firewallcmd-ipset[actiontype=<allports>]
再次启动测试工具方向FreeSWITCH恶意注册类似于2),fail2ban这次也检测到了scanner攻击,也针对scanner ip进行了ban操作,但仍禁止失败。
使用firewall-cmd查看direct规则:
ipv4 filter INPUT_direct 0 -p tcp -m multiport --dports 5060,5061 -m set --match-set f2b-freeswitch-tcp src -j REJECT --reject-with icmp-port-unreachable ipv4 filter INPUT_direct 0 -p udp -m multiport --dports 5060,5061 -m set --match-set f2b-freeswitch-udp src -j REJECT --reject-with icmp-port-unreachable
使用iptables查看规则:
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:67
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
INPUT_direct all -- 0.0.0.0/0 0.0.0.0/0
INPUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain INPUT_direct (1 references)
target prot opt source destination
REJECT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 5060,5061 match-set f2b-freeswitch-tcp src reject-with icmp-port-unreachable
REJECT udp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 5060,5061 match-set f2b-freeswitch-udp src reject-with icmp-port-unreachable
此时的conntrack记录:
ipv4 2 udp 17 179 src=192.168.1.12 dst=192.168.1.69 sport=5080 dport=5060 src=192.168.1.69 dst=192.168.1.12 sport=5060 dport=5080 [ASSURED] mark=0 zone=0 use=2
看到firewalld、iptables规则以及conntrack记录,对iptables和firewalld比较了解的同学估计也理解了为啥不能ban。。。
4、看了方法2和3的配置以及背后firewalld和iptable的规则,估计同学们有N种思路能让ban正常起来,本篇内容提供两种简单的方法,能让系统正常加固,抵御sip攻击:
1)方法1,启用NOTRACK
firewall-cmd --direct --add-rule ipv4 raw PREROUTING_direct 0 -p udp --dport 5060 -j NOTRACK
2)方法2,配置fail2ban使用firewalld内置的PREROUTING _direct链
使用方法1虽然能对检测到的sip攻击进行封禁,但NOTRACK的方法毕竟对业务路由可能会有影响,这催生了方法2,仅修改fail2ban的默认配置,使用firewalld内置的PREROUTING_direct链就能很完美的实现检测并封禁的功能,如下:
第一步,/etc/fail2ban/jail.d/00-firewalld.conf中使用firewall-ipset
第二步,修改/etc/fail2ban/action.d/firewallcmd-ipset.conf
将actionstart和actionstop中的filter修改为raw,如下:
[Definition]
actionstart = ipset create <ipmset> hash:ip timeout <default-ipsettime> <familyopt>
firewall-cmd --direct --add-rule <family> raw <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
actionflush = ipset flush <ipmset>
actionstop = firewall-cmd --direct --remove-rule <family> raw <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
<actionflush>
ipset destroy <ipmset>
将chain改为PREROUTING_direct,如下:
[Init]
# Option: chain
# Notes specifies the iptables chain to which the fail2ban rules should be
# added
# Values: [ STRING ]
#
chain = PREROUTING_direct
第三步,修改/etc/fail2ban/action.d/firewallcmd-common.conf
将blocktype改为DROP,如下:
# Option: blocktype (ipv4/ipv6)
# Notes See iptables/firewalld man pages for jump targets. Common values are REJECT,
# REJECT --reject-with icmp-port-unreachable, DROP
# Values: STRING
#blocktype = REJECT --reject-with <rejecttype>
blocktype = DROP
改完重启fail2ban测试,仅仅通过简单修改fail2ban配置,完美解决了检测sip攻击并封禁的问题。