这篇整理 FreeSWITCH 线上权限相关配置。
内容基于一台 Debian 11 服务器上的 /usr/local/freeswitch/etc/freeswitch 配置整理,重点看:
autoload_configs/acl.conf.xmlautoload_configs/event_socket.conf.xmlsip_profiles/internal.xmlsip_profiles/external.xmlvars.xml
FreeSWITCH 权限配置最容易出问题的地方不是 XML 难写,而是边界不清楚:
- 哪些 IP 可以连 ESL?
- 哪些 IP 可以走 SIP profile?
- 哪些呼叫允许免鉴权?
- 内外网 profile 是否混用?
- 默认密码是否还在用?
ACL 配置
ACL 文件路径:
1 | /usr/local/freeswitch/etc/freeswitch/autoload_configs/acl.conf.xml |
线上配置里保留了 FreeSWITCH 默认说明,并增加了两个关键 list:domains 和 esl_only。
1 | <network-lists> |
domains 用于 SIP profile 的入站访问控制。domain="$${domain}" 会根据 directory 里的
domain 信息构建 ACL,额外加入 127.0.0.1/32 和本机内网 IP,是为了允许本机和可信内网地址
访问。
esl_only 是专门给 ESL 用的 ACL。这里允许:
1 | 127.0.0.1/32 |
这个拆分很重要。SIP 能访问的范围和 ESL 能访问的范围不应该混在一起。ESL 是控制面接口,
可以 originate、hangup、uuid_transfer、监听事件,权限比普通 SIP 注册高很多。
ESL 权限
ESL inbound 配置路径:
1 | /usr/local/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml |
线上关键配置:
1 | <configuration name="event_socket.conf" description="Socket Client"> |
listen-ip="::" 表示监听 IPv6 unspecified 地址,在很多系统上也可能同时覆盖 IPv4。
所以真正的安全边界不能只依赖监听地址,必须配合:
1 | <param name="apply-inbound-acl" value="esl_only"/> |
这样只有 esl_only 里允许的 IP 能连 8021。
线上建议:
- ESL 8021 不开放公网。
- ESL 只允许业务服务器、运维跳板机、本机访问。
password不使用默认值。- 防火墙也要做同样的来源限制,ACL 不是唯一防线。
- 如果只允许本机访问,可以把
listen-ip改成127.0.0.1或::1,并同步检查业务服务连接方式。
验证:
1 | ss -lntup | grep 8021 |
从未授权机器连接应该失败。
vars.xml 基础密码与地址
文件路径:
1 | /usr/local/freeswitch/etc/freeswitch/vars.xml |
关键项:
1 | <X-PRE-PROCESS cmd="set" data="default_password=请改成强密码"/> |
default_password 会影响默认 directory 用户。测试环境常常为了方便统一密码,但线上不建议
所有分机共用一个密码。
domain=$${local_ip_v4} 表示默认 domain 使用本机 IPv4。内网测试可以这样配;如果线上需要
域名注册、多网卡、NAT 或公网线路,建议明确规划:
- SIP 终端注册用哪个 domain。
- SIP profile 监听哪个 IP。
- RTP 对外公布哪个 IP。
- 是否需要 STUN。
不要在多网卡服务器上只靠默认探测结果。
internal profile
文件路径:
1 | /usr/local/freeswitch/etc/freeswitch/sip_profiles/internal.xml |
线上关键配置:
1 | <param name="context" value="public"/> |
这里最需要关注的是:
1 | <param name="apply-inbound-acl" value="domains"/> |
它表示 internal profile 的入站请求要经过 domains 这个 ACL。也就是说,不是任意来源都可以
直接打到 internal profile。
另一个高风险项是:
1 | <param name="accept-blind-auth" value="true"/> |
这个参数用于允许某些网关或上游设备以较宽松的方式通过认证。它不是所有环境都应该打开。
如果上游线路是固定 IP 的 SIP trunk,可以配合 ACL 限制来源;如果是公网软电话注册场景,
就要谨慎评估。
auth-calls 决定是否要求呼叫鉴权。internal profile 如果对公网可达,必须非常谨慎。
常见建议是:
- 终端注册走 internal,开启鉴权。
- SIP trunk 呼入走 external 或单独 profile,通过来源 IP 白名单控制。
- 不要把
accept-blind-auth=true和大范围 ACL 放在一起。
数据库连接也在 profile 中配置:
1 | <param name="odbc-dsn" |
这个配置会影响 SIP profile 相关数据,例如注册、恢复、状态存储等。线上建议加超时和 keepalive,
避免数据库短暂异常时把 SIP 处理拖死。
external profile
文件路径:
1 | /usr/local/freeswitch/etc/freeswitch/sip_profiles/external.xml |
线上关键配置:
1 | <param name="context" value="public"/> |
external profile 通常用于对接外部 SIP trunk。这里 auth-calls=false 比较常见,因为运营商
或者上游网关可能不走分机密码认证,而是通过固定 IP 和网关配置鉴权。
但这也意味着必须用其他方式限制来源:
- 防火墙只允许运营商或上游网关 IP 访问 SIP 端口。
- profile 层增加 ACL。
- dialplan 层限制可呼叫的号码范围。
- 出局路由不要让任意呼入直接转外呼。
external profile 不建议直接给普通软电话注册使用。如果确实要支持公网注册,建议单独做一个
profile,独立端口、独立 ACL、独立鉴权策略。
core db 配置
路径:
1 | /usr/local/freeswitch/etc/freeswitch/autoload_configs/switch.conf.xml |
线上使用 PostgreSQL core db:
1 | <param name="core-db-dsn" |
这里同样建议:
- 独立数据库账号。
- 最小权限。
- 明确连接超时。
- 明确查询超时。
- 开启 keepalive。
数据库权限不是 SIP 权限,但数据库卡住会影响 FreeSWITCH 的稳定性,所以线上配置要把超时写清楚。
线上日志配置
FreeSWITCH 线上日志要先收敛默认输出,再给排查留临时开关。日志量过大不仅占磁盘,
也会在高并发时影响 I/O 和问题定位效率。
日志级别
FreeSWITCH 常用日志级别可以按 0-7 理解:
1 | 0 CONSOLE |
数值越小表示问题越严重,默认输出越少;数值越大表示日志越详细,输出也越多。
线上默认建议控制在 NOTICE,需要排查注册、呼叫、媒体或模块细节时,再临时打开DEBUG。
核心配置文件
日志相关配置主要看三个文件:
1 | /usr/local/freeswitch/etc/freeswitch/autoload_configs/switch.conf.xml |
switch.conf.xml 里可以设置全局日志上限,线上建议不要长期放到 debug:
1 | <param name="loglevel" value="notice"/> |
console.conf.xml 控制控制台输出。线上如果主要看文件日志,控制台可以保持 info 或notice,避免终端输出过多:
1 | <param name="loglevel" value="notice"/> |
logfile.conf.xml 控制文件日志、轮转、是否写入 UUID、实际写入级别等。线上建议文件日志
保留足够的异常和呼叫状态信息,但不要默认写入 debug。
一个偏保守的生产示例:
1 | <configuration name="logfile.conf" description="File Logging"> |
这里的含义是:
rotate-on-hup=true:收到 HUP 后重新打开日志文件,方便配合logrotate。rollover=104857600:单个日志文件约 100 MB 后轮转。maximum-rotate=30:FreeSWITCH 自身最多保留 30 个轮转文件。uuid=true:日志里带呼叫 UUID,方便过滤单次呼叫链路。mappings不包含debug:避免生产环境默认写入大量调试日志。
动态调试命令
线上排查可以临时调高日志级别,不一定每次都改 XML:
1 | fs_cli -x "fsctl loglevel debug" |
如果已经进入 fs_cli,可以直接执行:
1 | /log debug |
排查 SIP 信令时,优先只打开目标 profile 的 siptrace:
1 | fs_cli -x "sofia profile internal siptrace on" |
排查结束后必须恢复日志级别,并关闭 siptrace:
1 | fs_cli -x "fsctl loglevel notice" |
不要在高并发线上长期打开:
1 | fs_cli -x "sofia global siptrace on" |
全局 siptrace 会把大量 SIP 报文写入日志,既影响性能,也容易把真正的错误淹没。
需要临时抓 SIP 包时,更推荐在服务器上用 sngrep 观察,减少 FreeSWITCH 自身日志压力。
logrotate 配置建议
如果使用系统 logrotate 管理 FreeSWITCH 日志,可以按每日轮转、保留 14 天、gzip 压缩来配置。
示例文件:/etc/logrotate.d/freeswitch。
1 | /usr/local/freeswitch/var/log/freeswitch/*.log { |
如果 logfile.conf.xml 已开启 rotate-on-hup=true,postrotate 里发送 HUP 可以让
FreeSWITCH 重新打开日志文件。不同安装方式下 pid 文件路径可能不同,需要按实际路径确认。
排查建议
常用日志排查命令:
1 | tail -f -n 500 /usr/local/freeswitch/var/log/freeswitch/freeswitch.log |
定位单次呼叫时,先拿到 UUID,再过滤整条链路:
1 | grep "呼叫UUID" /usr/local/freeswitch/var/log/freeswitch/freeswitch.log |
线上排查的原则是:默认日志收敛,发现问题后临时放开,定位结束立即恢复。
修改后的加载方式
修改 XML 后先检查格式。至少执行:
1 | fs_cli -x reloadxml |
如果改了 SIP profile 的监听 IP、ACL、NAT、数据库连接,建议重启对应 profile:
1 | fs_cli -x "sofia profile internal restart" |
如果只改了 ESL 的 ACL 或密码,最稳妥是重启 mod_event_socket 或安排 FreeSWITCH 进程重启。
线上已有通话时不要随便重启主进程。
检查:
1 | fs_cli -x "sofia status" |
日志:
1 | tail -f -n 500 /usr/local/freeswitch/var/log/freeswitch/freeswitch.log |
线上推荐配置原则
1. ESL 是控制面,只走内网
ESL 8021 能控制通话,不要暴露公网。
推荐:
1 | <param name="apply-inbound-acl" value="esl_only"/> |
esl_only 里只放:
1 | 127.0.0.1/32 |
不要为了方便写成 0.0.0.0/0。
2. SIP 分 internal 和 external
internal 负责分机注册和内网业务,external 负责外部线路。不要把所有入口都塞进一个 profile。
internal 建议:
- 开启鉴权。
- 限制来源 ACL。
- 使用强密码。
- 只开放给可信终端或内网。
external 建议:
- 只允许 SIP trunk 来源 IP。
- 不允许任意号码转外呼。
- dialplan 做号码规则限制。
- 运营商 IP 变化时同步更新防火墙和 ACL。
3. 默认密码必须改
vars.xml 里的 default_password 不要保留默认值。更进一步,线上应该避免所有分机共用一个
默认密码。
4. ACL 和防火墙同时做
ACL 是 FreeSWITCH 应用层限制,防火墙是系统层限制。线上两层都要做。
常见组合:
1 | ESL 8021 只允许业务服务器和跳板机 |
5. 日志默认收敛,排查临时放开
线上不要长期打开 debug 或全局 siptrace。默认日志级别保持 notice,遇到问题时临时
调高到 debug,排查结束立即恢复。
6. 配置变更先备份
变更前先备份:
1 | cp -r /usr/local/freeswitch/etc/freeswitch \ |
配置出错时,FreeSWITCH 可能还能运行,但新加载的 profile、dialplan、ACL 不生效。
备份比事后回忆改了哪里可靠。
排查清单
ESL 连不上:
1 | ss -lntup | grep 8021 |
SIP 注册失败:
1 | fs_cli -x "sofia status profile internal" |
SIP trunk 呼入失败:
1 | fs_cli -x "sofia status profile external" |
数据库异常:
1 | grep -n "core-db-dsn" /usr/local/freeswitch/etc/freeswitch/autoload_configs/switch.conf.xml |
总结
FreeSWITCH 线上权限配置可以按一句话理解:
1 | ESL 只给业务控制面,SIP 按入口拆 profile,ACL 和防火墙都要收紧,默认密码全部换掉。 |
安装成功只是第一步。真正上线前,至少要确认:
- ESL 8021 不在公网暴露。
- internal/external profile 边界明确。
- SIP trunk 来源 IP 有白名单。
- 分机密码不是默认值。
- 数据库连接有超时。
- 每次改配置都有备份和回滚路径。