FreeSWITCH部署

产品介绍:FreeSWITCH 是一个电话的软交换解决方案,包括一个软电话和软交换机用以提供语音和聊天的产品驱动。FreeSWITCH 可以用作交换机引擎、PBX、多媒体网关以及多媒体服务器等。

基础环境

基础环境 基础信息 备注说明
操作系统版本 CentOS Linux release 7.9.2009 (Core)
硬盘 | 内存 100GB、8GB
防火墙 |时间 防火墙关闭、时间同步开启 # sed -i s+SELINUX=enforcing+SELINUX=disabled+ /etc/selinux/config && setenforce 0
FreeSWITCH 1.8.7 版本【推荐freeswitch-1.8.7.tar.gz
FreeSWITCH_PATH /usr/local/freeswitch 服务安装路径
FreeSWITCH_Port TCP 5060|5080 5060端口为internal内网注册端口,5080为external外部-无需注册
FreeSWITCH_RTP-Ports UDP 16384~32768 RTP音频流通讯端口,未开通情况下将无任何声音

操作系统优化

[root@localhost ~]#  cat /etc/security/limits.conf
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
# 

FreeSWITCH部署过程

推荐1.8.7版本 FreeSWITCH参考下载路径

安装相关依赖环境

[root@localhost ~]# hostnamectl set-hostname fs01
[root@localhost ~]# yum install -y https://files.freeswitch.org/repo/yum/centos-release/freeswitch-release-repo-0-1.noarch.rpm epel-release
[root@localhost ~]# curl -l -O https://files.freeswitch.org/releases/freeswitch/freeswitch-1.8.7.tar.gz
[root@localhost ~]# yum install -y yum-utils --enablerepo=extras 
[root@localhost ~]# yum install -y yum-plugin-ovl centos-release-scl rpmdevtools yum-utils git wget vim devtoolset-7-gcc* devtoolset-7 libtiff-devel cmake3 libatomic unixODBC unixODBC-devel.x86_64 postgresql-libs postgresql-devel libpqxx-devel
[root@localhost ~]# yum install -y gcc-c++ autoconf automake libtool ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel libxml2-devel libyuv-devel libvpx-devel libvpx2* libdb4* libidn-devel unbound-devel libuuid-devel lua-devel libsndfile-devel yasm-devel unixODBC unixODBC-devel mysql-connector-odbc

安装spandsp

解决: checking for spandsp >= 3.0... configure: error: no usable spandsp; please install spandsp3 devel package or equivalent

# 编译spandsp
# 推荐版本包: spandsp-master.zip
[root@localhost ~]# git clone https://github.com/freeswitch/spandsp.git
[root@localhost ~]# cd /data/freeswitch/spandsp
[root@localhost ~]# ./bootstrap.sh
[root@localhost ~]# ./configure
[root@localhost ~]# make
[root@localhost ~]# make install
[root@localhost ~]# ldconfig		# 加载动态库

安装sofia-sip

解决: checking for sofia-sip-ua >= 1.xx.xx... configure: error: no usable sofia-sip; please install sofia-sip-ua devel package or equivalent

# 编译sofia-sip
# 推荐版本包: sofia-sip-1.13.10.tar.gz
[root@localhost ~]# git clone https://github.com/freeswitch/sofia-sip.git
[root@localhost ~]# cd /data/freeswitch/sofia-sip
[root@localhost ~]# ./bootstrap.sh
[root@localhost ~]# ./configure
[root@localhost ~]# make
[root@localhost ~]# make install

# 添加库的路径到系统
[root@localhost ~]# export PKG_CONfig_PATH=/usr/local/lib/pkgconfig:${PKG_CONfig_PATH} 
[root@localhost ~]# ldconfig
# 需退出当前会话重新,重新进入系统编译安装

安装signalwire-c

解决: Makefile:932: *** You must install signalwire-client-c to build mod_signalwire. Stop.

Packages-version: signalwire-c-1.3.3
[root@localhost ~]# wget https://github.com/signalwire/signalwire-c/tags/signalwire-c-1.3.3.tar.gz
[root@localhost ~]# tar zxvf signalwire-c-1.3.3.tar.gz -C release/ && cd signalwire-c-1.3.3/
[root@localhost ~]# cmake3 .
[root@localhost ~]# make
[root@localhost ~]# make install
# 设置环境变量
[root@localhost ~]# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/:/usr/local/lib64/pkgconfig:${PKG_CONFIG_PATH}
[root@localhost ~]# ldconfig
[root@localhost ~]# ln -s /usr/local/lib64/pkgconfig/signalwire_client.pc /usr/lib64/pkgconfig/signalwire_client.pc

安装opus-devel

解决: Makefile:929: *** You must install libopus-dev to build mod_opus. Stop

[root@localhost ~]# cat /etc/yum.repos.d/linuxtech.repo
[linuxtech]
name=LinuxTECH
baseurl=http://pkgrepo.linuxtech.net/el6/release/
enabled=1
gpgcheck=0
gpgkey=http://pkgrepo.linuxtech.net/el6/release/RPM-GPG-KEY-LinuxTECH.NET
[root@localhost ~]# yum install opus opus-devel

lua模块安装

# 推荐用5.1.4版本, 验证过
[root@localhost ~]# yum install libreadline-dev readline-devel
[root@localhost ~]# yum install lua lua-devel
lua-5.1.4-15.el7.x86_64
lua-devel-5.1.4-15.el7.x86_64

cjson模块安装

Cjson_Packages: lua-cjson-2.1.0.tar.gz
Download_Packages: https://github.com/mpx/lua-cjson/releases/tag/2.1.0
[root@localhost ~]# tar zxvf lua-cjson-2.1.0.tar.gz -C release/ && cd release/lua-cjson-2.1.0
[root@gitlab lua-cjson-2.1.0]# vim Makefile
LUA_VERSION =       5.1                        # lua -v 查看Lua版本为: 5.1.4(修改对应的版本)
CJSON_LDFLAGS =     -shared
LUA_INCLUDE_DIR =   $(PREFIX)/include/lua51   # 打开
[root@gitlab lua-cjson-2.1.0]# cmake3 .
    -- The C compiler identification is GNU 4.8.5
    -- Check for working C compiler: /usr/bin/cc
    -- Check for working C compiler: /usr/bin/cc - works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Detecting C compile features
    -- Detecting C compile features - done
    -- Found Lua51: /usr/lib64/liblua-5.1.so;/usr/lib64/libm.so (found version "5.1.4")
    -- Looking for isinf
    -- Looking for isinf - found
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /root/Packages/release/lua-cjson-2.1.0

[root@gitlab lua-cjson-2.1.0]# make && make install
    Scanning dependencies of target cjson
    [ 25%] Building C object CMakeFiles/cjson.dir/lua_cjson.c.o
    [ 50%] Building C object CMakeFiles/cjson.dir/strbuf.c.o
    [ 75%] Building C object CMakeFiles/cjson.dir/fpconv.c.o
    [100%] Linking C shared module cjson.so
    [100%] Built target cjson

[root@gitlab lua-cjson-2.1.0]# make install
    [100%] Built target cjson
    Install the project...
    -- Install configuration: "Release"
    -- Installing: /usr/lib64/lua/5.1/cjson.so

编译FreeSWITCH

[root@localhost ~]# cd freeswitch-1.8.7
[root@localhost freeswitch-1.8.7]# ./devel-bootstrap.sh
[root@localhost freeswitch-1.8.7]# vim module.conf
# applications/mod_signalwire     # 关闭
# applications/mod_av             # 关闭
event_handlers/mod_odbc_cdr       # 开启话单存储odbc方式
event_handlers/mod_cdr_mongodb    # 开启话单存储mongodb方式
languages/mod_lua                 # 开启lua支持
event_handlers/mod_json_cdr       # 启用json话单模块
[root@localhost freeswitch-1.8.7]# ./configure --prefix=/usr/local/freeswitch --enable-portable-binary --with-gnu-ld --with-python=/usr/bin/python2.7 --with-openssl --enable-core-odbc-support --enable-zrtp --with-lua
[root@localhost freeswitch-1.8.7]# make
[root@localhost freeswitch-1.8.7]# make install

验证是否安装成功

[root@localhost ~]# /usr/local/freeswitch/bin/freeswitch -nonat	-nc	# 关闭upnp(或NAT-PMP)协议,并后台启动:
freeswitch@localhost > sofia status
                     Name          Type                                       Data      State
=================================================================================================
            external-ipv6       profile                   sip:mod_sofia@[::1]:5080      RUNNING (0)
              *.*.*.*         alias                                   internal      ALIASED
                 external       profile             sip:mod_sofia@*.*.*.*:5080      RUNNING (0)
    external::example.com       gateway                    sip:joeuser@example.com      NOREG
            internal-ipv6       profile                   sip:mod_sofia@[::1]:5060      RUNNING (0)
                 internal       profile             sip:mod_sofia@*.*.*.*:5060      RUNNING (0)
=================================================================================================

开启EventSocket TCP Server

[root@localhost ~]# cat autoload_configs/event_socket.conf.xml
<configuration name="event_socket.conf" description="Socket Client">
  <settings>
    <param name="nat-map" value="false"/>
    <param name="listen-ip" value="10.10.10.41"/>
    <param name="listen-port" value="8021"/>
    <param name="password" value="ClueCon"/>
    <param name="apply-inbound-acl" value="lan"/>
    <!--<param name="stop-on-bind-error" value="true"/>-->
  </settings>
</configuration>

# 进入freeswitch重新加载配置
freeswitch> reload mod_event_socket

# 通过socket方式连接
[root@localhost ~]# fs_cli -H 10.10.10.41 -P 8021 -p ClueConHope

Python通过ESL方式连接FreeSWITCH


# 准备环境安装Python环境和python-ESL环境
# Python3环境和python-ESL环境
[root@gitlab Packages]# wget https://jaist.dl.sourceforge.net/project/swig/swig/swig-3.0.12/swig-3.0.12.tar.gz
[root@gitlab Packages]# tar zxvf swig-3.0.12.tar.gz -C release && cd release/swig-3.0.12/
[root@gitlab Packages]# ./configure
[root@gitlab Packages]# make && make install
[root@gitlab Packages]# yum install python3-devel
[root@gitlab Packages]# pip3 install python-ESL			# 重新安装Python-ESL
Installing collected packages: python-ESL
  Running setup.py install for python-ESL ... done
Successfully installed python-ESL-1.4.18
[root@gitlab Packages]# pip3 list |grep ESL
python-ESL (1.4.18)

## Python2环境和python-ESL环境
[root@gitlab Packages]# wget https://bootstrap.pypa.io/pip/2.7/get-pip.py
[root@gitlab Packages]# python get-pip.py
[root@gitlab Packages]# pip install python-ESL
[root@gitlab Packages]# pip list | grep ESL
Python连接FreeSWITCH测试代码
#!/usr/bin/env python
# code_name: test_esl_code.py
from optparse import OptionParser
import sys

import ESL


def main(argv):
    parser = OptionParser()
    parser.add_option('-a', '--auth', dest='auth', default='ClueCon',
                      help='ESL password')
    parser.add_option('-s', '--server', dest='server', default='192.168.50.240',
                      help='FreeSWITCH server IP address')
    parser.add_option('-p', '--port', dest='port', default='8021',
                      help='FreeSWITCH server event socket port')
    parser.add_option('-c', '--command', dest='command', default='status',
                      help='command to run, surround multi-word commands in ""s')

    (options, args) = parser.parse_args()

    con = ESL.ESLconnection(options.server, options.port, options.auth)

    if not con.connected():
        print('Not Connected')
        sys.exit(2)

    # Run command
    e = con.api(options.command)
    if e:
        print(e.getBody())

if __name__ == '__main__':
    main(sys.argv[1:])

Python连接FreeSWITCH测试代码-运行测试代码结果
[root@gitlab code]# python test_esl_code.py
UP 0 years, 0 days, 0 hours, 6 minutes, 38 seconds, 797 milliseconds, 224 microseconds
FreeSWITCH (Version 1.8.7  64bit) is ready
0 session(s) since startup
0 session(s) - peak 0, last 5min 0
0 session(s) per Sec out of max 30, peak 0, last 5min 0
1000 session(s) max
min idle cpu 0.00/98.17
Current Stack Size/Max 240K/8192K

配置连接MySQL

# 指定版本安装 例如这里安装mysql-community-server-8.0.37
# adding the mysql yum repository
[root@localhost ~]# rpm -ivh mysql80-community-release-el7-7.noarch.rpm
[root@localhost ~]# yum-config-manager --enable mysql80-community
[root@localhost ~]# yum repolist enabled | grep mysql
[root@localhost ~]# yum install mysql-community-client-plugins-8.0.37 mysql-community-client-8.0.37 mysql-community-server-8.0.37 mysql-community-common-8.0.37 mysql-community-libs-8.0.37 mysql-community-icu-data-files-8.0.37

# 修改数据库存储路径
[root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config && setenforce 0
[root@localhost ~]# mkdir -p /data/MySQLdata && chown -R mysql.mysql /data/MySQLdata
[root@localhost ~]# cp /var/lib/mysql /data/MySQLdata/
[root@localhost ~]# vim /etc/my.cnf
datadir=/data/MySQLdata/mysql
socket=/data/MySQLdata/mysql/mysql.sock
[root@localhost ~]# systemctl restart mysqld

# 跳过密码认证
[root@localhost ~]# vim /etc/my.conf
[mysqld]
skip-grant-tables
[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# mysql -u root -p
无需输入密码,回车即可

# get superuser account 'root'@'localhost' is created
[root@localhost ~]#  grep "temporary password" /var/log/mysqld.log
[root@localhost ~]#  mysql -u root -p
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MyNewPass4!';
mysql> flush privileges;

# MySQL修改连接方式为mysql_native_password
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
#默认连接端口
port       = 3306
# 修改密码加密方式为:mysql_native_password
default_authentication_plugin   = mysql_native_password

# 设置MySQL密码长度
# 查看当前密码长度
show VARIABLES LIKE "validate_password_length"
# 更改密码长度
set global validate_password.length=6;

# 查询MySQL最大连接数
show VARIABLES LIKE "max_connections";
# 设置最大连接数为2000
set GLOBAL max_connections = 65535;

# 查询MySQL当前连接数
# 当前连接数
mysql> show status LIKE 'Threads_connected';
# 历史最大连接数
mysql> show status LIKE 'Max_used_connections';
# 最大连接数限制
mysql> show VARIABLES LIKE "max_connections";
配置连接odbc
[root@localhost ~]# cat /etc/odbc.ini	# 默认没有文件,需新建
[freeswitch]
Driver		= /usr/lib64/libmyodbc8a.so		# 参考/etc/odbcinst.ini,或者find
SERVER		= 10.10.10.41
PORT		= 3306
DATABASE	= freeswitch
OPTION		= 67108864
USER		= fsroot
PASSWORD	= fsPwdreMvc38!!
Threading	= 0
测试连接MySQL数据库
[root@localhost ~]# isql -v freeswitch
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> quit

# mysql 压测
concurrency: 							测试中,并发的线程数/客户端数
iterations: 							指定测试重复的次数
auto-generate-sql-add-autoincrement: 	在自动生成的表中添加自增列
engine:									指定建表时的存储引擎
number-of-queries:						指定每个线程执行的 SQL 语句数量上限(不精确)

mysql> mysqlslap --concurrency=100  --iterations 10 -a  --auto-generate-sql-add-autoincrement --engine=innodb --number-of-queries=1000 -h 127.0.0.1 -uroot -p
FreeSWITCH使用ODBC连接MySQL
[root@localhost ~]# vim autoload_configs/switch.conf.xml
<param name="core-db-dsn" value="odbc://freeswitch::" />
[root@localhost ~]# vim autoload_configs/db.conf.xml
<param name="odbc-dsn" value="odbc://freeswitch::" />
[root@localhost ~]# vim sip_profiles/internal.xml
<param name="odbc-dsn" value="odbc://freeswitch::" />
[root@localhost ~]# vim sip_profiles/external.xml
<param name="odbc-dsn" value="odbc://freeswitch::" />
# 重启FS过程中,可能有建表错误,请自行创建表
[root@localhost ~]# 

配置FreeSWITCH支持MongoDB

配置Mongodb服务
mongodb_version: 4.2
[root@localhost ~]# cat /etc/yum.repos.d/mongodb-org-4.2.repo
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc

# 安装指定版本 mongodb-4.2.15
[root@localhost ~]# yum install mongodb-org-tools-4.2.15 \
mongodb-org-4.2.15 \
mongodb-org-mongos-4.2.15 \
mongodb-org-server-4.2.15 \
mongodb-org-shell-4.2.15

# 配置Mongodb服务
[root@localhost ~]# vim /etc/mongod.conf
# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo		# 数据存储位置
  journal:
    enabled: true
#  engine:
#  wiredTiger:

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

# network interfaces
net:
  port: 28017
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.


#security:
security:
  authorization: enabled
#operationProfiling:

#replication:
#replication:
#  replSetName: mongoCluster
#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

# 启动 Mongodb服务
[root@localhost ~]# chown mongod.mongod /tmp/mongodb-27017.sock
[root@localhost ~]# systemctl status mongod
[root@localhost ~]# systemctl enable --now mongod

# 基于MongoDB服务为FreeSWITCH创建用户
[root@localhost ~]# vim /etc/mongod.conf
#security:
#  authorization: enabled
[root@localhost ~]# systemctl restart mongod

[root@localhost ~]# mongo
>use admin
>db.createUser({
	user:'admin',
	pwd:'pcOEM0827',
	roles:[
	    { role: "userAdminAnyDatabase", db: "admin" },
	    { role: "dbAdminAnyDatabase", db: "admin" },
	    { role: "readWriteAnyDatabase", db: "admin" }
    ]
})

# 客户端登录
# mongodb://admin:pcOEM0827@mongodb_server_ip:27017/?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false


# 创建crm集合,并创建赋予root用户和pcOEM0827密码,
use crm
db.createUser({
	user:'root',
	pwd:'pcOEM0827',
	roles:[
	    { role: "userAdminAnyDatabase", db: "admin" }
    ]
})

# 客户端登录
# mongodb://root:pcOEM0827@mongodb_server_ip:27017/?authSource=crm&readPreference=primary&appname=MongoDB%20Compass&ssl=false
配置FreeSWITCH服务
# 加载模块,重新编译(修改编译过程中的modules.conf, 若有可不用重新编译)
[root@localhost ~]# vim freeswitch/modules.conf
event_handlers/mod_cdr_mongodb
[root@localhost ~]# make && make install

# 动态加载支持MongoDB的模块
[root@localhost ~]# vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml
<load module="mod_cdr_mongodb"/>			# 添加模块

freeswitch@localhost > reload mod_cdr_mongodb
+OK Reloading XML
+OK module unloaded
+OK module loaded

# 配置FreeSWITCH连接MongoDB认证方式
[root@localhost ~]# vim autoload_configs/mongo.conf.xml
<!--<param name="connection-string" value="mongodb://127.0.0.1:27017/?connectTimeoutMS=10000"/>-->
<param name="connection-string" value="mongodb://root:pcOEM0827@10.10.10.41:27017/?authSource=crm&readPreference=primary&appname=MongoDB%20Compass&ssl=false"/>

# 配置数据存放在crm.cdr表中
[root@localhost ~]# vim /usr/local/freeswitch/etc/freeswitch/autoload_configs/cdr_mongodb.conf.xml
<configuration name="cdr_mongodb.conf" description="MongoDB CDR logger">
  <settings>
    <!-- Hostnames and IPv6 addrs not supported (yet) -->
    <param name="host" value="127.0.0.1"/>
    <param name="port" value="27017"/>

    <!-- Namespace format is database.collection -->
    <!--<param name="namespace" value="test.cdr"/>-->
    <param name="namespace" value="crm.cdr"/>

    <!-- If true, create CDR for B-leg of call (default: true) -->
    <param name="log-b-leg" value="false"/>
  </settings>
</configuration>

# 配置完成后,需要重启FreeSWITCH才能生效
[root@localhost ~]#  freeswitch --nonat
验证话单存储MongoDB
Windows_MongoDB_Package: MongoDB Compass version: 1.26.1
[root@localhost ~]#