这篇记录 Debian 12 上编译安装 FreeSWITCH 1.10.12 的过程。

仓库里之前已经有一篇 Debian 11 的安装记录,这篇主要面向 Debian 12,重点是把
freeswitch_install.sh 脚本拆开说明:它做了哪些事情、为什么要先编译几个依赖库、
安装完成后还要检查哪些配置。

环境与目标

验证环境:

1
Linux debian12 6.1.0-47-amd64 x86_64 GNU/Linux

目标版本:

1
2
FS_VERSION="v1.10.12"
INSTALL_PATH="/usr/local/freeswitch"

最终希望得到:

  1. /usr/local/freeswitch/bin/freeswitch
  2. /usr/local/freeswitch/bin/fs_cli
  3. mod_sofiamod_spandspmod_shoutmod_mariadb
  4. PostgreSQL core db 支持
  5. freeswitch 系统用户和基础目录权限

如果服务器访问 GitHub 较慢,可以先配置代理:

1
2
3
export http_proxy="http://代理地址:端口"
export https_proxy="http://代理地址:端口"
export no_proxy="localhost,127.0.0.1,.local,.internal,内网网段"

安装脚本

新建 freeswitch_install.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/bin/bash
set -e

FS_VERSION="v1.10.12"
INSTALL_PATH="/usr/local/freeswitch"

echo "==============================================================="
echo "开始安装 FreeSWITCH $FS_VERSION"
echo "依赖库:libks Sofia-SIP SpanDSP signalwire-c"
echo "==============================================================="

apt-get update

apt-get install -y \
autoconf \
automake \
bison \
build-essential \
cmake \
erlang-dev \
git \
libavformat-dev \
libavcodec-dev \
libavutil-dev \
libswresample-dev \
libcurl4-openssl-dev \
libdb-dev \
libedit-dev \
libexpat1-dev \
libflac-dev \
libgdbm-dev \
libldns-dev \
liblua5.2-dev \
libmariadb-dev \
libmp3lame-dev \
libmpg123-dev \
libncurses5-dev \
libogg-dev \
libopus-dev \
libpcre3-dev \
libpq-dev \
libshout3-dev \
libsndfile1-dev \
libspeex-dev \
libspeexdsp-dev \
libsqlite3-dev \
libssl-dev \
libswscale-dev \
libtiff5-dev \
libtool \
libtool-bin \
libtpl-dev \
libvorbis-dev \
nasm \
pkg-config \
python3-dev \
unixodbc-dev \
uuid-dev \
wget \
zlib1g-dev

rm -rf /usr/src/freeswitch-deps
mkdir -p /usr/src/freeswitch-deps
cd /usr/src/freeswitch-deps

git clone --branch v2.0.10 https://github.com/signalwire/libks.git
git clone --branch v1.13.17 https://github.com/freeswitch/sofia-sip.git
git clone --branch fs https://github.com/freeswitch/spandsp.git
git clone --branch v2.0.5 https://github.com/signalwire/signalwire-c.git

echo ">>> 编译 libks"
cd /usr/src/freeswitch-deps/libks
cmake . -DCMAKE_INSTALL_PREFIX=/usr -DWITH_LIBBACKTRACE=1
make -j"$(nproc)"
make install
ldconfig

echo ">>> 编译 Sofia-SIP"
cd /usr/src/freeswitch-deps/sofia-sip
./bootstrap.sh
./configure --prefix=/usr
make -j"$(nproc)"
make install
ldconfig

echo ">>> 编译 SpanDSP"
cd /usr/src/freeswitch-deps/spandsp
./bootstrap.sh
./configure --prefix=/usr
make -j"$(nproc)"
make install
ldconfig

echo ">>> 编译 signalwire-c"
cd /usr/src/freeswitch-deps/signalwire-c
PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig \
cmake . -DCMAKE_INSTALL_PREFIX=/usr
make install
ldconfig

echo ">>> 下载 FreeSWITCH $FS_VERSION"
cd /usr/src
rm -rf freeswitch
git clone --branch "$FS_VERSION" https://github.com/signalwire/freeswitch.git
cd freeswitch

./bootstrap.sh -j

sed -i 's/#endpoints\/mod_sofia/endpoints\/mod_sofia/' modules.conf
sed -i 's/#applications\/mod_spandsp/applications\/mod_spandsp/' modules.conf
sed -i 's/#applications\/mod_av/applications\/mod_av/' modules.conf
sed -i 's/#formats\/mod_shout/formats\/mod_shout/' modules.conf
sed -i 's/#databases\/mod_mariadb/databases\/mod_mariadb/' modules.conf

./configure --prefix="$INSTALL_PATH" --enable-core-pgsql-support
make -j"$(nproc)"
make install
make cd-sounds-install
make cd-moh-install

ln -sf "$INSTALL_PATH/bin/fs_cli" /usr/bin/fs_cli
ln -sf "$INSTALL_PATH/bin/freeswitch" /usr/bin/freeswitch

if ! getent group freeswitch >/dev/null; then
groupadd freeswitch
fi

if ! getent passwd freeswitch >/dev/null; then
useradd -r -g freeswitch -d "$INSTALL_PATH" -s /bin/false freeswitch
fi

chown -R freeswitch:freeswitch "$INSTALL_PATH"
chmod -R ug+rw "$INSTALL_PATH"

echo "==============================================================="
echo "FreeSWITCH $FS_VERSION 安装成功"
echo "可用命令:freeswitch -nc,fs_cli"
echo "==============================================================="

执行:

1
2
chmod +x freeswitch_install.sh
./freeswitch_install.sh

脚本做了什么

这个脚本本质上分成 5 步。

第一步是安装编译环境。FreeSWITCH 不是只依赖 gccmake,SIP、音频编码、
数据库、TLS、Lua、ODBC 等能力都对应一批开发包。Debian 12 下常见缺失项包括
libpq-devlibmariadb-devlibopus-devlibshout3-devunixodbc-dev

第二步是编译 FreeSWITCH 依赖库:

依赖 作用
libks SignalWire 相关基础库
sofia-sip FreeSWITCH 的 SIP 协议栈基础
spandsp 传真、DTMF、音频信号处理等能力
signalwire-c SignalWire C 客户端库

第三步是拉取 FreeSWITCH 1.10.12 源码,并在 modules.conf 中打开需要的模块:

1
2
3
4
5
endpoints/mod_sofia
applications/mod_spandsp
applications/mod_av
formats/mod_shout
databases/mod_mariadb

其中 mod_sofia 是 SIP 核心模块,mod_spandsp 常用于回铃音、DTMF、传真等信号处理,
mod_shout 常用于播放 HTTP/MP3 流,mod_mariadb 用于连接 MariaDB/MySQL。

第四步是执行:

1
2
3
./configure --prefix=/usr/local/freeswitch --enable-core-pgsql-support
make -j"$(nproc)"
make install

--enable-core-pgsql-support 用来启用 PostgreSQL core db 支持。后面如果希望把
FreeSWITCH 的核心表、SIP 注册等数据放进 PostgreSQL,这一步不能漏。

第五步是做系统集成:

1
2
3
4
5
6
ln -sf /usr/local/freeswitch/bin/fs_cli /usr/bin/fs_cli
ln -sf /usr/local/freeswitch/bin/freeswitch /usr/bin/freeswitch
groupadd freeswitch
useradd -r -g freeswitch -d /usr/local/freeswitch -s /bin/false freeswitch
chown -R freeswitch:freeswitch /usr/local/freeswitch
chmod -R ug+rw /usr/local/freeswitch

这样之后,可以直接执行 freeswitchfs_cli,并让运行目录归属于专门的
freeswitch 用户。

启动前配置

配置目录:

1
/usr/local/freeswitch/etc/freeswitch

先改 vars.xml

1
2
3
4
<X-PRE-PROCESS cmd="set" data="default_password=请改成强密码"/>
<X-PRE-PROCESS cmd="set" data="bind_server_ip=$${domain}"/>
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=$${domain}"/>
<X-PRE-PROCESS cmd="set" data="external_sip_ip=$${domain}"/>

default_password 一定不要继续使用默认值。测试环境可以简单一点,线上建议用足够长的
随机密码,并且按分机、网关、ESL 分开管理。

如果不使用 Verto 和 SignalWire,可以在
autoload_configs/modules.conf.xml 里注释:

1
2
<!-- <load module="mod_verto"/> -->
<!-- <load module="mod_signalwire"/> -->

确认 SIP 核心模块启用:

1
<load module="mod_sofia"/>

数据库连接

如果希望 FreeSWITCH 使用 PostgreSQL,可以在
autoload_configs/switch.conf.xml<settings> 中加入:

1
2
<param name="core-db-dsn"
value="pgsql://hostaddr=数据库IP dbname=freeswitch user=用户名 password=密码 options='-c statement_timeout=3000' connect_timeout=5 keepalives=1 keepalives_idle=30 keepalives_interval=5 keepalives_count=3" />

sip_profiles/internal.xmlsip_profiles/external.xml<settings> 中加入:

1
2
<param name="odbc-dsn"
value="pgsql://hostaddr=数据库IP dbname=freeswitch user=用户名 password=密码 options='-c statement_timeout=3000' connect_timeout=5 keepalives=1 keepalives_idle=30 keepalives_interval=5 keepalives_count=3" />

这里建议加 statement_timeoutconnect_timeout 和 TCP keepalive。线上数据库偶发慢查询
或者网络抖动时,FreeSWITCH 不应该被一个长时间无响应的数据库连接拖住。

启动与验证

启动:

1
freeswitch -nc

进入控制台:

1
fs_cli

常用检查:

1
2
3
4
version
status
sofia status
module_exists mod_spandsp

检查 SIP profile:

1
2
sofia status profile internal
sofia status profile external

检查端口:

1
ss -lntup | grep -E '5060|5080|8021'

查看日志:

1
tail -f -n 500 /usr/local/freeswitch/var/log/freeswitch/freeswitch.log

停止:

1
fs_cli -x shutdown

如果只是调试环境,也可以:

1
killall freeswitch

重新编译

如果只是改了 modules.conf,想重新编译 FreeSWITCH 二进制,不想碰 XML 配置,可以准备一个
fs_rebuild.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
set -e

INSTALL_PATH="/usr/local/freeswitch"
cd /usr/src/freeswitch

./bootstrap.sh -j
./configure --prefix="$INSTALL_PATH" --enable-core-pgsql-support

make -j"$(nproc)"
make install

echo "更新完成。请执行 reloadxml,并按需重启对应 profile。"

执行前先备份配置:

1
2
cp -r /usr/local/freeswitch/etc/freeswitch \
/usr/local/freeswitch/etc/freeswitch.bak_$(date +%F)

注意事项

  1. 编译依赖尽量固定版本。libkssofia-sipspandspsignalwire-c 任意一个版本不匹配,
    都可能在 configure 或运行时出现奇怪问题。
  2. modules.conf 控制编译哪些模块,autoload_configs/modules.conf.xml 控制运行时加载哪些模块,
    这两个文件不是一回事。
  3. 线上不要把 ESL 8021 暴露到公网,后面单独写一篇 ACL、ESL、SIP profile 的权限配置。
  4. vars.xml、ACL、profile 后,至少执行 reloadxml。涉及 SIP 监听、ACL、NAT 的变更,
    建议重启对应 profile。
  5. 数据库连接串不要直接写默认口令。博客里的连接串只表示格式,真正上线要用独立账号和最小权限。