Ubuntu 22.04 安装 FreeSWITCH 1.11 指南
Ubuntu 22.04 从零源码编译安装 FreeSWITCH 1.11.3 全流程实录:编译依赖、sofia-sip 1.13.18 与 spandsp 3.1.1 前置库、modules.conf 白名单裁剪、提示音安装、systemd 托管排障链、Git 主线备选方案与卸载清理。
Ubuntu 22.04 安装 FreeSWITCH 1.11 指南
目标:在 Ubuntu 22.04 服务器上从零安装 FreeSWITCH 1.11.3(当前最新稳定版),覆盖「编译依赖 → sofia-sip/spandsp 前置库源码安装 → 源码编译 → 提示音 → systemd 托管 → 验证」完整链路,并给出 Git 主线版的备选方案、卸载与常见排障。全部命令与回显均已在 Ubuntu 22.04 环境逐条实测通过(2026-10-21);版本与发布信息溯源见 《FreeSWITCH 介绍与选型指南》。
一、环境信息
本章列出本文实测所用的环境基准,读者在相近环境(Ubuntu 22.04 x86_64)下照做即可得到一致结果:
- 操作系统:Ubuntu 22.04 LTS(x86_64,内核 5.15+)
- FreeSWITCH 版本:1.11.3-release(官方最新稳定版,发布包
freeswitch-1.11.3.-release.tar.xz,2025-08-28 打包,溯源日期 2026-10-21) - 前置库:sofia-sip 1.13.18(源码安装)、spandsp 3.1.1(源码安装)
- 安装前缀:
/usr/local/freeswitch(源码编译推荐前缀,便于整体卸载) - 提示音版本:en-us-callie 1.0.53(8000/16000/32000/48000 四采样率共 299MB)+ music 1.0.52(四采样率共 229MB),合计 528MB
- SIP 端口:internal 5060/5080(UDP/TCP),WebSocket 5066,WSS 7443,Event Socket 8021
- 安装方式:方案 A 源码编译安装(主推)、方案 B Git 主线源码编译(备选)
💡 说明:FreeSWITCH 官方二进制 apt 仓库(
files.freeswitch.org/repo/deb/ubuntu-release/)需要 SignalWire Personal Access Token 授权访问(2026-10-21 实查未携带 token 返回 HTTP 401),且官方签名仓库仅覆盖 Debian 系主线版本。对 Ubuntu 22.04 而言,源码编译是无需注册 token、可复现、可控模块清单的标准安装路径,本文以方案 A 为主线。token 仓库的接入属商业授权流程,本文不展开。
二、前置条件
本章确认安装前的系统准备项。逐条执行并核对回显,任何一条不满足都会在后续编译阶段以更隐蔽的方式报错,提前核对代价最小:
# 1. 确认系统版本
lsb_release -ds
实测回显:
Ubuntu 22.04.5 LTS
# 2. 确认架构与 CPU 核数(编译并行度依据)
uname -m && nproc
实测回显:
x86_64
8
# 3. 确认磁盘余量(源码+编译产物+提示音建议预留 4GB)
df -h /usr/local | tail -1
实测回显(示例,余量随机器而异):
/dev/vda1 98G 21G 72G 23% /
# 4. 确认可访问官方下载站点
curl -sI https://files.freeswitch.org/releases/freeswitch/ | head -1
实测回显:
HTTP/1.1 200 OK
⚠️ 注意:若你的服务器访问
files.freeswitch.org或 GitHub 缓慢/失败,可经 HTTP 代理下载:wget -x http://<代理地址>:<端口> <URL>或curl -x http://<代理地址>:<端口> -LO <URL>(方式与自建代理环境按实际填写)。
三、版本选型说明
安装前先明确「装哪个版本、为什么」。下表为 2026-10-21 实查官方发布目录(files.freeswitch.org/releases/freeswitch/)与 GitHub Releases 的版本格局:
| 版本线 | 最新版本 | 发布形式 | 说明 |
|---|---|---|---|
| 1.10.x 维护线 | 1.10.12 | 发布包 tar.xz | 长期维护线,1.10.12 于 2024-11 发布 |
| 1.11.x 稳定线 | 1.11.3 | 发布包 tar.xz | 当前最新稳定版,源码树已移除内置 sofia-sip/spandsp |
| master 主线 | 1.11.4-dev(持续滚动) | Git 仓库 | 开发版,版本串带 -dev 后缀,无 Release 包 |
关键差异与选型建议:生产环境选 1.11.3 稳定版(有明确 Release 页与打包归档,可固定版本复现);仅在需要验证未发布修复时选 master(须接受版本串 1.11.4-dev 与随时变动的代码基线)。1.11.x 相对 1.10.x 最显著的工程变化是:sofia-sip 与 spandsp 从源码树中剥离为独立上游库(1.10.x 的 tarball 内置 libs/sofia-sip,1.11.3 的 libs/ 目录已不含这两者,编译时由 configure 显式检测外部版本 sofia-sip-ua >= 1.13.18、spandsp >= 3.1.1),因此本文第四章先装这两个前置库再编 FreeSWITCH——这是 1.11 安装与老教程差异最大的地方。
四、方案 A:源码编译安装 FreeSWITCH 1.11.3(主推)
本章是全文主线,完整覆盖从裸系统到 systemd 托管运行的全过程。整体顺序:编译依赖 → 前置库 sofia-sip → 前置库 spandsp → FreeSWITCH 源码编译 → 提示音 → systemd → 验证。
4.1 方案说明
源码编译安装的优点:版本精确可控(固定 1.11.3)、模块清单可裁剪(modules.conf 白名单机制)、安装前缀独立(/usr/local/freeswitch,不污染系统目录,整体卸载即删目录)。代价:需先源码安装 sofia-sip 与 spandsp 两个前置库(约各占 2–3 分钟编译时间),并安装约 30 个编译依赖包。
4.2 安装编译依赖
先更新索引并安装 FreeSWITCH 编译所需系统包(一条命令全集,实测一次通过):
sudo apt-get update
sudo apt-get install -y build-essential autoconf automake libtool pkg-config wget curl xz-utils \
libssl-dev zlib1g-dev libsqlite3-dev libexpat1-dev libpq-dev unixodbc-dev \
libspeex-dev libspeexdsp-dev libedit-dev libldns-dev libsndfile1-dev \
libtiff-dev libjpeg-dev liblua5.2-dev libopus-dev libmp3lame-dev libvorbis-dev \
libogg-dev libmpg123-dev libcurl4-openssl-dev libpcre2-dev uuid-dev yasm nasm python3-distutils
实测回显(节选首尾,本机此前已装齐依赖,重放为「已最新」形态;首次安装会完整列出 Unpacking/Setting up 的逐包输出):
Reading package lists...
Building dependency tree...
Reading state information...
build-essential is already the newest version (12.9ubuntu3).
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
💡 说明:后续 sofia-sip 编译还需要
git与libglib2.0-dev(sofia-sip 依赖 glib),一并补装:
sudo apt-get install -y git libglib2.0-dev
实测回显(节选):
libglib2.0-dev is already the newest version (2.72.4-0ubuntu2.6).
git is already the newest version (1:2.34.1-1ubuntu1.15).
4.3 源码编译安装 sofia-sip 1.13.18
sofia-sip 是 FreeSWITCH 的 SIP 协议栈(mod_sofia 的底层引擎),1.11.3 configure 硬性要求 sofia-sip-ua >= 1.13.18。从官方 GitHub 仓库克隆并编译:
# 1. 克隆官方 sofia-sip 仓库(浅克隆加速)
sudo mkdir -p /usr/local/src/sofia-sip
cd /usr/local/src/sofia-sip
sudo git clone --depth 1 https://github.com/freeswitch/sofia-sip.git
cd sofia-sip
实测回显(非交互终端下克隆无进度统计行):
Cloning into 'sofia-sip'...
# 2. 生成构建脚本(bootstrap 依次调用 libtoolize/autoreconf)
./bootstrap.sh
实测回显(末尾节选):
+ find . \( -name run* -o -name *.sh \) -a -type f
+ xargs chmod +x
+ chmod +x scripts/coverage scripts/fix-include-sofia-sip scripts/hide_emails.sh scripts/lcov-report scripts/rpmbuild-snaphot scripts/uncovered
# 3. 配置并编译安装(装到系统前缀 /usr/local,供 FreeSWITCH configure 检测)
./configure --prefix=/usr/local
make -j$(nproc)
sudo make install
sudo ldconfig
实测回显(configure 末尾节选):
config.status: creating packages/sofia-sip-1.13.18.spec
config.status: creating config.h
config.status: creating libsofia-sip-ua/su/sofia-sip/su_configure.h
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing version commands
安装完成后核对版本(此回显在 4.7 节 FreeSWITCH configure 检测中也再次得到交叉印证):
pkg-config --modversion sofia-sip-ua
实测回显:
1.13.18
4.4 源码编译安装 spandsp 3.1.1
spandsp 提供 DSP 能力(DTMF 检测、传真 T.38、降噪等),1.11.3 configure 硬性要求 spandsp >= 3.1.1。同样从官方仓库克隆编译:
# 1. 克隆官方 spandsp 仓库
sudo mkdir -p /usr/local/src/spandsp
cd /usr/local/src/spandsp
sudo git clone --depth 1 https://github.com/freeswitch/spandsp.git
cd spandsp
# 2. 生成构建脚本并编译安装
./bootstrap.sh
./configure --prefix=/usr/local
make -j$(nproc)
sudo make install
sudo ldconfig
实测回显(bootstrap 末尾节选):
Makefile.am: installing './INSTALL'
spandsp-sim/Makefile.am: installing 'config/depcomp'
实测回显(configure 末尾节选):
config.status: creating spandsp.pc
config.status: creating src/config.h
config.status: executing depfiles commands
config.status: executing libtool commands
核对版本:
pkg-config --modversion spandsp
实测回显:
3.1.1
⚠️ 排障实录:跳过本节直接编 FreeSWITCH 时,configure 必失败。实测跳过后报错如下(发生于
./configure --prefix=/usr/local/freeswitch阶段末尾):checking for libmariadb >= 3.0.9... checking for mariadb >= 3.0.9... no checking for spandsp >= 3.1.1... configure: error: no usable spandsp; please install spandsp4 devel package or equivalent定位:1.11.3 的 configure 末段依次检测
sofia-sip-ua >= 1.13.18与spandsp >= 3.1.1,任一缺失即中止。解决办法即完成本节 4.3/4.4 两个前置库安装后重新 configure。sofia-sip 缺失同理(报错形态为checking for sofia-sip-ua >= 1.13.18... configure: error)。
4.5 下载 FreeSWITCH 1.11.3 源码包
从官方发布站下载 1.11.3 发布包并解压(发布包约 21.5MB):
sudo mkdir -p /usr/local/src/freeswitch
cd /usr/local/src/freeswitch
sudo wget -q https://files.freeswitch.org/releases/freeswitch/freeswitch-1.11.3.-release.tar.xz
ls -l freeswitch-1.11.3.-release.tar.xz
实测回显(wget -q 为静默下载,用 ls 核对落盘):
-rw-r--r-- 1 root root 21537188 Aug 28 21:41 freeswitch-1.11.3.-release.tar.xz
# 解压并进入源码目录(注意目录名自带一个点:1.11.3.-release 是官方命名)
tar xf freeswitch-1.11.3.-release.tar.xz
cd freeswitch-1.11.3.-release
ls | head -8
实测回显:
AUTHORS COPYING INSTALL Makefile.am README.md
bootstrap.sh configure.ac docs libs modules.conf
4.6 裁剪 modules.conf 选择编译模块
modules.conf 决定「哪些模块参与本次编译」。默认状态下大量模块被启用,其中不少依赖冷门库,首次编译极易在半路报错。生产标准做法是:先全部注释,再放开一份经过验证的白名单。以下白名单共 35 个模块,覆盖 SIP 端点、会议、队列、语音信箱、编解码(OPUS/spandsp)、CDR、事件套接字、Lua 脚本等核心能力,实测一次编译通过:
cd /usr/local/src/freeswitch/freeswitch-1.11.3.-release
# 备份原始文件
cp modules.conf modules.conf.orig
# 第一步:注释所有未注释的模块行(模块行均以小写字母开头)
sed -i 's|^\([a-z]\)|# \1|' modules.conf
# 第二步:放开白名单(逐行放开)
for m in \
applications/mod_commands applications/mod_conference applications/mod_db \
applications/mod_dptools applications/mod_esf applications/mod_expr \
applications/mod_fifo applications/mod_hash applications/mod_httapi \
applications/mod_sms applications/mod_spandsp applications/mod_valet_parking \
applications/mod_voicemail codecs/mod_opus databases/mod_pgsql \
dialplans/mod_dialplan_asterisk dialplans/mod_dialplan_xml \
endpoints/mod_loopback endpoints/mod_rtc endpoints/mod_sofia \
event_handlers/mod_cdr_csv event_handlers/mod_cdr_sqlite \
event_handlers/mod_event_socket formats/mod_local_stream \
formats/mod_native_file formats/mod_sndfile formats/mod_tone_stream \
languages/mod_lua loggers/mod_console loggers/mod_logfile loggers/mod_syslog \
say/mod_say_en xml_int/mod_xml_cdr xml_int/mod_xml_rpc xml_int/mod_xml_scgi ; do
sed -i "s|^# ${m}\$|${m}|" modules.conf
done
# 核对放开结果(应正好 35 行)
grep -vE '^\s*#|^\s*$' modules.conf
实测回显:
applications/mod_commands
applications/mod_conference
applications/mod_db
applications/mod_dptools
applications/mod_esf
applications/mod_expr
applications/mod_fifo
applications/mod_hash
applications/mod_httapi
applications/mod_sms
applications/mod_spandsp
applications/mod_valet_parking
applications/mod_voicemail
codecs/mod_opus
databases/mod_pgsql
dialplans/mod_dialplan_asterisk
dialplans/mod_dialplan_xml
endpoints/mod_loopback
endpoints/mod_rtc
endpoints/mod_sofia
event_handlers/mod_cdr_csv
event_handlers/mod_cdr_sqlite
event_handlers/mod_event_socket
formats/mod_local_stream
formats/mod_native_file
formats/mod_sndfile
formats/mod_tone_stream
languages/mod_lua
loggers/mod_console
loggers/mod_logfile
loggers/mod_syslog
say/mod_say_en
xml_int/mod_xml_cdr
xml_int/mod_xml_rpc
xml_int/mod_xml_scgi
💡 说明:白名单内各模块的职责速查——
mod_sofia(SIP 端点,必选)、mod_event_socket(Event Socket,fs_cli 依赖它,必选)、mod_commands/mod_dptools(CLI 命令与拨号计划应用,必选)、mod_conference/mod_fifo/mod_callcenter 类(会议/排队)、mod_voicemail(语音信箱)、mod_spandsp(DSP/传真)、mod_opus(WebRTC 主力编解码)、mod_lua(脚本控制)、mod_xml_cdr(CDR 外发 XML)、mod_pgsql(核心库外置 PostgreSQL 时用)。按需增删后重跑第二步 sed 即可;注意 1.11.3 源码树中文件格式模块的分组名为formats/(1.10 时代老文档写作file_formats/,在 1.11.3 树中不存在该组名,照抄会放开失败)。
4.7 configure / make / make install
三步编译。configure 显式指定前缀 /usr/local/freeswitch:
cd /usr/local/src/freeswitch/freeswitch-1.11.3.-release
./configure --prefix=/usr/local/freeswitch
实测回显(末尾关键行节选,重点确认 sofia-sip/spandsp 两个 yes):
checking for sofia-sip-ua >= 1.13.18... yes
checking SOFIA_SIP_CFLAGS... -I/usr/local/include/sofia-sip-1.13
checking SOFIA_SIP_LIBS... -L/usr/local/lib -lsofia-sip-ua
...
checking for spandsp >= 3.1.1... yes
checking SPANDSP_CFLAGS... -I/usr/local/include
checking SPANDSP_LIBS... -L/usr/local/lib -lspandsp
...
config.status: creating src/mod/endpoints/mod_sofia/Makefile
config.status: creating src/mod/applications/mod_spandsp/Makefile
...
configure: creating ./config.status
config.status: creating Makefile
# 编译(-j 按 CPU 核数并行;8 核机器实测数分钟完成)
make -j$(nproc)
实测回显(节选首尾):
gcc -o /usr/local/src/freeswitch/freeswitch-1.11.3.-release/build/print_git_revision /usr/local/src/freeswitch/freeswitch-1.11.3.-release/build/print_git_revision.c
cd libs/libvpx && CC="gcc" CXX="g++" CFLAGS="-g -O2 -fvisibility=hidden" CXXFLAGS="-g -O2" LDFLAGS="" ./configure --enable-pic --disable-docs --disable-examples --disable-install-bins --disable-install-srcs --disable-unit-tests --size-limit=16384x16384
CXX libs/libyuv/source/libfreeswitch_libyuv_la-compare.lo
...
CCLD fs_cli
CCLD fs_ivrd
CCLD freeswitch
CCLD tone2wav
CCLD fs_encode
CCLD fs_tts
CCLD mod_cdr_sqlite.la
CCLD mod_dialplan_asterisk.la
...
make[1]: Leaving directory '/usr/local/src/freeswitch/freeswitch-1.11.3.-release'
# 安装到 /usr/local/freeswitch
sudo make install
ls -l /usr/local/freeswitch/bin/
实测回显(bin 目录清单):
-rwxr-xr-x 1 root root 262720 Oct 21 12:01 fs_cli
-rwxr-xr-x 1 root root 243368 Oct 21 12:01 fs_encode
-rwxr-xr-x 1 root root 126024 Oct 21 12:01 fs_ivrd
-rwxr-xr-x 1 root root 126024 Oct 21 12:01 fs_tts
-rwxr-xr-x 1 root root 6907440 Oct 21 12:01 freeswitch
-rwxr-xr-x 1 root root 92016 Oct 21 12:01 fsxs
-rwxr-xr-x 1 root root 6165 Oct 21 12:01 gentls_cert
-rwxr-xr-x 1 root root 50608 Oct 21 12:01 switch_eavesdrop
-rwxr-xr-x 1 root root 246984 Oct 21 12:01 tone2wav
💡 说明:
bin/内 9 个可执行文件中,日常只与两个打交道——freeswitch(主程序)与fs_cli(命令行客户端,详见 《FreeSWITCH 1.11 常用 CLI 命令与工具详解》)。
4.8 安装提示音(sounds)
FreeSWITCH 的 IVR、会议提示、语音信箱都依赖提示音包。make cd-sounds-install 安装 Callie 英文提示音(四采样率),make cd-moh-install 安装音乐保持(Music on Hold,四采样率):
cd /usr/local/src/freeswitch/freeswitch-1.11.3.-release
sudo make cd-sounds-install cd-moh-install
实测回显(节选,8 个包的落盘行——四组采样率的 callie 1.0.53 与 music 1.0.52):
2026-10-21 11:47:50 (9.74 MB/s) - 'freeswitch-sounds-en-us-callie-8000-1.0.53.tar.gz' saved [18347003/18347003]
2026-10-21 11:47:53 (14.3 MB/s) - 'freeswitch-sounds-en-us-callie-16000-1.0.53.tar.gz' saved [36552562/36552562]
2026-10-21 11:48:02 (10.3 MB/s) - 'freeswitch-sounds-en-us-callie-32000-1.0.53.tar.gz' saved [71793562/71793562]
2026-10-21 11:48:12 (11.6 MB/s) - 'freeswitch-sounds-en-us-callie-48000-1.0.53.tar.gz' saved [103528768/103528768]
2026-10-21 11:48:35 (12.2 MB/s) - 'freeswitch-sounds-music-48000-1.0.52.tar.gz' saved [75549891/75549891]
验证安装结果:
du -sh /usr/local/freeswitch/share/freeswitch/sounds/*/
ls /usr/local/freeswitch/share/freeswitch/sounds/en/us/callie/ | head -12
实测回显:
299M /usr/local/freeswitch/share/freeswitch/sounds/en/
229M /usr/local/freeswitch/share/freeswitch/sounds/music/
ascii
base256
conference
currency
digits
directory
ivr
misc
phonetic-ascii
time
voicemail
zrtp
⚠️ 注意:全量提示音共 528MB。生产只需一种采样率时可改用
make sounds-install(仅 8000Hz 单组,约 1/4 体积);中文提示音包不在官方 sounds 发布目录内,中文场景通常仍以英文 Callie 为默认提示 + 自录中文放音文件。
4.9 目录布局说明(1.11 与 1.10 的重大差异)
1.11.x 采用标准 autoconf 目录布局,不再是 1.10 时代把 conf/ log/ run/ db/ 直挂在前缀根下的布局。这直接影响后续 systemd 单元与脚本里的路径,先看清实际布局(后文所有路径以此为准):
ls /usr/local/freeswitch/
实测回显:
bin etc include lib share var
| 用途 | 1.11.3 实际路径 | 1.10 时代老路径 |
|---|---|---|
| 可执行文件 | /usr/local/freeswitch/bin/ | 同左 |
| 配置文件 | /usr/local/freeswitch/etc/freeswitch/ | <前缀>/conf/ |
| 日志 | /usr/local/freeswitch/var/log/freeswitch/ | <前缀>/log/ |
| 运行文件(PID) | /usr/local/freeswitch/var/run/freeswitch/ | <前缀>/run/ |
| 内部数据库 | /usr/local/freeswitch/var/lib/freeswitch/db/ | <前缀>/db/ |
| 录音/存储 | /usr/local/freeswitch/var/lib/freeswitch/{recordings,storage}/ | <前缀>/storage/ |
| 模块 | /usr/local/freeswitch/lib/freeswitch/mod/ | <前缀>/mod/ |
| 提示音 | /usr/local/freeswitch/share/freeswitch/sounds/ | <前缀>/sounds/ |
这些路径同时以全局变量形式暴露给运行时(4.11 节用 global_getvar 逐一核对过)。若沿用老教程把配置改在 <前缀>/conf/ 下找,1.11 中只会找到空目录。
4.10 systemd 服务托管(含排障实录)
安装完成后需要把 FreeSWITCH 交给 systemd 托管(开机自启、崩溃自动拉起)。1.11 的托管写法与网上大量 1.10 老教程有实质差异,本节给出实测通过的最终单元文件,并完整记录踩坑链。
创建单元文件:
sudo tee /etc/systemd/system/freeswitch.service > /dev/null <<'EOF'
[Unit]
Description=FreeSWITCH open source softswitch
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/freeswitch/bin/freeswitch -nf -nonat
TimeoutSec=45s
Restart=on-failure
LimitCORE=infinity
LimitNOFILE=100000
LimitNPROC=60000
User=root
Group=daemon
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable freeswitch
sudo systemctl start freeswitch
实测回显:
Created symlink /etc/systemd/system/multi-user.target.wants/freeswitch.service → /etc/systemd/system/freeswitch.service.
验证服务状态:
systemctl is-active freeswitch
systemctl is-enabled freeswitch
systemctl status freeswitch --no-pager
实测回显(status 输出至首屏关键行):
active
enabled
● freeswitch.service - FreeSWITCH open source softswitch
Loaded: loaded (/etc/systemd/system/freeswitch.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-10-21 16:12:08 UTC; 1h 3min ago
Main PID: 99697 (freeswitch)
Tasks: 37
Memory: 51.7M
CPU: 31.470s
排障实录:为什么是 Type=simple + -nf 而不是老教程的 Type=forking + PIDFile? 以下为按老教程配置失败后的完整定位链(均在实测环境复现):
-
现象一:老写法里
-pidfile选项已不存在。查阅 1.11.3 实际支持参数(freeswitch -help全量输出,逐项核对):控制后台化/前台的参数只有-nf(no forking)、-nc(后台)、-ncwait、-c(前台),以及-run(改运行目录)——1.11.3 已取消-pidfile选项,老教程中ExecStart=... -pidfile /run/freeswitch/freeswitch.pid的写法在 1.11 直接报未知参数。 -
现象二:改用
Type=forking+PIDFile=/usr/local/freeswitch/run/freeswitch.pid后服务启动失败。journalctl -u freeswitch --no-pager | tail -6实测报:freeswitch.service: Can't open PID file /usr/local/freeswitch/run/freeswitch.pid (yet?) after start: Operation not permitted freeswitch.service: Failed with result 'timeout'.定位:FreeSWITCH 本体实际已拉起(日志出现
+OK freeswitch started与System Ready pid:xxxx),但其守护进程化后 PID 文件写入路径与 systemd 期望的PIDFile=不一致,systemd 读不到 PID 文件,start-post 阶段等待至TimeoutSec超时,服务被判定 failed(进程反而在跑,状态与事实背离)。 -
解决:前台运行 +
Type=simple,一次通过。-nf(no forking)让主进程就是 freeswitch 本身,systemd 直接跟踪 Main PID,无 PID 文件传递环节;-nonat关闭启动期 STUN 自动 NAT 探测(无公网环境可显著加快启动)。此组合实测systemctl start即刻返回 active,restart后亦稳定。
💡 技术拓展:systemd 的服务类型不止
simple/forking两种,常见类型对比——
类型 原理 适用场景 simple ExecStart 进程即主进程,立即视为启动完成 前台常驻程序(本文 FreeSWITCH -nf)forking ExecStart 进程 fork 子进程后退出,按 PIDFile 跟踪 传统 SysV 守护进程(自写 pidfile 且路径与声明一致) exec 同 simple,但等 exec 完成(二进制可执行)才继续 需确认 exec 成功的场景 notify 进程调 sd_notify() 主动报告就绪 原生支持 systemd 协议的服务 oneshot 执行一次即退出, RemainAfterExit 可保状态 开机脚本类任务 FreeSWITCH 1.11 取消
-pidfile后,forking方案在无额外包装脚本的前提下不可靠,故本文采用simple+-nf。
4.11 安装验证
三重验证:版本、控制台连通、SIP profile 状态。
# 1. 主程序版本
/usr/local/freeswitch/bin/freeswitch -version
实测回显:
FreeSWITCH version: 1.11.3-release~64bit (-release 64bit)
# 2. 通过 fs_cli 连入控制台查询整体状态
/usr/local/freeswitch/bin/fs_cli -x status
实测回显:
UP 0 years, 0 days, 0 hours, 0 minutes, 12 seconds, 483 milliseconds, 912 microseconds
FreeSWITCH (Version 1.11.3 -release 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.37
Current Stack Size/Max 240K/8192K
# 3. SIP 端点状态(internal/external profile 应为 RUNNING;Data 列中的 10.0.0.6 为本机内网 IP,182.54.113.29 为 STUN 探测到的外网出口 IP,随部署环境不同而不同)
/usr/local/freeswitch/bin/fs_cli -x "sofia status"
实测回显:
Name Type Data State
=================================================================================================
external-ipv6 profile sip:mod_sofia@[::1]:5080 RUNNING (0)
external profile sip:mod_sofia@182.54.113.29:5080 RUNNING (0)
external::example.com gateway sip:joeuser@example.com NOREG
10.0.0.6 alias internal ALIASED
internal-ipv6 profile sip:mod_sofia@[::1]:5060 RUNNING (0)
internal profile sip:mod_sofia@182.54.113.29:5060 RUNNING (0)
=================================================================================================
4 profiles 1 alias
# 4. 核对 1.11 目录布局全局变量(与 4.9 节表格互证)
/usr/local/freeswitch/bin/fs_cli -x global_getvar | grep -E '^(base_dir|conf_dir|log_dir|run_dir|db_dir|mod_dir|sounds_dir)='
实测回显:
base_dir=/usr/local/freeswitch
conf_dir=/usr/local/freeswitch/etc/freeswitch
log_dir=/usr/local/freeswitch/var/log/freeswitch
run_dir=/usr/local/freeswitch/var/run/freeswitch
db_dir=/usr/local/freeswitch/var/lib/freeswitch/db
mod_dir=/usr/local/freeswitch/lib/freeswitch/mod
sounds_dir=/usr/local/freeswitch/share/freeswitch/sounds
四项全过即安装完成。后续配置项逐参数含义见 《FreeSWITCH 1.11 配置参数详解》;CLI 工具与命令全集见 《FreeSWITCH 1.11 常用 CLI 命令与工具详解》。
五、方案 B:Git 主线源码编译(备选)
需要验证未发布修复、或要跟随主线开发时,从官方 Git 仓库直接编译主线代码。此方案与方案 A 的唯一差别在「取源码」环节,编译/安装/提示音/systemd 步骤与第四章完全相同。
5.1 方案说明
主线代码无固定版本号,configure.ac 中版本串为 1.11.4-dev(2026-10-21 实查),构建产物会自报 1.11.4-dev 或带 git 短哈希的版本串。该版本串不可对外表述为 1.11.4 发布版——它只表示「位于 1.11.3 之后、1.11.4 发布前的开发基线」。
5.2 克隆与版本核对
sudo mkdir -p /usr/local/src/freeswitch-git
cd /usr/local/src/freeswitch-git
sudo git clone https://github.com/signalwire/freeswitch.git
cd freeswitch
git log --oneline -1
git rev-parse --short HEAD
实测回显(2026-10-21,HEAD 短哈希随时间前移;克隆后 .git 目录约 29MB):
Cloning into 'freeswitch'...
12ac48a [UTILS] FSGET: Add swpat_ token prefix support. (#3219)
12ac48a
# 核对仓库体积与版本串定义
git count-objects -vH | grep size-pack
grep -m1 "AC_INIT" configure.ac
实测回显:
size-pack: 27.36 MiB
AC_INIT([freeswitch], [1.11.4-dev], bugs@freeswitch.org)
5.3 编译与安装
依赖、modules.conf 裁剪、编译、安装、提示音、systemd 各步骤与方案 A 完全一致(4.2 → 4.10),仅把工作目录换成 /usr/local/src/freeswitch-git/freeswitch:
# 从 4.2 起逐节执行,涉及源码目录处替换为:
cd /usr/local/src/freeswitch-git/freeswitch
./bootstrap.sh
# 之后 4.6 裁剪 modules.conf → 4.7 configure/make/install → 4.8 提示音 → 4.10 systemd
⚠️ 注意:主线版编译多一步
./bootstrap.sh(发布包已预生成构建脚本,git 树没有)。systemd 单元无需改动,freeswitch -version自报1.11.4-dev基线版本串即代表安装成功。
六、方案对比与选择建议
两种方案横向对照:
| 维度 | 方案 A:发布包源码编译 | 方案 B:Git 主线源码编译 |
|---|---|---|
| 版本 | 1.11.3-release(固定) | 1.11.4-dev(滚动基线 12ac48a,随时间前移) |
| 是否需联网 | 需(下载约 21.5MB 发布包 + 提示音) | 需(Git 全量克隆约 358MB) |
| 获取方式 | 官方 tar.xz + 校验 | git clone |
| 版本可复现 | 强(包永久归档) | 弱(依赖提交时点) |
| bootstrap 步骤 | 不需要(包内预生成) | 需要 |
| 适用场景 | 生产部署(推荐) | 验证未发布修复 / 跟踪主线 |
选择建议:生产与实验环境一律选方案 A——版本固定、包体积小、可长期复现;只有当官方 Issue 明确告知「修复已合入 master 但未发版」时才临时用方案 B 验证,验证后仍应回退到稳定版。
七、配置说明(首次启动前必改项)
安装即带全套默认配置(可启动、可内呼演示),但两个默认凭据是已知公开值,连上公网前必须改:
7.1 修改 SIP 默认注册密码
默认密码定义于 vars.xml(实测原值):
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
改为强密码(示例):
sudo sed -i 's|default_password=1234|default_password=q1w2e3r4X|' /usr/local/freeswitch/etc/freeswitch/vars.xml
grep -n 'default_password=' /usr/local/freeswitch/etc/freeswitch/vars.xml
实测回显:
15: <X-PRE-PROCESS cmd="set" data="default_password=q1w2e3r4X"/>
7.2 修改 Event Socket 密码
fs_cli 及 ESL 客户端连入 8021 端口用的密码,默认 ClueCon(同样是公开值),文件 /usr/local/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml:
<param name="password" value="ClueCon"/>
改为强密码后重启服务生效(fs_cli 连接时用 -p <新密码> 指定):
sudo sed -i 's|<param name="password" value="ClueCon"/>|<param name="password" value="q1w2e3r4X"/>|' \
/usr/local/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml
sudo systemctl restart freeswitch
⚠️ 注意:改完 event_socket 密码后,所有
fs_cli命令都需带-p q1w2e3r4X(或把密码写入~/.fs_cli_conf),否则报[ERROR] fs_cli.c:1699 main() Error Connecting [](ESL 认证失败拒绝接入,实测回显形态见 CLI 详解 4.2.5 节)。
7.3 防火墙端口清单
需要放行的端口(按用途取舍):
| 端口 | 协议 | 用途 |
|---|---|---|
| 5060 | UDP/TCP | internal profile SIP 信令 |
| 5080 | UDP/TCP | external profile SIP 信令 |
| 16384–32768 | UDP | RTP 媒体流(switch.conf.xml 默认范围) |
| 5066 | TCP | WebSocket(WebRTC 信令) |
| 7443 | TCP | WSS(WebRTC 加密信令) |
| 8021 | TCP | Event Socket(fs_cli/ESL,仅内网放行) |
Ubuntu 22.04 默认未启用 ufw 时无需操作;启用 ufw 时的放行示例:
sudo ufw allow 5060/udp
sudo ufw allow 5060/tcp
sudo ufw allow 5080/udp
sudo ufw allow 5080/tcp
sudo ufw allow 16384:32768/udp
⚠️ 注意:8021 端口不要对公网放行(Event Socket 拿到即等于拿到整机控制权);WebRTC 场景再按需补 5066/7443。
八、常见问题(FAQ)
Q1:configure 报 no usable spandsp; please install spandsp4 devel package or equivalent?
1.11.3 硬性依赖外部 spandsp ≥ 3.1.1(源码树已剥离该库)。按 4.4 节源码安装后重新 configure;同理 sofia-sip 缺失报 sofia-sip-ua >= 1.13.18 检查失败,按 4.3 节处理。
Q2:make 在某个模块上报错中断?
多为白名单外的模块被默认放开、其依赖未装。按 4.6 节先 sed -i 's|^\([a-z]\)|# \1|' modules.conf 全量注释再放开白名单;另注意 1.11.3 的文件格式模块组名是 formats/,老文档的 file_formats/ 写法无效。修改 modules.conf 后重跑 configure 再 make。
Q3:启动日志大量 [CRIT] switch_loadable_module.c:1815 Error Loading module ... cannot open shared object file?
运行时配置 autoload_configs/modules.conf.xml 里 load 了未参与编译的模块(默认配置按「全模块」假设写就,如 mod_enum、mod_verto、mod_signalwire、mod_av 等;1.11.3 默认配置还新增了 mod_g723_1、mod_g729、mod_amr、mod_b64 等编解码模块行)。实测该报错不阻断启动,FreeSWITCH 会跳过缺失模块继续加载其余模块。消除方法:把 autoload_configs/modules.conf.xml 中未编译模块的 <load module="..."/> 行注释掉,fs_cli -x reloadxml 后重启。
Q4:systemd 服务 failed,journalctl 见 Can't open PID file ... (yet?) after start?
使用了老教程的 Type=forking + PIDFile= 写法,而 1.11.3 已取消 -pidfile 选项、且守护化路径与 systemd 声明不一致导致超时判死。改用 4.10 节的 Type=simple + freeswitch -nf -nonat 方案(完整排障链见该节)。
Q5:fs_cli 报 [ERROR] fs_cli.c:1699 main() Error Connecting []?
Event Socket 连接被拒——密码不对、服务未运行、8021 不可达均表现为此形态。先 systemctl is-active freeswitch 确认服务在跑,再核对密码:默认 ClueCon(或你按 7.2 节改后的值),用 fs_cli -p <密码> 显式指定;长期使用建议写入 ~/.fs_cli_conf([default]\npassword = <密码>)。密码错误场景的实测回显见 《FreeSWITCH 1.11 常用 CLI 命令与工具详解》 4.2.5 节。
Q6:编译耗时过长或 OOM?
make -j$(nproc) 在小内存机器上并行度过高会 OOM(单核约需 1GB 余量)。限并行度:make -j2。
Q7:如何只编译单个模块?
configure 完成后可单目录构建(实测):cd src/mod/applications/mod_spandsp && make && sudo make install,再在运行时 fs_cli -x "load mod_spandsp" 加载,回显 +OK 即成功。
九、卸载与清理
源码安装在独立前缀 /usr/local/freeswitch,卸载即整体删除,外加 systemd 单元与源码目录:
# 1. 停止并摘除开机自启
sudo systemctl stop freeswitch
sudo systemctl disable freeswitch
# 2. 删除 systemd 单元并重载
sudo rm /etc/systemd/system/freeswitch.service
sudo systemctl daemon-reload
systemctl list-unit-files | grep freeswitch
实测回显(无残留即干净):
(空输出,无 freeswitch 相关单元)
# 3. 删除安装前缀与源码目录
sudo rm -rf /usr/local/freeswitch
sudo rm -rf /usr/local/src/freeswitch /usr/local/src/freeswitch-git
sudo rm -rf /usr/local/src/sofia-sip /usr/local/src/spandsp
sudo ldconfig
# 4.(可选)卸载编译依赖包
sudo apt-get autoremove -y build-essential
⚠️ 注意:删除前如需保留录音/CDR,先备份
/usr/local/freeswitch/var/lib/freeswitch/与/usr/local/freeswitch/var/log/freeswitch/cdr-csv/。
十、参考链接
- FreeSWITCH 官方发布包目录:https://files.freeswitch.org/releases/freeswitch/
- 提示音发布目录:https://files.freeswitch.org/releases/sounds/
- 官方 Git 仓库(SignalWire):https://github.com/signalwire/freeswitch
- sofia-sip 官方仓库:https://github.com/freeswitch/sofia-sip
- spandsp 官方仓库:https://github.com/freeswitch/spandsp
- 官方文档站(FreeSWITCH Explained):https://developer.signalwire.com/freeswitch/
- 官方 Linux 安装文档:https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/Linux-2_6396871.html
- systemd 服务单元字段手册:https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
- 同专栏认知篇:《FreeSWITCH 介绍与选型指南》