非常详细的 使用`Fail2Ban`防止sip攻击`FreeSWITCH`教程 (一)

# 使用`Fail2Ban`防止sip攻击`FreeSWITCH`

 

`FreeSWITCH`在公网运行容易遭受sip攻击,解决的办法有很多种,而`Fail2Ban`安装配置以及调试比较简单,不失为一种好的选择。

 

`Fail2Ban`版本很多,配置方式略有差别。

 

本次测试是基于`Fail2Ban 0.9.6`版本,其他相关信息如下:

 

    - Debian9

 

- FreeSWITCH 1.10.3,`base_dir`是`/usr/local/freeswitch`

 

## 安装`Fail2Ban`

 

```shell

cd /usr/local/src;

git clone https://github.com/fail2ban/fail2ban.git -b 0.11.1

cd /usr/local/src/fail2ban;

python3 setup.py install

#配置成服务

ubuntu

cp files/debian-initd /etc/init.d/fail2ban

update-rc.d fail2ban defaults

centos

 

cp files/redhat-initd  /etc/init.d/fail2ban

chkconfig fail2ban on

 

yum install redhat-lsb -y

 

配置之后操作

service fail2ban start

 

服务器如果重启可能导致fail2ban启动失败,需要执行以下命令

sed -i 's@Starting fail2ban.*@&\n    [ ! -e "/var/run/fail2ban" ] \&\& mkdir /var/run/fail2ban@' /etc/init.d/fail2ban

systemctl daemon-reload

service fail2ban start

 

```

 

## 配置`iptables`

 

# iptables -D INPUT -s 120.5.142.230 -j DROP

iptables -D INPUT -s 120.5.5.158  -j DROP

iptables -A INPUT -s 101.17.88.2  -j ACCEPT

120.5.5.158

ACCEPT

```shell

 

 

iptables -A INPUT -p tcp --dport 5060:5061 -j ACCEPT

iptables -A INPUT -p udp --dport 5060 -j ACCEPT

iptables -A INPUT -p tcp --dport 5080 -j ACCEPT

iptables -A INPUT -p udp --dport 5080 -j ACCEPT

 

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -p tcp --dport 9922 -j ACCEPT

iptables -A INPUT -p udp --dport 6660 -j ACCEPT

iptables -A INPUT -p udp --dport 6880 -j ACCEPT

iptables -A INPUT -p tcp --dport 8831 -j ACCEPT

iptables -A INPUT -p tcp --dport 8899 -j ACCEPT

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

iptables -A INPUT -p tcp --dport 443 -j ACCEPT

iptables -A INPUT -p tcp --dport 7443 -j ACCEPT

iptables -A INPUT -p udp --dport 16384:32768 -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

```

禁止被扫描

```

iptables -I INPUT -j DROP -p tcp --dport 5060   --string "friendly-scanner" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5080 --string "friendly-scanner" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5060 --string "friendly-scanner" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5080 --string "friendly-scanner" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5060 --string "sipcli" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5080 --string "sipcli" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5060 -m string --string "sipcli" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5080 -m string --string "sipcli" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5060 -m string --string "Sippy" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5080 -m string --string "Sippy" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5060 -m string --string "Sippy" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5080 -m string --string "Sippy" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5060 -m string --string "VaxSIPUserAgent" --algo bm

iptables -I INPUT -j DROP -p tcp --dport 5080 -m string --string "VaxSIPUserAgent" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5060 -m string --string "VaxSIPUserAgent" --algo bm

iptables -I INPUT -j DROP -p udp --dport 5080 -m string --string "VaxSIPUserAgent" --algo bm

```

 

 

## 配置 `FreeSWITCH`

 

1. sip_profiles

 

```

<param name="log-auth-failures" value="true"/>

```

 

2. switch.conf.xml 要修改一个配置项目

 

```

<param name="threaded-system-exec" value="true"/>

```

 

## 配置 fail2ban

 

### 配置 freeswitch jail

 

找到 `/etc/fail2ban/jail.conf` 的 freeswitch 段,修改成下面这样:

注意日志文件的路径

```

[freeswitch]

enabled = true

* port     = 5060,5061,5080    # sip profile 的端口

* action   = iptables-allports[name=freeswitch, protocol=all]  # 这里不用改动

* logpath  = /usr/local/freeswitch/log/freeswitch.log # freeswitch.log的全路径

* filter   = freeswitch    #这里不用改动

* maxretry = 5             # 尝试次数

* bantime  = -1            # -1 永久 ban(禁止)

* findtime = 3600          # 发现的时间,这几个参数合起来的意思就是,如果 1 小时内检查到 哪个 IP 地址,做了 5 次尝试,那么永久禁止他

* ignoreip = 127.0.0.1/8 192.168.0.0/16 10.0.0.0/8 172.16.0.0/16  # 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 = .*? \[WARNING\] sofia_reg\.c:\d+ SIP auth (failure|challenge) \((REGISTER|INVITE)\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>$

            .*? \[WARNING\] sofia_reg\.c:\d+ Can't find user \[\d+@\d+\.\d+\.\d+\.\d+\] from <HOST>$

            .*? \[WARNING\] sofia\.c:\d+ IP <HOST> Rejected by acl \"domains"$

            

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\.$

 

```

[WARNING] sofia.c:10487 IP 62.138.3.130 Rejected by acl "domains"

            ``          

              

现在运行`systemctl restart fail2ban`重启服务

 

再运行 `fail2ban-client status`,输出如下:

 

```

Status

|- Number of jail:      1

`- Jail list:   freeswitch

```

 

运行`fail2ban-client status freeswitch`,输出如下:

 

```

Status for the jail: freeswitch

|- Filter

|  |- Currently failed: 0

|  |- Total failed:     0

|  `- File list:        /usr/local/freeswitch/log/freeswitch.log

`- Actions

   |- Currently banned: 0

   |- Total banned:     0

   `- Banned IP list:

```

 

现在试着ban一个ip,执行这个命令:

 

```

fail2ban-client set freeswitch banip 192.168.1.11

```

 

然后用`fail2ban-client status freeswitch`查看

 

```

Status for the jail: freeswitch

|- Filter

|  |- Currently failed: 0

|  |- Total failed:     0

|  `- File list:        /usr/local/freeswitch/log/freeswitch.log

`- Actions

   |- Currently banned: 1

   |- Total banned:     3

   `- Banned IP list:   192.168.1.11

```

 

可以看到, `192.168.1.11` 这个地址已经被ban

 

执行这个命令`iptables -nvL --line-numbers`

 

输出如下:

 

```

Chain INPUT (policy DROP 9 packets, 2952 bytes)

num   pkts bytes target     prot opt in     out     source               destination

1     1057  132K f2b-freeswitch  all  --  *      *       0.0.0.0/0            0.0.0.0/0

2        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0

3       13   808 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED

4        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22

5        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80

6        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443

7        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5066

8        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:7443

9        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpts:5060:5061

10       0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:5060

11       0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5080

12       0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:5080

13       0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpts:16384:32768

14       0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8

 

Chain FORWARD (policy DROP 0 packets, 0 bytes)

num   pkts bytes target     prot opt in     out     source               destination

 

Chain OUTPUT (policy ACCEPT 6 packets, 496 bytes)

num   pkts bytes target     prot opt in     out     source               destination

 

Chain f2b-freeswitch (1 references)

num   pkts bytes target     prot opt in     out     source               destination

1        0     0 REJECT     all  --  *      *       113.113.113.113      0.0.0.0/0            reject-with icmp-port-unreachable

2     1057  132K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

 

```

 

用这个命令解除,`fail2ban-client set freeswitch unbanip 192.168.1.11`

 

## 把 FreeSWITCH 运行起来,运行`tail -f /var/log/fail2ban.log`进行观察,再结合`/usr/local/freeswitch/log/freeswitch.log`的日志内容,进行调试,不断优化。

 

## fail2ban.lua

 

一般情况下`Fail2Ban`工作的很好,但还是有特殊的呼叫流程`Fail2Ban`抓不到。为此,笔者写了个`fail2ban.lua`,弥补`Fail2Ban`的不足

 

1. 修改`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::") ~= 1 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)

```

以上如果freeswitch在docker里边,可以通过freeswitch的事件通知方式,在宿主机中将注册失败和拨打失败相关的消息的ip用fail2ban拦截,后续我会写一些rabbitmq事件相关的文章,可以供大家参考

为了编写一个SIP压测FreeSWITCH的脚本,您可以使用SIPp工具。SIPp是一个开源的SIP协议测试和性能评估工具,它可以模拟SIP终端和服务器,生成和接收SIP请求,以及对SIP网络进行压力测试。 下面是一个简单的SIPp脚本示例,用于模拟SIP终端向FreeSWITCH服务器发送呼叫请求: ``` <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> <scenario name="SIPp Scenario"> <send retrans="500"> <![CDATA[ INVITE sip:test@freeswitch-server SIP/2.0 Via: SIP/2.0/UDP 192.168.0.1:5060;branch=z9hG4bK-1234 From: <sip:caller@test.com>;tag=1234 To: <sip:test@freeswitch-server> Call-ID: call-1234@192.168.0.1 CSeq: 1 INVITE Contact: <sip:caller@192.168.0.1:5060> Content-Type: application/sdp Content-Length: 150 v=0 o=- 1234 5678 IN IP4 192.168.0.1 s=Test call c=IN IP4 192.168.0.1 t=0 0 m=audio 10000 RTP/AVP 0 a=rtpmap:0 PCMU/8000 ]]> </send> <recv response="100" optional="true"/> <recv response="180" optional="true"/> <recv response="183" optional="true"/> <recv response="200"/> <send> <![CDATA[ ACK sip:test@freeswitch-server SIP/2.0 Via: SIP/2.0/UDP 192.168.0.1:5060;branch=z9hG4bK-5678 From: <sip:caller@test.com>;tag=1234 To: <sip:test@freeswitch-server>;tag=5678 Call-ID: call-1234@192.168.0.1 CSeq: 1 ACK Contact: <sip:caller@192.168.0.1:5060> Content-Length: 0 ]]> </send> <pause milliseconds="5000"/> <send> <![CDATA[ BYE sip:test@freeswitch-server SIP/2.0 Via: SIP/2.0/UDP 192.168.0.1:5060;branch=z9hG4bK-4321 From: <sip:caller@test.com>;tag=1234 To: <sip:test@freeswitch-server>;tag=5678 Call-ID: call-1234@192.168.0.1 CSeq: 2 BYE Contact: <sip:caller@192.168.0.1:5060> Content-Length: 0 ]]> </send> <recv response="200"/> </scenario> ``` 该脚本使用SIPp模拟一个基本的SIP呼叫流程,包括发送INVITE请求、接收100、180、183和200响应、发送ACK请求、等待5秒钟
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值