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 主线备选方案与卸载清理。

FreeSWITCH即时通信FreeSWITCH2026/10/22

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? 以下为按老教程配置失败后的完整定位链(均在实测环境复现):

  1. 现象一:老写法里 -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 直接报未知参数。

  2. 现象二:改用 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(进程反而在跑,状态与事实背离)。

  3. 解决:前台运行 + Type=simple,一次通过。-nf(no forking)让主进程就是 freeswitch 本身,systemd 直接跟踪 Main PID,无 PID 文件传递环节;-nonat 关闭启动期 STUN 自动 NAT 探测(无公网环境可显著加快启动)。此组合实测 systemctl start 即刻返回 active,restart 后亦稳定。

💡 技术拓展:systemd 的服务类型不止 simple/forking 两种,常见类型对比——

类型原理适用场景
simpleExecStart 进程即主进程,立即视为启动完成前台常驻程序(本文 FreeSWITCH -nf)
forkingExecStart 进程 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 防火墙端口清单

需要放行的端口(按用途取舍):

端口协议用途
5060UDP/TCPinternal profile SIP 信令
5080UDP/TCPexternal profile SIP 信令
16384–32768UDPRTP 媒体流(switch.conf.xml 默认范围)
5066TCPWebSocket(WebRTC 信令)
7443TCPWSS(WebRTC 加密信令)
8021TCPEvent 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/。

十、参考链接