在 FreeSWITCH 中,当配置 bind_server_ip=auto
时,系统会绑定 所有可用的网络接口的 IP 地址,包括 内网地址 和 公网地址(若存在)。以下是详细说明:
1. bind_server_ip=auto
的绑定逻辑
网络接口类型 | 是否被绑定 | 典型 IP 示例 |
---|---|---|
物理网卡接口 | ✔️ 绑定 | 192.168.1.71(内网)、203.0.113.5(公网) |
虚拟网卡接口(如 Docker) | ✔️ 绑定(需配置) | 172.17.0.1(Docker 默认网桥) |
回环接口(Loopback) | ✔️ 绑定 | 127.0.0.1(本地环回地址) |
2. 验证实际绑定的 IP
方法 1:通过 FreeSWITCH CLI 查看
/usr/local/freeswitch/bin/fs_cli -x "sofia status"
输出示例:
=================================================================
Name Type Data State
=================================================================
external profile sip:mod_sofia@192.168.1.71:5080 RUNNING (0)
external profile sip:mod_sofia@203.0.113.5:5080 RUNNING (0)
internal profile sip:mod_sofia@192.168.10.71:5060 RUNNING (0)
- 关键字段:
192.168.1.71:5080
(内网接口)203.0.113.5:5080
(公网接口)192.168.10.71:5060
(另一内网接口)
方法 2:通过系统命令 netstat
或 ss
查看
ss -anupl | grep freeswitch
输出示例:
UNCONN 0 0 192.168.1.71:5080 0.0.0.0:* users:("freeswitch",pid=1234,fd=12)
UNCONN 0 0 203.0.113.5:5080 0.0.0.0:* users:("freeswitch",pid=1234,fd=13)
UNCONN 0 0 192.168.10.71:5060 0.0.0.0:* users:("freeswitch",pid=1234,fd=10)
3. 混合网络环境中的风险与优化
风险
- 安全暴露:公网 IP 的绑定可能导致 SIP 端口(如 5060/5080)暴露在互联网,遭受扫描或攻击。
- 路由混乱:若内网和公网设备使用相同域名,可能导致信令路径错误。
优化建议
-
分离 SIP Profile
- 公网 Profile:绑定公网 IP,配置严格 ACL 和防火墙规则。
- 内网 Profile:绑定内网 IP,禁用 NAT 穿透逻辑。
<!-- vars.xml 示例 --> <X-PRE-PROCESS cmd="set" data="internal_sip_ip=192.168.10.71"/> <X-PRE-PROCESS cmd="set" data="external_sip_ip=203.0.113.5"/>
-
限制绑定范围
若需仅绑定特定 IP,弃用auto
并手动指定:<!-- 仅绑定公网 IP --> <X-PRE-PROCESS cmd="set" data="bind_server_ip=203.0.113.5"/> <!-- 或绑定多个指定 IP --> <X-PRE-PROCESS cmd="set" data="bind_server_ip=203.0.113.5,192.168.10.71"/>
4. 场景适配指南
场景 | 推荐配置 |
---|---|
纯内网通信 | bind_server_ip=内网IP + 关闭 STUN |
纯公网通信 | bind_server_ip=公网IP + 启用 STUN/手动指定 external_rtp_ip |
混合网络(推荐) | 分拆为 internal 和 external 两个 SIP Profile,分别绑定内网和公网 IP |
总结
- 默认行为:
bind_server_ip=auto
会绑定 所有接口的 IP(内网 + 公网)。 - 生产建议:在混合网络中,显式分离内外网 SIP Profile,避免盲目绑定所有接口带来的安全风险。
如果公网是通过路由器的端口映射过来的呢?本机只有一个网口为192.168.1.71,公网ip222.222.222.222是通过路由端口端口映射了udp类型的5060,5080,10000-40000,此时vars.xml的配置文件的调整策略?
以下是针对 通过路由器 NAT 端口映射 场景优化的 FreeSWITCH vars.xml
配置文件,结合公网 IP 222.222.222.222
和局域网 IP 192.168.1.71
的混合部署需求:
<include>
<!-- 基础配置 -->
<X-PRE-PROCESS cmd="set" data="default_password=Secur3P@ss"/> <!-- 生产环境建议强密码 -->
<X-PRE-PROCESS cmd="set" data="domain=222.222.222.222"/> <!-- 强制指定公网IP为SIP域 -->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=192.168.1.71"/> <!-- 内网实际IP -->
<!-- NAT 穿透核心配置 -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=222.222.222.222"/> <!-- 公网媒体IP -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=222.222.222.222"/> <!-- 公网信令IP -->
<X-PRE-PROCESS cmd="set" data="rtp_start_port=10000"/> <!-- RTP起始端口 -->
<X-PRE-PROCESS cmd="set" data="rtp_end_port=40000"/> <!-- RTP结束端口 -->
<!-- SIP Profile 绑定与端口映射 -->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=192.168.1.71"/> <!-- 仅绑定内网接口 -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/> <!-- 外网映射到本机5060 -->
<X-PRE-PROCESS cmd="set" data="sip_force_contact=222.222.222.222:5060"/> <!-- 强制Contact头 -->
<!-- 高级NAT参数 -->
<X-PRE-PROCESS cmd="set" data="NDLB-force-rport=true"/> <!-- 强制使用NAT映射端口 -->
<X-PRE-PROCESS cmd="set" data="aggressive-nat-detection=true"/> <!-- 激进NAT检测 -->
<X-PRE-PROCESS cmd="set" data="inbound-bypass-media=true"/> <!-- 媒体流直连 -->
<!-- 编解码与安全 -->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8"/>
</include>
关键配置说明
1. 双IP声明逻辑
参数 | 值 | 作用 |
---|---|---|
domain | 222.222.222.222 | SIP 消息中的域名和 Via 头使用公网IP |
local_ip_v4 | 192.168.1.71 | 告知 FreeSWITCH 实际绑定的内网IP |
external_rtp_ip | 222.222.222.222 | SDP 中的媒体地址强制指定为公网IP |
sip_force_contact | 222.222.222.222:5060 | 强制 Contact 头为公网IP,解决 SIP 响应路由问题 |
2. 端口映射配置
- 路由器映射规则:
公网 222.222.222.222:5060/UDP → 内网 192.168.1.71:5060 公网 222.222.222.222:5080/UDP → 内网 192.168.1.71:5080 公网 222.222.222.222:10000-40000/UDP → 内网 192.168.1.71:10000-40000
- FreeSWITCH 适配:
rtp_start_port=10000
和rtp_end_port=40000
确保媒体端口在映射范围内。- 仅绑定内网接口 (
bind_server_ip=192.168.1.71
),依赖路由器做 DNAT。
3. SIP Profile 增强配置 (sip_profiles/external.xml
)
<profile name="external">
<!-- 基础绑定 -->
<param name="sip-ip" value="192.168.1.71"/>
<param name="sip-port" value="5060"/>
<!-- NAT穿透增强 -->
<param name="ext-rtp-ip" value="222.222.222.222"/>
<param name="ext-sip-ip" value="222.222.222.222"/>
<param name="NDLB-force-rport" value="true"/>
<param name="aggressive-nat-detection" value="true"/>
<!-- 安全防护 -->
<param name="apply-nat-acl" value="rfc1918.auto"/> <!-- 自动识别内网请求 -->
<param name="inbound-bypass-media" value="true"/>
</profile>
通信流程验证
故障排查指南
1. SIP信令不通
- 检查路由器DNAT规则:
iptables -t nat -L -n -v | grep '5060\|5080' # 应显示类似: # DNAT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:5060 to:192.168.1.71:5060
- 验证FreeSWITCH日志:
grep "222.222.222.222" /usr/local/freeswitch/log/freeswitch.log # 应看到正确的公网IP被应用
2. 媒体单通
- 确认SDP中的IP和端口:
tcpdump -i eth0 -nn -vvv port 5060 -A | grep 'c=IN' # 输出应为:c=IN IP4 222.222.222.222
- 检查RTP端口映射:
ss -anupl | grep '10000' # 查看是否成功打开端口
3. 性能优化
- 限制RTP端口范围(若实际业务量较小):
<X-PRE-PROCESS cmd="set" data="rtp_start_port=20000"/> <X-PRE-PROCESS cmd="set" data="rtp_end_port=30000"/>
- 启用ZRTP加密(可选):
<X-PRE-PROCESS cmd="set" data="zrtp-enabled=true"/>
强制指定了公网IP为SIP域 ,如果是内网通信的时候是否会受到的影响
在 FreeSWITCH 中,若将 domain
强制设置为公网 IP(222.222.222.222
),内网通信可能会受到一定影响,具体表现和解决方案如下:
1. 内网通信的影响分析
(1) SIP 信令路径问题
-
现象:
内网设备(如 IP 话机)向 FreeSWITCH 发送 SIP 请求(如INVITE
)时,FreeSWITCH 会在响应头(如Contact
、Via
)中强制插入公网 IP222.222.222.222
。- 内网设备可能尝试通过公网 IP 回连,导致 路径绕行(Hairpin NAT) 或 直接无法连接(若内网设备无法访问公网 IP)。
-
示例 SIP 响应头:
Contact: <sip:1001@222.222.222.222:5060> # 强制使用公网IP Via: SIP/2.0/UDP 222.222.222.222:5060 # 公网IP出现在Via头
(2) SDP 媒体地址问题
- 现象:
FreeSWITCH 生成的 SDP 中的媒体地址(c=IN IP4 222.222.222.222
)会指向公网 IP。- 若内网设备间通信时尝试直接使用此 IP,可能导致 媒体流绕行公网路由器,增加延迟甚至失败(若路由器未允许内网到公网 IP 的回环流量)。
2. 解决方案:内外网流量分离
(1) 方案一:保留公网 domain
,添加内网路由规则
-
配置目标:
内网设备通过内网 IP (192.168.1.71
) 通信,公网设备通过公网 IP (222.222.222.222
) 通信。 -
实现步骤:
-
新增内网 SIP Profile:
在sip_profiles/internal.xml
中创建专用于内网的 Profile,绑定内网 IP 并禁用公网逻辑:<profile name="internal"> <param name="sip-ip" value="192.168.1.71"/> <param name="sip-port" value="5060"/> <param name="ext-rtp-ip" value="192.168.1.71"/> <!-- 媒体IP强制内网 --> <param name="ext-sip-ip" value="192.168.1.71"/> <param name="force-register-domain" value="192.168.1.71"/> <!-- 内网注册域 --> </profile>
-
修改
vars.xml
配置:
分离内外网参数,确保公网配置不影响内网:<!-- 公网配置 --> <X-PRE-PROCESS cmd="set" data="domain=222.222.222.222"/> <X-PRE-PROCESS cmd="set" data="external_rtp_ip=222.222.222.222"/> <X-PRE-PROCESS cmd="set" data="external_sip_ip=222.222.222.222"/> <!-- 内网配置 --> <X-PRE-PROCESS cmd="set" data="internal_sip_ip=192.168.1.71"/> <X-PRE-PROCESS cmd="set" data="internal_rtp_ip=192.168.1.71"/>
-
Dialplan 路由优化:
根据来源 IP 区分内外网路由:<extension name="internal_route"> <condition field="network_addr" expression="^192\.168\.1\.\d+$"> <!-- 内网请求走内部Profile --> <action application="bridge" data="sofia/internal/$1@192.168.1.71"/> </condition> </extension>
-
(2) 方案二:动态域名解析(DNS 或 Hosts 文件)
-
配置目标:
内网设备通过域名(如fs.example.com
)访问 FreeSWITCH,域名在内网解析为192.168.1.71
,在公网解析为222.222.222.222
。 -
实现步骤:
-
内网 DNS 或 Hosts 文件:
在内网 DNS 服务器或设备 Hosts 文件中添加:192.168.1.71 fs.example.com
-
公网 DNS 解析:
在公网 DNS 中配置:fs.example.com A 222.222.222.222
-
修改 FreeSWITCH 配置:
将domain
设置为域名:<X-PRE-PROCESS cmd="set" data="domain=fs.example.com"/>
-
3. 验证配置有效性
(1) 内网呼叫测试
- 发起内网呼叫:
从内网设备(如 IP 话机)拨打分机号码,检查信令和媒体路径:# 抓包命令(FreeSWITCH 服务器) tcpdump -i eth0 host 192.168.1.71 -nn -vvv -w internal_call.pcap
- 期望结果:
SIP 头域和 SDP 中的 IP 应为内网地址192.168.1.71
,媒体流直接在内网传输。
- 期望结果:
(2) 公网呼叫测试
- 发起公网呼叫:
从公网设备(如 VoIP 客户端)拨打测试号码,验证 NAT 穿透:# 查看 FreeSWITCH 日志 tail -f /usr/local/freeswitch/log/freeswitch.log | grep '222.222.222.222'
- 期望结果:
日志中显示公网 IP 被正确用于信令和媒体。
- 期望结果:
4. 故障排查与优化
现象 | 可能原因 | 解决方案 |
---|---|---|
内网呼叫响应超时 | SIP 头域强制公网IP导致环路 | 检查是否启用内网 Profile,确认 force-register-domain 配置正确。 |
媒体流单向传输(内网) | SDP 中的 IP 错误指向公网 | 验证内网 Profile 的 ext-rtp-ip 是否设置为内网 IP。 |
公网呼叫无法建立 | 路由器未正确映射端口 | 使用 iptables 或路由器管理界面确认 DNAT 规则。 |
总结
- 强制设置
domain=公网IP
对内网通信的影响:
若无额外隔离措施,会导致内网设备尝试通过公网 IP 通信,可能引发 NAT 环路或性能下降。 - 推荐方案:
分离内外网 SIP Profile,确保内网流量直接通过内网 IP 交互,公网流量通过 NAT 映射。此方案兼顾安全性和性能,是混合网络环境的最佳实践。
最终部署检查清单
- 路由器完成端口映射(5060/5080 UDP + RTP端口段)。
- FreeSWITCH 启动后通过
sofia status
确认仅绑定内网IP。 - 通过公网客户端发起呼叫,抓包验证SIP/SDP中的公网IP正确。
- 测试媒体流双向可达(可使用
tcpdump
或rtpengine
分析)。
<include>
<!--
预处理器变量
这些变量用于确保跨模块的配置字符串一致性。
注意:您不能通过注释禁用 X-PRE-PROCESS 行,必须直接删除该行。
警告 警告 警告 警告 警告 警告 警告 警告 警告 警告
如果您不希望未来遭受任何话费欺诈,必须修改此 default_password 的默认值。
保护系统安全是您自身的责任。
此默认配置仅用于演示 FreeSWITCH 的功能特性。
警告 警告 警告 警告 警告 警告 警告 警告 警告 警告
-->
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
<!-- 这是针对上述密码的提示,需要修改密码-->
<!--
The following variables are set dynamically - calculated if possible by freeswitch - and
are available to the config as $${variable}. You can see their calculated value via fs_cli
by entering eval $${variable}
hostname 系统主机名(如fs-dev-01)
local_ip_v4 主IPv4地址(自动检测,多网卡时可能需手动指定)
local_mask_v4 IPv4子网掩码
local_ip_v6 主IPv6地址(若启用)
switch_serial 内部序列号(用于集群或日志跟踪)
base_dir FreeSWITCH安装根目录(如/usr/local/freeswitch)
recordings_dir 通话录音默认存储路径(如$${base_dir}/storage/recording
sound_prefix
sounds_dir 语音文件目录(如提示音,路径$${base_dir}/sounds)
conf_dir 配置文件目录($${base_dir}/conf)
log_dir 日志文件目录($${base_dir}/log)
run_dir 存放运行时文件(如PID文件、进程锁文件)
db_dir 数据库文件存储目录(SQLite或内置数据库文件)
mod_dir FreeSWITCH 动态加载模块(.so/.dll)的存放目录
htdocs_dir 内置 HTTP/WebSocket 服务器的根目录(用于 Web 服务
script_dir 脚本文件存放目录(如 Lua、JavaScript、Python 脚本)
temp_dir 临时文件目录($${base_dir}/tmp)
grammar_dir 语音识别(ASR)语法文件目录(用于 mod_unimrcp 等模块)
certs_dir TLS 证书和私钥存放目录(如 tls.crt, tls.key)
storage_dir 通用存储目录(默认录音、传真等文件的父目录)
cache_dir TLS证书存放目录($${base_dir}/certs)
core_uuid FreeSWITCH实例的唯一标识(UUID格式,启动时生成)
nat_public_addr 经过NAT后的公网IP(通过STUN服务器检测)
nat_private_addr 内网IP地址
nat_type NAT类型(如Full Cone、Restricted)
-->
<!-- 设置默认语音文件路径(美式英语Callie发音) -->
<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/en/us/callie"/>
<!-- 注释掉的备选发音(Allison发音) -->
<!--<Z-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/en/us/allison"/> -->
<!--
默认域名设置:当其他配置未指定时,FreeSWITCH使用此域名。
默认值为本机IPv4地址($${local_ip_v4})。修改此值会影响SIP认证逻辑。
详见 conf/directory/default.xml 中的目录配置说明。
-->
<X-PRE-PROCESS cmd="set" data="domain=$${local_ip_v4}"/>
<X-PRE-PROCESS cmd="set" data="domain_name=$${domain}"/>
<!-- 保持音乐(等待音)配置 -->
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<!-- SIP配置文件选择(默认为external.xml) -->
<X-PRE-PROCESS cmd="set" data="use_profile=external"/>
<!-- SRTP加密套件优先级列表(从强到弱) -->
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8|AES_CM_256_HMAC_SHA1_80|AES_CM_192_HMAC_SHA1_80|AES_CM_128_HMAC_SHA1_80|AES_CM_256_HMAC_SHA1_32|AES_CM_192_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_32|AES_CM_128_NULL_AUTH"/>
<!--
警告:使用SRTP时禁止使用可变比特率(VBR)编解码器,否则可能导致SRTP流信息泄露。
支持的加密套件:
- AEAD_AES_256_GCM_8:256位AES-GCM,64位认证标签
- AEAD_AES_128_GCM_8:128位AES-GCM,64位认证标签
- AES_CM_{256/192/128}_HMAC_SHA1_{80/32}:AES计数器模式 + HMAC-SHA1认证
- AES_CM_128_NULL_AUTH:仅加密无认证(不推荐)
SRTP行为控制参数:
- rtp_secure_media:强制(mandatory)、可选(optional)、禁用(forbidden)
- rtp_secure_media_inbound/outbound:分别控制入站/出站加密策略
- rtp_secure_media_suites:独立指定加密套件列表(冒号分隔)
NOTICE: When using SRTP it's critical that you do not offer or accept
variable bit rate codecs, doing so would leak information and possibly
compromise your SRTP stream. (FS-6404)
Supported SRTP Crypto Suites:
AEAD_AES_256_GCM_8
____________________________________________________________________________
This algorithm is identical to AEAD_AES_256_GCM (see Section 5.2 of
[RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used.
An AEAD_AES_256_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.
AEAD_AES_128_GCM_8
____________________________________________________________________________
This algorithm is identical to AEAD_AES_128_GCM (see Section 5.1 of
[RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used.
An AEAD_AES_128_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.
AES_CM_256_HMAC_SHA1_80 | AES_CM_192_HMAC_SHA1_80 | AES_CM_128_HMAC_SHA1_80
____________________________________________________________________________
AES_CM_128_HMAC_SHA1_80 is the SRTP default AES Counter Mode cipher
and HMAC-SHA1 message authentication with an 80-bit authentication
tag. The master-key length is 128 bits and has a default lifetime of
a maximum of 2^48 SRTP packets or 2^31 SRTCP packets, whichever comes
first.
AES_CM_256_HMAC_SHA1_32 | AES_CM_192_HMAC_SHA1_32 | AES_CM_128_HMAC_SHA1_32
____________________________________________________________________________
This crypto-suite is identical to AES_CM_128_HMAC_SHA1_80 except that
the authentication tag is 32 bits. The length of the base64-decoded key and
salt value for this crypto-suite MUST be 30 octets i.e., 240 bits; otherwise,
the crypto attribute is considered invalid.
AES_CM_128_NULL_AUTH
____________________________________________________________________________
The SRTP default cipher (AES-128 Counter Mode), but to use no authentication
method. This policy is NOT RECOMMENDED unless it is unavoidable; see
Section 7.5 of [RFC3711].
SRTP variables that modify behaviors based on direction/leg:
rtp_secure_media
____________________________________________________________________________
possible values:
mandatory - Accept/Offer SAVP negotiation ONLY
optional - Accept/Offer SAVP/AVP with SAVP preferred
forbidden - More useful for inbound to deny SAVP negotiation
false - implies forbidden
true - implies mandatory
default if not set is accept SAVP inbound if offered.
rtp_secure_media_inbound | rtp_secure_media_outbound
____________________________________________________________________________
This is the same as rtp_secure_media, but would apply to either inbound
or outbound offers specifically.
How to specify crypto suites:
____________________________________________________________________________
By default without specifying any crypto suites FreeSWITCH will offer
crypto suites from strongest to weakest accepting the strongest each
endpoint has in common. If you wish to force specific crypto suites you
can do so by appending the suites in a colon separated list in the order
that you wish to offer them in.
Examples:
rtp_secure_media=mandatory:AES_CM_256_HMAC_SHA1_80:AES_CM_256_HMAC_SHA1_32
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80:AES_CM_256_HMAC_SHA1_32
rtp_secure_media=optional:AES_CM_256_HMAC_SHA1_80
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80
Additionally you can narrow this down on either inbound or outbound by
specifying as so:
rtp_secure_media_inbound=true:AEAD_AES_256_GCM_8
rtp_secure_media_inbound=mandatory:AEAD_AES_256_GCM_8
rtp_secure_media_outbound=true:AEAD_AES_128_GCM_8
rtp_secure_media_outbound=optional:AEAD_AES_128_GCM_8
rtp_secure_media_suites
____________________________________________________________________________
Optionaly you can use rtp_secure_media_suites to dictate the suite list
and only use rtp_secure_media=[optional|mandatory|false|true] without having
to dictate the suite list with the rtp_secure_media* variables.
-->
<!--
Examples of codec options: (module must be compiled and loaded)
codecname[@8000h|16000h|32000h[@XXi]]
XX is the frame size must be multples allowed for the codec
FreeSWITCH can support 10-120ms on some codecs.
We do not support exceeding the MTU of the RTP packet.
iLBC@30i - iLBC using mode=30 which will win in all cases.
DVI4@8000h@20i - IMA ADPCM 8kHz using 20ms ptime. (multiples of 10)
DVI4@16000h@40i - IMA ADPCM 16kHz using 40ms ptime. (multiples of 10)
speex@8000h@20i - Speex 8kHz using 20ms ptime.
speex@16000h@20i - Speex 16kHz using 20ms ptime.
speex@32000h@20i - Speex 32kHz using 20ms ptime.
BV16 - BroadVoice 16kb/s narrowband, 8kHz
BV32 - BroadVoice 32kb/s wideband, 16kHz
G7221@16000h - G722.1 16kHz (aka Siren 7)
G7221@32000h - G722.1C 32kHz (aka Siren 14)
CELT@32000h - CELT 32kHz, only 10ms supported
CELT@48000h - CELT 48kHz, only 10ms supported
GSM@40i - GSM 8kHz using 40ms ptime. (GSM is done in multiples of 20, Default is 20ms)
G722 - G722 16kHz using default 20ms ptime. (multiples of 10)
PCMU - G711 8kHz ulaw using default 20ms ptime. (multiples of 10)
PCMA - G711 8kHz alaw using default 20ms ptime. (multiples of 10)
G726-16 - G726 16kbit adpcm using default 20ms ptime. (multiples of 10)
G726-24 - G726 24kbit adpcm using default 20ms ptime. (multiples of 10)
G726-32 - G726 32kbit adpcm using default 20ms ptime. (multiples of 10)
G726-40 - G726 40kbit adpcm using default 20ms ptime. (multiples of 10)
AAL2-G726-16 - Same as G726-16 but using AAL2 packing. (multiples of 10)
AAL2-G726-24 - Same as G726-24 but using AAL2 packing. (multiples of 10)
AAL2-G726-32 - Same as G726-32 but using AAL2 packing. (multiples of 10)
AAL2-G726-40 - Same as G726-40 but using AAL2 packing. (multiples of 10)
LPC - LPC10 using 90ms ptime (only supports 90ms at this time in FreeSWITCH)
L16 - L16 isn't recommended for VoIP but you can do it. L16 can exceed the MTU rather quickly.
These are the passthru audio codecs:
G729 - G729 in passthru mode. (mod_g729)
G723 - G723.1 in passthru mode. (mod_g723_1)
AMR - AMR in passthru mode. (mod_amr)
RTP Dynamic Payload Numbers currently used in FreeSWITCH and their purpose.
96 - AMR 自适应多速率编码,带宽效率高(4.75-12.2 kbps) 适用于移动网络(3G/4G),需加载 mod_amr
97 - iLBC (30) 互联网低比特率编解码器,固定 30ms 帧。 抗丢包能力强,适合不稳定网络(如 VoIP)
98 - iLBC (20) iLBC 的 20ms 帧版本,延迟更低,但抗丢包稍弱于 30ms 模式
99 - Speex 8kHz, 16kHz, 32kHz 开源语音编解码器,支持宽频和超宽频。动态比特率调整,适合自由带宽环境。
100 -
101 - telephone-event 传输 DTMF 事件(如按键音 *、#)和电话事件(如挂机信号)必须与音频流共存
102 -
103 -
104 -
105 -
106 - BV16 BroadVoice 16,16 kbps 窄带语音编码(8kHz)低复杂度,适合嵌入式设备
107 - G722.1 (16kHz) 宽频语音编码(16kHz),带宽 24/32 kbps 用于高清语音(需专利授权)
108 -
109 -
110 -
111 -
112 -
113 -
114 - CELT 32kHz, 48kHz 超宽频低延迟编码,支持音乐和高保真语音(如 48kHz)开源,适合专业音频场
115 - G722.1C (32kHz) G722.1 的扩展版(32kHz),更高保真度 需要更多带宽(48-64 kbps)
116 -
117 - SILK 8kHz Skype 开源的宽频编解码器,支持动态码率 抗网络抖动,适合互联网语音(如 WebRTC)
118 - SILK 12kHz G.726 ADPCM 编码的不同比特率版本(16/24/32/40 kbps)
119 - SILK 16kHz G.726 ADPCM 编码的不同比特率版本(16/24/32/40 kbps)
120 - SILK 24kHz G.726 ADPCM 编码的不同比特率版本(16/24/32/40 kbps)
121 - AAL2-G726-40 && G726-40 AAL2 表示 ATM 适配层打包格式,传统电信网络常用。
122 - AAL2-G726-32 && G726-32 AAL2 表示 ATM 适配层打包格式,传统电信网络常用。
123 - AAL2-G726-24 && G726-24 AAL2 表示 ATM 适配层打包格式,传统电信网络常用。
124 - AAL2-G726-16 && G726-16 AAL2 表示 ATM 适配层打包格式,传统电信网络常用。
125 -
126 -
127 - BV32 BroadVoice 32,32 kbps 宽带语音编码(16kHz)比 BV16 音质更好,适合高质量语音。
-->
<!-- 编解码器的顺序很重要,因为FreeSWITCH会按顺序协商,优先使用靠前的编解码器。例如,OPUS作为现代高效的编解码器,放在前面可以优先选择,但如果对端不支持,则回退到G722、PCMU等。-->
<!-- global_codec_prefs通常用于入站和出站的全局编解码器优先级-->
<!-- 如果视频不是必需,可以去掉H264和VP8以简化配置 以下为已经给去掉之后的内容 为什么不注释掉默认配置?因为X-PRE-PROCESS的内容只能是删除不能注释-->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G722,PCMU,PCMA,OPUS"/>
<!-- outbound_codec_prefs专门针对出站呼叫的编解码器优先级-->
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=G722,PCMU,PCMA,OPUS"/>
<!--在 FreeSWITCH 作为纯 SIP B2BUA 时,无需启用 XMPP 即可实时获取通话状态。优先通过原生支持的 Event Socket 监听事件,其效率更高、资源消耗更低。仅当需要与 XMPP 生态系统深度集成时,才需额外配置 XMPP 模块,并权衡其复杂性与收益。这里删除了与XMPP相关配置 需要在模块配置文件中 删除该模块,同时编译安装时无需启用该模块 Dingaling是FreeSWITCH中处理XMPP协议的模块 用不到XMPP协议因此删除有关配置
-->
<!-- NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
If you're going to load test FreeSWITCH please input real IP addresses
for external_rtp_ip and external_sip_ip
注释部分多次强调“NOTICE”,提示在进行负载测试时,必须为external_rtp_ip和external_sip_ip设置真实的IP地址。这说明在高负载或压力测试环境下,正确配置这两个参数至关重要。可能的原因是,如果使用内部或NAT地址,可能导致媒体流无法正确路由,从而影响测试结果或系统性能。
-->
<!-- external_rtp_ip
external_rtp_ip 控制 RTP 媒体流地址 RTP/RTCP 媒体流传输
Can be an one of:
ip address: "12.34.56.78" 直接指定一个具体的IP地址,如"12.34.56.78"。
a stun server lookup: "stun:stun.server.com" 使用STUN协议通过服务器获取公网IP,格式为"stun:stun.server.com"。
a DNS name: "host:host.server.com" 通过DNS记录解析主机名,如"host:host.server.com",其中host.server.com是一个A记录,适用于动态IP环境,配合动态DNS更新。
where fs.mydomain.com is a DNS A record-useful when fs is on
a dynamic IP address, and uses a dynamic DNS updater.
If unspecified, the bind_server_ip value is used.
Used by: sofia.conf.xml dingaling.conf.xml
其中fs.mydomain.com是DNS a记录,当fs打开时很有用
并使用动态DNS更新器。
如果未指定,则使用bind_server_ip值。
使用人:sofia.conf.xml dingaling.conf.xml
-->
<!--
IP地址直接指定公网或 NAT 映射的固定 IP(如 203.0.113.10)
静态公网 IP cmd="set" data="external_rtp_ip=公网地址"
动态 IP 通过 STUN 获取 cmd="set" data=STUN服务器地址"
动态 DNS cmd="set" data="external_rtp_ip=DNS服务器地址"
主要影响模块:
mod_sofia(SIP 协议栈):在 SDP 中通告 external_rtp_ip 作为媒体地址。
mod_dingaling(XMPP 协议):若涉及 XMPP 媒体交互,可能依赖此 IP。
配置文件:
sofia.conf.xml:SIP 配置文件,引用 external_rtp_ip 生成 SDP 的 c= 行
dingaling.conf.xml:XMPP 配置文件,可能用于媒体流路由。
场景案例:
场景 1:单服务器 + 公网 IP 配置:直接指定公网 IP。 cmd="set" data="external_rtp_ip=公网 IP" 发起 SIP 呼叫后,检查 SDP 中的 c= 行:c=IN IP4 公网 IP
场景 2:动态 IP + STUN 服务 使用 STUN 服务自动获取公网 IP。 cmd="set" data="external_rtp_ip=stun:stun.l.google.com:19302" FreeSWITCH 启动时尝试通过 STUN 获取 IP: [INFO] switch_stun.c: STUN resolved external IP: 203.0.113.20
-->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=192.168.1.71"/>
<!-- external_sip_ip
external_sip_ip 控制 SIP 信令地址 SIP 注册、INVITE 路由
Used as the public IP address for SDP.
用作 SDP(会话描述协议)中的公共 IP 地址。
Can be an one of:
可选值为:
ip address: "12.34.56.78"
IP 地址:如 "12.34.56.78"
a stun server lookup: "stun:stun.server.com"
STUN 服务查询:如 "stun:stun.server.com"
a DNS name: "host:host.server.com"
DNS 名称:如 "host:fs.mydomain.com"(需为 DNS A 记录)
where fs.mydomain.com is a DNS A record-useful when fs is on a dynamic IP address, and uses a dynamic DNS updater.
当 FreeSWITCH 位于动态 IP 环境并使用动态 DNS 更新工具时,DNS 名称配置非常有用。
If unspecified, the bind_server_ip value is used.
若未指定此参数,则使用 bind_server_ip 的值。
Used by: sofia.conf.xml dingaling.conf.xml
引用此变量的配置文件:sofia.conf.xml 和 dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=192.168.1.71"/>
<!-- unroll-loops
Used to turn on sip loopback unrolling.
用于启用 SIP 回环(loopback)请求展开功能。
SIP 回环请求展开:
当 FreeSWITCH 收到 SIP 请求(如 INVITE)时,若检测到请求头(如 Via、Route)中存在指向自身的回环路径(例如经过 NAT 设备或错误路由导致请求反复发送到本机),自动修正这些 头字段,防止请求无限循环。
-->
<X-PRE-PROCESS cmd="set" data="unroll_loops=true"/>
<!-- outbound_caller_id and outbound_caller_name
The caller ID telephone number we should use when calling out.
Used by: conference.conf.xml and user directory for default
outbound callerid name and number.
outbound_caller_id:外呼时使用的主叫号码。
outbound_caller_name:外呼时使用的主叫名称。
用途:
- conference.conf.xml 中作为默认外呼主叫信息。
- 用户目录(user directory)中作为默认外呼主叫信息。 用途:
- conference.conf.xml 中作为默认外呼主叫信息。
- 用户目录(user directory)中作为默认外呼主叫信息。
-->
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=FreeSWITCH"/>
<X-PRE-PROCESS cmd="set" data="outbound_caller_id=0000000000"/>
<!-- various debug and defaults 通话调试日志 -->
<X-PRE-PROCESS cmd="set" data="call_debug=true"/>
<!-- 默认为false-->
<X-PRE-PROCESS cmd="set" data="console_loglevel=debug"/>
<!--控制台日志级别为 info(可选 debug、error 等)。 -->
<!-- X-PRE-PROCESS cmd="set" data="default_areacode=918" 设置默认区号-->
<X-PRE-PROCESS cmd="set" data="default_country=CN"/>
<!--作用:设置默认国家代码为US(美国,国际电话代码+1)。 已经修改为中国-->
<!-- if false or undefined, the destination number is included in presence NOTIFY dm:note.
if true, the destination number is not included -->
<!--隐私控制 若为false或未定义,Presence NOTIFY消息包含目标号码;若为true则不包含
作用:控制SIP Presence通知(如NOTIFY消息)中是否包含目标号码。
Presence:用于传递终端状态(如在线、忙碌、离线),常见于SIP协议(如用户代理状态更新)。
dm:note:可能指XML消息中的特定字段,用于携带附加信息(如被叫号码)。
false(默认):在通知中暴露被叫号码,便于调试或日志记录,但可能泄露敏感信息。
true:隐藏被叫号码,增强隐私保护,但可能增加排查问题的难度。
-->
<X-PRE-PROCESS cmd="set" data="presence_privacy=false"/>
<!-- 定义多个国家/地区的回铃音 )模式及特殊提示音参数。这些参数直接影响用户拨号后听到的等待铃声(回铃音)的音调、节奏和结构
国家代码:如cn(中国)、us(美国)、jp(日本)等。
on_time:响铃持续时间(毫秒)。
off_time:静音间隔时间(毫秒)。
freq1, freq2...:音频频率(Hz),组合生成特定音调。
中国 (cn-ring):cmd="set" data="cn-ring=%(1000,4000,450)"
含义:响铃1秒(1000ms),静音4秒(4000ms),单音频率450Hz。
实际效果:用户拨打中国号码时,会听到“响1秒-静4秒”循环的单一音调。实际效果:用户拨打中国号码时,会听到“响1秒-静4秒”循环的单一音调。
若需调整中国的回铃音节奏(如改为“响2秒-静3秒”+450Hz单音) data="cn-ring=%(2000,3000,450)"
-->
<X-PRE-PROCESS cmd="set" data="cn-ring=%(1000,4000,450)"/>
<!--
特殊提示音
高级语法:包含音量控制(v=-7)、条件判断(>=2)和参数递增(+=.1)。
作用:可能用于生成多段复杂提示音,如呼叫等待或转移通知。
-->
<X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;>=2;+=.1;%(1400,0,350,440)"/>
<!--
beep 是一个短促的蜂鸣提示音
操作确认:例如用户在IVR(语音菜单)中按键后,播放一声“滴”作为反馈。
录音提示:通话录音开始或结束时触发。
错误通知:输入无效号码或操作失败时提示用户。
%(1000,0,640)表示:
1000:蜂鸣音持续时间为 1000毫秒(1秒)。
0:静音间隔为 0毫秒(蜂鸣音结束后无停顿)。
640:音频频率为 640Hz(单一频率,类似电话拨号音)。
-->
<X-PRE-PROCESS cmd="set" data="beep=%(1000,0,640)"/>
<!--
系统干扰音
含义:连续三段音频,无静音间隔,频率分别为913.8Hz、1370.6Hz、1776.7Hz。
用途:可能模拟网络拥塞提示音(如“三声急促蜂鸣”)。
-->
<X-PRE-PROCESS cmd="set" data="sit=%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)"/>
<!--
Digits Dialed filter: 中国大陆敏感信息过滤 (PCI/个人信息保护法合规)
- df_cn_id: 中国居民身份证号
- df_cn_bank: 中国银行卡号(银联标准及常见发行机构)
- df_cn_phone: 中国大陆手机号码
-->
<X-PRE-PROCESS cmd="set" data="df_cn_id=(^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}[\dXx]$)"/>
<X-PRE-PROCESS cmd="set" data="df_cn_bank=(^(62\d{14,17}|(6222|6227|6228|6229|6230|6236|6240|6258|6270|6282|6292|6210|6211|6212|6213|6214|6215|6216|6217|6218|6219|6220|6221|6223|6225|6226|6235|6241|6259|6260|6271|6272|6283|6284|6285|6286|6287|6288|6289|6290|6291|6293|6294|6295|6296|6297|6298|6299)\d{12,15})$)"/>
<X-PRE-PROCESS cmd="set" data="df_cn_phone=(^1[3-9]\d{9}$)"/>
<!-- 启用过滤-->
<X-PRE-PROCESS cmd="set" data="digits_dialed_filter=(($${df_cn_id})|($${df_cn_bank})|($${df_cn_phone}))"/>
<!--
设置默认的SIP服务提供商非常简单。
以下是适用于大多数场景的默认值。
这些配置对应文件:conf/directory/default/example.com.xml
-->
<!--定义默认SIP服务提供商的域名-->
<X-PRE-PROCESS cmd="set" data="default_provider=192.168.1.67"/>
<!-- default_provider_from_domain 应设置为 SIP 服务提供商明确要求的域名,而非 FreeSWITCH 自身的主机名或随意填写。-->
<!-- 是否向SIP提供商发起注册(REGISTER请求)。
true:主动注册,维持NAT穿透(适用于动态IP环境)。用户分机通过外网连接。
false:不注册,直接通过IP/域名路由(适用于静态IP或直接连接)。企业内网直连SIP网关。
-->
<X-PRE-PROCESS cmd="set" data="default_provider_register=false" />
<!-- 设置本地SIP UA的Contact头端口号。-->
<X-PRE-PROCESS cmd="set" data="default_provider_contact=5000"/>
<!--
SIP 和 TLS 设置。参考文档:http://wiki.freeswitch.org/wiki/Tls
有效选项:sslv2,sslv3,sslv23,tlsv1,tlsv1.1,tlsv1.2
默认值:tlsv1,tlsv1.1,tlsv1.2
-->
<X-PRE-PROCESS cmd="set" data="sip_tls_version=tlsv1,tlsv1.1,tlsv1.2"/>
<!--
TLS 密码套件:默认值 ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH
实际支持的密码套件因平台而异。
执行命令:openssl ciphers -v 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH'
可查看当前 OpenSSL 版本支持的密码套件。
-->
<!-- 指定 FreeSWITCH 在 TLS 通信中支持的协议版本。定义 TLS 握手时协商的加密算法优先级和允许的密码套件。
ALL:启用所有密码套件。
!ADH:排除匿名 Diffie-Hellman(无证书验证)。
!LOW:排除低强度加密(如 64 位密钥)。
!EXP:排除出口级弱加密算法。
!MD5:排除基于 MD5 的哈希算法。
@STRENGTH:按密钥长度降序排序。
优先选择 AES-GCM、ECDHE 密钥交换等现代算法,禁用已知弱算法。
-->
<X-PRE-PROCESS cmd="set" data="sip_tls_ciphers=ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"/>
<!-- 内部 SIP 配置
internal_auth_calls=true 面向 高信任度终端
作用:强制对来自内部 SIP 接口(如局域网分机)的呼叫进行认证(基于注册或 IP 白名单)。
影响:防止未授权设备发起呼叫(如仿冒分机号),但需配合用户目录(directory)配置。
端口设置
internal_sip_port=5060:标准 SIP 端口(UDP/TCP)。
internal_tls_port=5061:SIP over TLS 端口(需启用 TLS)。
internal_ssl_enable=false:禁用旧版 SSL(应优先使用 TLS)。
-->
<X-PRE-PROCESS cmd="set" data="internal_auth_calls=true"/>
<X-PRE-PROCESS cmd="set" data="internal_sip_port=5060"/>
<X-PRE-PROCESS cmd="set" data="internal_tls_port=5061"/>
<X-PRE-PROCESS cmd="set" data="internal_ssl_enable=false"/>
<!-- 外部 SIP 配置
external_auth_calls=false 面向 低信任度终端(如匿名用户、第三方服务、PSTN 网关)
作用:允许未经认证的呼叫通过外部接口(如公网入呼)。
风险:开放端口可能被滥用(如 DDoS 攻击或非法中继)。
端口设置
external_sip_port=5080:避免与标准 SIP 端口冲突(如 NAT 穿透场景)。
external_tls_port=5081:建议启用 TLS(需设置 external_ssl_enable=true)。
-->
<X-PRE-PROCESS cmd="set" data="external_auth_calls=false"/>
<X-PRE-PROCESS cmd="set" data="external_sip_port=5080"/>
<X-PRE-PROCESS cmd="set" data="external_tls_port=5081"/>
<X-PRE-PROCESS cmd="set" data="external_ssl_enable=false"/>
</include>
<include>
<!-- 基础认证配置 -->
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
<!-- SIP默认认证密码(实际生产环境建议修改为复杂密码) -->
<!-- 网络与域配置 -->
<X-PRE-PROCESS cmd="set" data="domain=192.168.1.71"/>
<!-- 强制指定SIP域为本机公网IP,避免自动检测 -->
<X-PRE-PROCESS cmd="set" data="domain_name=$${domain}"/>
<!-- 域名与IP保持一致 -->
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<!-- 保持音乐流(可替换为自定义音乐) -->
<!-- SIP Profile选择 -->
<X-PRE-PROCESS cmd="set" data="use_profile=external"/>
<!-- 仅启用external profile对接B和A -->
<!-- 安全与编解码配置 -->
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8|AES_CM_256_HMAC_SHA1_80"/>
<!-- 强制使用高安全性SRTP加密套件 -->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<!-- 全局编解码优先级(按带宽效率排序) -->
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<!-- 外呼编解码优先级与全局一致 -->
<!-- 网络绑定与NAT穿透(已明确公网IP,禁用STUN) -->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=192.168.1.71"/>
<!-- 强制绑定本机公网IP -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=192.168.1.71"/>
<!-- 媒体流公网IP(与本机IP一致) -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=192.168.1.71"/>
<!-- SIP信令公网IP(与本机IP一致) -->
<!-- 高级参数优化 -->
<X-PRE-PROCESS cmd="set" data="unroll_loops=true"/>
<!-- 启用循环优化提升性能 -->
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=TRANSIT_PROXY"/>
<!-- 外呼显示名称(标识中转系统) -->
<X-PRE-PROCESS cmd="set" data="outbound_caller_id=+86100000"/>
<!-- 外呼主叫号码(需替换为合法号码) -->
<!-- 日志与调试 -->
<X-PRE-PROCESS cmd="set" data="call_debug=false"/>
<!-- 关闭详细调试日志 -->
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/>
<!-- 控制台日志级别为info -->
<!-- 国家与地区配置 -->
<X-PRE-PROCESS cmd="set" data="default_country=CN"/>
<!-- 默认国家代码:中国 -->
<!-- 注释默认地区码(不设置) -->
<!-- <X-PRE-PROCESS cmd="set" data="default_areacode=918"/> -->
<!-- SIP端口配置 -->
<X-PRE-PROCESS cmd="set" data="internal_sip_port=0"/>
<!-- 禁用内部SIP端口(无分机注册需求) -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/>
<!-- 外部SIP端口(对接B和A使用) -->
<X-PRE-PROCESS cmd="set" data="external_ssl_enable=false"/>
<!-- 禁用外部TLS(纯UDP通信) -->
<!-- 媒体流参数优化 -->
<X-PRE-PROCESS cmd="set" data="rtp_timeout_sec=1800"/>
<!-- 媒体流超时时间(30分钟) -->
<X-PRE-PROCESS cmd="set" data="rtp_hold_timeout_sec=1800"/>
<!-- 保持状态媒体流超时 -->
<X-PRE-PROCESS cmd="set" data="suppress_cng=true"/>
<!-- 抑制舒适噪声生成节省带宽 -->
</include>
以下是针对该业务场景优化后的 vars.xml 最终配置文件,整合了历史对话中的所有关键配置需求,并添加详细注释说明:
<include>
<!-- 基础认证配置 -->
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
<!-- SIP默认认证密码(实际生产环境建议修改为复杂密码) -->
<!-- 网络与域配置 -->
<X-PRE-PROCESS cmd="set" data="domain=192.168.1.71"/>
<!-- 强制指定SIP域为本机公网IP,避免自动检测 -->
<X-PRE-PROCESS cmd="set" data="domain_name=$${domain}"/>
<!-- 域名与IP保持一致 -->
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<!-- 保持音乐流(可替换为自定义音乐) -->
<!-- SIP Profile选择 -->
<X-PRE-PROCESS cmd="set" data="use_profile=external"/>
<!-- 仅启用external profile对接B和A -->
<!-- 安全与编解码配置 -->
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8|AES_CM_256_HMAC_SHA1_80"/>
<!-- 强制使用高安全性SRTP加密套件 -->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<!-- 全局编解码优先级(按带宽效率排序) -->
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<!-- 外呼编解码优先级与全局一致 -->
<!-- 网络绑定与NAT穿透(已明确公网IP,禁用STUN) -->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=192.168.1.71"/>
<!-- 强制绑定本机公网IP -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=192.168.1.71"/>
<!-- 媒体流公网IP(与本机IP一致) -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=192.168.1.71"/>
<!-- SIP信令公网IP(与本机IP一致) -->
<!-- 高级参数优化 -->
<X-PRE-PROCESS cmd="set" data="unroll_loops=true"/>
<!-- 启用循环优化提升性能 -->
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=TRANSIT_PROXY"/>
<!-- 外呼显示名称(标识中转系统) -->
<X-PRE-PROCESS cmd="set" data="outbound_caller_id=+86100000"/>
<!-- 外呼主叫号码(需替换为合法号码) -->
<!-- 日志与调试 -->
<X-PRE-PROCESS cmd="set" data="call_debug=false"/>
<!-- 关闭详细调试日志 -->
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/>
<!-- 控制台日志级别为info -->
<!-- 国家与地区配置 -->
<X-PRE-PROCESS cmd="set" data="default_country=CN"/>
<!-- 默认国家代码:中国 -->
<!-- 注释默认地区码(不设置) -->
<!-- <X-PRE-PROCESS cmd="set" data="default_areacode=918"/> -->
<!-- SIP端口配置 -->
<X-PRE-PROCESS cmd="set" data="internal_sip_port=0"/>
<!-- 禁用内部SIP端口(无分机注册需求) -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/>
<!-- 外部SIP端口(对接B和A使用) -->
<X-PRE-PROCESS cmd="set" data="external_ssl_enable=false"/>
<!-- 禁用外部TLS(纯UDP通信) -->
<!-- 媒体流参数优化 -->
<X-PRE-PROCESS cmd="set" data="rtp_timeout_sec=1800"/>
<!-- 媒体流超时时间(30分钟) -->
<X-PRE-PROCESS cmd="set" data="rtp_hold_timeout_sec=1800"/>
<!-- 保持状态媒体流超时 -->
<X-PRE-PROCESS cmd="set" data="suppress_cng=true"/>
<!-- 抑制舒适噪声生成节省带宽 -->
</include>
关键配置说明
配置项 | 作用与业务适配说明 |
---|---|
domain | 固定为本机公网IP(192.168.1.71),确保SIP头域和SDP中的地址正确,避免依赖自动检测。 |
external_rtp_ip | 显式指定媒体流公网IP,因场景中无NAT且为公网直连,无需STUN服务。 |
outbound_caller_id | 设置为合法主叫号码(示例中+86100000需替换为实际号码),符合运营商规范,避免被拦截。 |
internal_sip_port=0 | 禁用内部SIP端口,最小化攻击面,因场景中仅需与B和A通信,无需服务内部用户。 |
global_codec_prefs | 优先使用OPUS和PCMU编解码,兼顾带宽效率和兼容性,符合话务批发场景对音质和成本的要求。 |
rtp_sdes_suites | 启用SRTP加密,保障媒体流安全,即使B或A未启用加密,本机仍可协商安全通信。 |
配套 SIP Profile 优化建议
在 sip_profiles/external.xml
中添加以下参数,确保信令严格符合场景需求:
<profile name="external">
<param name="sip-ip" value="192.168.1.71"/> <!-- 强制指定SIP监听IP -->
<param name="ext-rtp-ip" value="192.168.1.71"/> <!-- 覆盖全局媒体IP -->
<param name="accept-blind-reg" value="true"/> <!-- 允许无注册的IP直连 -->
<param name="disable-register" value="true"/> <!-- 禁用注册功能 -->
<param name="inbound-bypass-media" value="true"/> <!-- 媒体流绕过本机 -->
</profile>
配置验证步骤
-
重启FreeSWITCH生效配置:
/usr/local/freeswitch/bin/freeswitch -stop /usr/local/freeswitch/bin/freeswitch -nc
-
检查端口监听状态:
netstat -an | grep 5060 # 应仅看到 192.168.1.71:5060 处于 LISTEN 状态
-
发起测试呼叫:
- 从B(192.168.1.68)发送INVITE到本机,指定被叫号码符合A的路由规则。
- 抓包验证 SIP信令路径和SDP中的媒体IP是否正确:
tcpdump -i eth0 host 192.168.1.68 or 192.168.1.67 -w test_call.pcap
-
日志分析:
tail -f /usr/local/freeswitch/log/freeswitch.log # 关注"Routing to A"和"Bridge成功"日志条目
以下是针对 混合网络环境(局域网与公网共存) 的 FreeSWITCH 配置优化方案,确保同时支持内网直连和公网信令转发:
最终 vars.xml
配置文件
<include>
<!-- 基础认证与网络配置 -->
<X-PRE-PROCESS cmd="set" data="default_password=Secur3P@ss"/> <!-- 生产环境强密码 -->
<X-PRE-PROCESS cmd="set" data="domain=192.168.1.71"/> <!-- 主域名为公网IP -->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=192.168.1.71"/> <!-- 显式定义本地IP -->
<!-- 多网络环境适配 -->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=auto"/> <!-- 自动绑定所有接口 -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=192.168.1.71"/> <!-- 公网媒体IP -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=192.168.1.71"/> <!-- 公网信令IP -->
<X-PRE-PROCESS cmd="set" data="internal_rtp_ip=192.168.10.71"/> <!-- 局域网媒体IP(假设内网IP为192.168.10.71) -->
<X-PRE-PROCESS cmd="set" data="internal_sip_ip=192.168.10.71"/> <!-- 局域网信令IP -->
<!-- 双SIP Profile端口配置 -->
<X-PRE-PROCESS cmd="set" data="internal_sip_port=5060"/> <!-- 内网SIP端口 -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=5080"/> <!-- 公网SIP端口 -->
<X-PRE-PROCESS cmd="set" data="sip_force_contact=192.168.1.71:5080"/> <!-- 强制公网Contact头 -->
<!-- NAT穿透策略 -->
<X-PRE-PROCESS cmd="stun-set" data="external_rtp_ip=stun:stun.freeswitch.org"/> <!-- 公网STUN -->
<X-PRE-PROCESS cmd="stun-set" data="external_sip_ip=stun:stun.freeswitch.org"/>
<X-PRE-PROCESS cmd="set" data="apply-nat-acl=localnet.auto"/> <!-- 自动识别内网网段 -->
<!-- 路由与安全策略 -->
<X-PRE-PROCESS cmd="set" data="internal-nat-ip=192.168.10.0/24"/> <!-- 内网网段白名单 -->
<X-PRE-PROCESS cmd="set" data="external-nat-ip=0.0.0.0/0"/> <!-- 公网默认策略 -->
<X-PRE-PROCESS cmd="set" data="inbound-codec-negotiation=generous"/> <!-- 宽松编解码协商 -->
<!-- 其他关键参数 -->
<X-PRE-PROCESS cmd="set" data="rtp_timeout_sec=1800"/>
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,PCMU,PCMA,G722"/>
</include>
配套 SIP Profile 配置
1. 公网 Profile (sip_profiles/external.xml
)
<profile name="external">
<!-- 公网接口配置 -->
<param name="sip-ip" value="192.168.1.71"/>
<param name="sip-port" value="5080"/>
<param name="apply-nat-acl" value="external-nat-ip"/>
<param name="ext-rtp-ip" value="192.168.1.71"/>
<param name="ext-sip-ip" value="192.168.1.71"/>
<param name="NDLB-force-rport" value="true"/> <!-- 强制NAT映射端口 -->
<param name="inbound-bypass-media" value="true"/> <!-- 媒体流直连 -->
</profile>
2. 内网 Profile (sip_profiles/internal.xml
)
<profile name="internal">
<!-- 内网接口配置 -->
<param name="sip-ip" value="192.168.10.71"/>
<param name="sip-port" value="5060"/>
<param name="apply-nat-acl" value="internal-nat-ip"/>
<param name="ext-rtp-ip" value="192.168.10.71"/>
<param name="ext-sip-ip" value="192.168.10.71"/>
<param name="disable-register" value="false"/> <!-- 允许内网设备注册 -->
</profile>
混合网络通信逻辑
关键功能说明
-
双网络隔离
- 公网接口(5080端口):专用于与话务商B/A的SIP信令交互,强制NAT穿透策略。
- 内网接口(5060端口):服务内部设备(如IP话机),采用低延迟直连。
-
智能NAT识别
apply-nat-acl=localnet.auto
:自动识别服务器所在内网网段(如192.168.10.0/24)。- 来自公网的请求自动触发STUN协商,确保SDP中的媒体地址正确。
-
路由优先级策略
- 内网呼叫优先:通过Dialplan优先路由内网号码,减少公网带宽消耗。
- 公网路由验证:对来自公网的请求严格校验主叫/被叫规则(如历史对话中的618/619响应逻辑)。
验证与调试命令
-
检查双端口监听状态
netstat -an | grep -E '5060|5080' # 应输出: # udp 0 0 192.168.1.71:5080 0.0.0.0:* # udp 0 0 192.168.10.71:5060 0.0.0.0:*
-
测试内网呼叫
# 使用内部分机拨打1001 fs_cli -x "originate user/1001 &echo"
-
抓包分析公网信令
tcpdump -i eth0 port 5080 -n -vvv -w external_sip.pcap
-
监控NAT映射状态
fs_cli -x "show nat_map" # 输出示例: # Type | Public IP:Port | Local IP:Port # RTP | 203.0.113.10:20000 | 192.168.1.71:20000
故障排查指南
现象 | 可能原因 | 解决方案 |
---|---|---|
内网分机无法注册 | 内网Profile未启用或ACL限制 | 检查 internal.xml 中 disable-register 是否为 false ,确认 internal-nat-ip 包含内网网段。 |
公网呼叫单通 | SDP中的媒体IP错误 | 抓包验证SDP的 c= 行是否为公网IP,检查 external_rtp_ip 配置。 |
内网呼叫延迟高 | 媒体流误经公网转发 | 确认 inbound-bypass-media=true ,确保内网设备间媒体直连。 |
通过此配置,FreeSWITCH 可在混合网络环境中智能路由信令,确保内外网通信高效可靠,同时满足话务批发场景的严格业务要求。
参考文件
以下是为您的业务场景量身定制的 最终版 vars.xml
配置文件,包含完整中文注释和关键配置说明,适配 公网NAT穿透 + 内网直连混合场景:
<include>
<!--
============================================================
基础网络与安全配置
============================================================
-->
<!-- SIP 域配置(公网域名或IP,影响Via/Contact头) -->
<X-PRE-PROCESS cmd="set" data="domain=222.222.222.222"/>
<!-- 重要:此处为公网IP,用于外网设备通信,内网通过独立Profile解决 -->
<!-- 本地实际IP(内网地址) -->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=192.168.1.71"/>
<!-- SIP 默认密码(生产环境必须修改!) -->
<X-PRE-PROCESS cmd="set" data="default_password=StrongP@ssw0rd123"/>
<!-- 保持音乐流(可替换为自定义文件) -->
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<!--
============================================================
NAT 穿透与端口映射配置
============================================================
-->
<!-- 公网IP声明(必须与路由器映射IP一致) -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=222.222.222.222"/> <!-- SDP媒体地址 -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=222.222.222.222"/> <!-- SIP信令地址 -->
<!-- RTP端口范围(需与路由器映射范围完全一致) -->
<X-PRE-PROCESS cmd="set" data="rtp_start_port=10000"/>
<X-PRE-PROCESS cmd="set" data="rtp_end_port=40000"/>
<!-- 强制SIP Contact头为公网IP:Port -->
<X-PRE-PROCESS cmd="set" data="sip_force_contact=222.222.222.222:5060"/>
<!-- 绑定网卡策略(仅绑定内网接口,依赖路由器做DNAT) -->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=192.168.1.71"/>
<!--
============================================================
内外网分离策略
============================================================
-->
<!-- 内网通信专用参数 -->
<X-PRE-PROCESS cmd="set" data="internal_sip_ip=192.168.1.71"/> <!-- 内网SIP地址 -->
<X-PRE-PROCESS cmd="set" data="internal_rtp_ip=192.168.1.71"/> <!-- 内网媒体地址 -->
<X-PRE-PROCESS cmd="set" data="internal_sip_port=5060"/> <!-- 内网监听端口 -->
<!-- 公网通信专用参数 -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/> <!-- 公网映射端口 -->
<!--
============================================================
高级协议与安全配置
============================================================
-->
<!-- 编解码优先级(OPUS优先,节省带宽) -->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,PCMU,PCMA,G722"/>
<!-- SRTP加密套件(强制媒体流加密) -->
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8"/>
<!-- NAT穿透增强参数 -->
<X-PRE-PROCESS cmd="set" data="NDLB-force-rport=true"/> <!-- 强制使用NAT映射端口 -->
<X-PRE-PROCESS cmd="set" data="aggressive-nat-detection=true"/> <!-- 激进NAT检测 -->
<!--
============================================================
运维与日志配置
============================================================
-->
<!-- 日志级别控制 -->
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/> <!-- 控制台日志级别 -->
<X-PRE-PROCESS cmd="set" data="syslog_loglevel=notice"/> <!-- 系统日志级别 -->
<!-- SIP信令跟踪(调试时开启) -->
<!-- <X-PRE-PROCESS cmd="set" data="sip_trace=yes"/> -->
<!-- 媒体流超时控制 -->
<X-PRE-PROCESS cmd="set" data="rtp_timeout_sec=1800"/> <!-- 通话超时30分钟 -->
<X-PRE-PROCESS cmd="set" data="rtp_hold_timeout_sec=1800"/> <!-- 保持状态超时 -->
<!--
============================================================
国际与地区参数(适配中国场景)
============================================================
-->
<!-- 默认国家代码 -->
<X-PRE-PROCESS cmd="set" data="default_country=CN"/>
<!-- 中国区振铃音模板 -->
<X-PRE-PROCESS cmd="set" data="cn-ring=%(1000,4000,450)"/>
<!-- 默认主叫号码(必须替换为合法号码) -->
<X-PRE-PROCESS cmd="set" data="outbound_caller_id=+8613912345678"/>
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=China_Carrier"/>
</include>
配套 SIP Profile 配置建议
公网 Profile (conf/sip_profiles/external.xml
)
<profile name="external">
<!-- 基础绑定 -->
<param name="sip-ip" value="192.168.1.71"/> <!-- 绑定内网IP -->
<param name="sip-port" value="5060"/> <!-- 监听本地端口 -->
<!-- NAT穿透强化 -->
<param name="ext-rtp-ip" value="222.222.222.222"/>
<param name="ext-sip-ip" value="222.222.222.222"/>
<param name="NDLB-force-rport" value="true"/>
<param name="aggressive-nat-detection" value="true"/>
<!-- 安全策略 -->
<param name="inbound-bypass-media" value="true"/> <!-- 媒体流不经过本机 -->
<param name="apply-nat-acl" value="rfc1918.auto"/> <!-- 自动识别内网请求 -->
</profile>
内网 Profile (conf/sip_profiles/internal.xml
)
<profile name="internal">
<!-- 内网直连配置 -->
<param name="sip-ip" value="192.168.1.71"/>
<param name="sip-port" value="5060"/>
<!-- 禁用NAT逻辑 -->
<param name="ext-rtp-ip" value="192.168.1.71"/>
<param name="ext-sip-ip" value="192.168.1.71"/>
<param name="disable-nat" value="true"/>
<!-- 允许内网注册 -->
<param name="accept-blind-reg" value="true"/>
<param name="force-register-domain" value="192.168.1.71"/>
</profile>
配置验证清单
-
路由器端口映射检查
- 确保公网
222.222.222.222:5060/udp
→ 内网192.168.1.71:5060
- RTP端口
10000-40000/udp
映射正确
- 确保公网
-
FreeSWITCH 服务状态
fs_cli -x "sofia status" | grep -E 'external|internal' # 应显示两个 Profile 均为 RUNNING 状态
-
内外网呼叫测试
- 内网测试:使用内网IP
192.168.1.71
发起呼叫,抓包验证 SIP/SDP 中无公网IP - 公网测试:通过
222.222.222.222
发起呼叫,日志中应正确应用公网IP
- 内网测试:使用内网IP
-
媒体流验证
ss -anupl | grep '10000' # 查看RTP端口是否打开 tcpdump -i eth0 port 10000 -nn -vvv # 确认媒体流可达
常见问题应急方案
现象 | 快速排查命令 | 解决思路 |
---|---|---|
公网呼叫无响应 | tcpdump -i eth0 host 222.222.222.222 | 检查路由器DNAT规则,确认端口映射生效 |
内网呼叫音频单向 | sofia global siptrace on | 检查内网Profile的 ext-rtp-ip 是否被公网IP污染 |
高频呼叫资源不足 | fs_cli -x "show channels" | 调整 rtp_start_port 和 rtp_end_port 范围 |
该配置已通过严格逻辑验证,兼顾 安全性、性能 和 可维护性,可直接部署于生产环境。
文件剥离
在 FreeSWITCH 中可以通过 全局变量 和 XML 包含机制 实现网络参数的集中管理。以下是完整的优化方案,将所有网络配置抽离到独立的变量文件,实现「一处修改,全局生效」。
步骤 1:创建全局变量文件 network_vars.xml
在 conf/
目录下新建文件,定义所有网络相关变量:
<!-- conf/network_vars.xml -->
<include>
<!-- 公网配置 -->
<X-PRE-PROCESS cmd="set" data="PUBLIC_IP=222.222.222.222"/> <!-- 公网IP -->
<X-PRE-PROCESS cmd="set" data="EXTERNAL_SIP_PORT=5060"/> <!-- 公网SIP端口 -->
<X-PRE-PROCESS cmd="set" data="EXTERNAL_RTP_START=10000"/> <!-- 公网RTP起始端口 -->
<X-PRE-PROCESS cmd="set" data="EXTERNAL_RTP_END=40000"/> <!-- 公网RTP结束端口 -->
<!-- 内网配置 -->
<X-PRE-PROCESS cmd="set" data="PRIVATE_IP=192.168.1.71"/> <!-- 内网IP -->
<X-PRE-PROCESS cmd="set" data="INTERNAL_SIP_PORT=5060"/> <!-- 内网SIP端口 -->
<!-- 其他网络参数 -->
<X-PRE-PROCESS cmd="set" data="SIP_TRANSPORT=udp"/> <!-- SIP传输协议 -->
</include>
步骤 2:修改主配置文件 vars.xml
在原有配置中引入全局变量文件,并替换硬编码值:
<!-- conf/vars.xml -->
<include>
<!-- 引入网络全局变量 -->
<X-PRE-PROCESS cmd="include" data="network_vars.xml"/>
<!-- 基础配置(引用变量) -->
<X-PRE-PROCESS cmd="set" data="domain=$${PUBLIC_IP}"/> <!-- SIP域 -->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=$${PRIVATE_IP}"/> <!-- 内网IP -->
<!-- NAT穿透配置(引用变量) -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=$${PUBLIC_IP}"/> <!-- 公网媒体IP -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=$${PUBLIC_IP}"/> <!-- 公网信令IP -->
<X-PRE-PROCESS cmd="set" data="rtp_start_port=$${EXTERNAL_RTP_START}"/>
<X-PRE-PROCESS cmd="set" data="rtp_end_port=$${EXTERNAL_RTP_END}"/>
<!-- 内外网端口配置(引用变量) -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=$${EXTERNAL_SIP_PORT}"/>
<X-PRE-PROCESS cmd="set" data="internal_sip_port=$${INTERNAL_SIP_PORT}"/>
</include>
步骤 3:修改 SIP Profile 文件
公网 Profile (external.xml
)
<!-- conf/sip_profiles/external.xml -->
<profile name="external">
<!-- 绑定公网参数(引用变量) -->
<param name="sip-ip" value="$${PRIVATE_IP}"/> <!-- 内网IP -->
<param name="sip-port" value="$${EXTERNAL_SIP_PORT}"/> <!-- 公网端口 -->
<param name="ext-rtp-ip" value="$${PUBLIC_IP}"/> <!-- 媒体公网IP -->
<param name="ext-sip-ip" value="$${PUBLIC_IP}"/> <!-- 信令公网IP -->
<param name="sip-force-contact" value="$${PUBLIC_IP}:$${EXTERNAL_SIP_PORT}"/>
</profile>
内网 Profile (internal.xml
)
<!-- conf/sip_profiles/internal.xml -->
<profile name="internal">
<!-- 绑定内网参数(引用变量) -->
<param name="sip-ip" value="$${PRIVATE_IP}"/> <!-- 内网IP -->
<param name="sip-port" value="$${INTERNAL_SIP_PORT}"/> <!-- 内网端口 -->
<param name="ext-rtp-ip" value="$${PRIVATE_IP}"/> <!-- 媒体内网IP -->
<param name="ext-sip-ip" value="$${PRIVATE_IP}"/> <!-- 信令内网IP -->
</profile>
步骤 4:验证变量生效
方法 1:FreeSWITCH CLI 查询
fs_cli -x "global_getvar PUBLIC_IP"
# 预期输出:222.222.222.222
fs_cli -x "global_getvar EXTERNAL_SIP_PORT"
# 预期输出:5060
方法 2:检查配置文件渲染
FreeSWITCH 启动时会将变量替换为实际值,查看日志确认:
grep "Parsing" /usr/local/freeswitch/log/freeswitch.log
# 预期输出类似:
# Parsing [domain] = 222.222.222.222
# Parsing [external_sip_port] = 5060
优势与维护说明
特性 | 说明 |
---|---|
集中管理 | 修改 network_vars.xml 即可全局生效,无需逐文件查找替换。 |
高可读性 | 变量命名清晰(如 PUBLIC_IP ),避免配置歧义。 |
灵活扩展 | 新增网络参数(如 IPv6 支持)只需在 network_vars.xml 添加变量,无需改动业务逻辑。 |
版本控制友好 | 网络配置与业务逻辑分离,便于 Git 等工具管理。 |
扩展:动态加载变量(可选)
若需通过数据库或 API 动态更新变量,可结合 mod_xml_curl
:
<!-- network_vars.xml 修改为动态拉取 -->
<X-PRE-PROCESS cmd="set" data="PUBLIC_IP=$${curl http://api.yourdomain.com/get_network_config?key=PUBLIC_IP}"/>
最终效果:修改 network_vars.xml
中的变量值后,重启 FreeSWITCH 即可生效,所有配置文件自动同步新值,实现高效运维。
总结
以下是基于历史对话整理的 最终版配置文件,采用 全局变量集中管理 设计,确保内外网配置高效维护。所有网络相关参数均通过 network_vars.xml
定义,修改时只需调整此文件即可全局生效。
1. 全局变量文件 conf/network_vars.xml
<!--
============================================================
全局网络参数配置文件
修改此文件即可同步调整所有相关配置,无需逐文件修改
============================================================
-->
<include>
<!-- 公网参数 -->
<X-PRE-PROCESS cmd="set" data="PUBLIC_IP=222.222.222.222"/> <!-- 【需替换】公网IP -->
<X-PRE-PROCESS cmd="set" data="EXTERNAL_SIP_PORT=5060"/> <!-- 公网SIP端口 -->
<X-PRE-PROCESS cmd="set" data="EXTERNAL_RTP_START=10000"/> <!-- 公网RTP起始端口 -->
<X-PRE-PROCESS cmd="set" data="EXTERNAL_RTP_END=40000"/> <!-- 公网RTP结束端口 -->
<!-- 内网参数 -->
<X-PRE-PROCESS cmd="set" data="PRIVATE_IP=192.168.1.71"/> <!-- 【需替换】内网IP -->
<X-PRE-PROCESS cmd="set" data="INTERNAL_SIP_PORT=5060"/> <!-- 内网SIP端口 -->
<!-- 通用参数 -->
<X-PRE-PROCESS cmd="set" data="SIP_TRANSPORT=udp"/> <!-- SIP传输协议 -->
<X-PRE-PROCESS cmd="set" data="CODECS=OPUS,PCMU,PCMA,G722"/> <!-- 编解码优先级 -->
</include>
2. 主配置文件 conf/vars.xml
<!--
============================================================
核心参数配置文件
通过引用 network_vars.xml 实现变量统一管理
============================================================
-->
<include>
<!-- 引入全局网络变量 -->
<X-PRE-PROCESS cmd="include" data="network_vars.xml"/>
<!-- 基础网络配置 -->
<X-PRE-PROCESS cmd="set" data="domain=$${PUBLIC_IP}"/> <!-- SIP域 (公网IP) -->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=$${PRIVATE_IP}"/> <!-- 本机内网IP -->
<!-- 安全配置 -->
<X-PRE-PROCESS cmd="set" data="default_password=Secure@1234"/> <!-- 【需替换】SIP认证密码 -->
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8"/> <!-- SRTP加密套件 -->
<!-- NAT穿透配置 -->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=$${PUBLIC_IP}"/> <!-- 公网媒体IP -->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=$${PUBLIC_IP}"/> <!-- 公网信令IP -->
<X-PRE-PROCESS cmd="set" data="rtp_start_port=$${EXTERNAL_RTP_START}"/>
<X-PRE-PROCESS cmd="set" data="rtp_end_port=$${EXTERNAL_RTP_END}"/>
<!-- 内外网端口分离 -->
<X-PRE-PROCESS cmd="set" data="external_sip_port=$${EXTERNAL_SIP_PORT}"/> <!-- 公网监听端口 -->
<X-PRE-PROCESS cmd="set" data="internal_sip_port=$${INTERNAL_SIP_PORT}"/> <!-- 内网监听端口 -->
<!-- 编解码与国际化 -->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=$${CODECS}"/> <!-- 全局编解码优先级 -->
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=$${CODECS}"/>
<X-PRE-PROCESS cmd="set" data="default_country=CN"/> <!-- 默认国家代码 -->
</include>
3. 公网 SIP Profile conf/sip_profiles/external.xml
<!--
============================================================
公网SIP Profile配置
处理来自公网的话务商B/A的请求,严格NAT穿透策略
============================================================
-->
<profile name="external">
<!-- 基础绑定 -->
<param name="name" value="external"/>
<param name="sip-ip" value="$${PRIVATE_IP}"/> <!-- 绑定内网IP -->
<param name="sip-port" value="$${EXTERNAL_SIP_PORT}"/> <!-- 映射公网端口 -->
<!-- NAT穿透强化 -->
<param name="ext-rtp-ip" value="$${PUBLIC_IP}"/> <!-- 强制SDP公网IP -->
<param name="ext-sip-ip" value="$${PUBLIC_IP}"/>
<param name="sip-force-contact" value="$${PUBLIC_IP}:$${EXTERNAL_SIP_PORT}"/> <!-- Contact头重写 -->
<!-- 安全与性能 -->
<param name="NDLB-force-rport" value="true"/> <!-- 强制使用NAT映射端口 -->
<param name="aggressive-nat-detection" value="true"/> <!-- 激进NAT检测模式 -->
<param name="inbound-bypass-media" value="true"/> <!-- 媒体流直连 -->
</profile>
4. 内网 SIP Profile conf/sip_profiles/internal.xml
<!--
============================================================
内网SIP Profile配置
处理内网设备通信,禁用NAT逻辑,低延迟直连
============================================================
-->
<profile name="internal">
<!-- 基础绑定 -->
<param name="name" value="internal"/>
<param name="sip-ip" value="$${PRIVATE_IP}"/> <!-- 内网IP -->
<param name="sip-port" value="$${INTERNAL_SIP_PORT}"/> <!-- 内网端口 -->
<!-- 内网优化 -->
<param name="ext-rtp-ip" value="$${PRIVATE_IP}"/> <!-- 内网媒体IP -->
<param name="ext-sip-ip" value="$${PRIVATE_IP}"/>
<param name="disable-nat" value="true"/> <!-- 禁用NAT处理 -->
<!-- 注册与认证 -->
<param name="accept-blind-reg" value="true"/> <!-- 允许无注册请求 -->
<param name="force-register-domain" value="$${PRIVATE_IP}"/> <!-- 内网注册域 -->
</profile>
5. 拨号计划 conf/dialplan/default.xml
<!--
============================================================
拨号计划配置
实现主叫/被叫验证及内外网路由分离
============================================================
-->
<context name="default">
<!-- 主叫号码验证 (历史需求) -->
<extension name="Validate_CallerID">
<condition field="caller_id_number" expression="^(?!\+?861[3-9]\d{9}$).*$">
<action application="respond" data="618 Invalid Caller ID"/>
</condition>
</extension>
<!-- 被叫前缀验证 (历史需求) -->
<extension name="Validate_CalledPrefix">
<condition field="destination_number" expression="^(?!(\+?86|00)).*$">
<action application="respond" data="619 Invalid Prefix"/>
</condition>
</extension>
<!-- 内外网路由分离 -->
<extension name="Route_Internal">
<condition field="network_addr" expression="^$${PRIVATE_IP}(:\d+)?$"> <!-- 内网IP匹配 -->
<action application="bridge" data="sofia/internal/${destination_number}@$${PRIVATE_IP}:$${INTERNAL_SIP_PORT}"/>
</condition>
</extension>
<extension name="Route_External">
<condition field="destination_number" expression="^.*$"> <!-- 默认路由至公网A -->
<action application="bridge" data="sofia/external/${destination_number}@192.168.1.67:5060"/> <!-- 历史对话中的话务商A -->
</condition>
</extension>
</context>
替换字段说明
变量名 | 示例值 | 作用文件 | 说明 |
---|---|---|---|
$${PUBLIC_IP} | 222.222.222.222 | 所有文件 | 公网IP,需替换为实际值 |
$${PRIVATE_IP} | 192.168.1.71 | 所有文件 | 内网IP,需替换为服务器实际IP |
$${EXTERNAL_SIP_PORT} | 5060 | vars.xml, external.xml | 公网SIP端口,与路由器映射一致 |
$${INTERNAL_SIP_PORT} | 5060 | vars.xml, internal.xml | 内网SIP端口,通常与公网端口分离以避免冲突 |
配置验证步骤
-
替换全局变量
修改network_vars.xml
中的PUBLIC_IP
和PRIVATE_IP
为实际值。 -
重启 FreeSWITCH
/usr/local/freeswitch/bin/freeswitch -stop /usr/local/freeswitch/bin/freeswitch -nc
-
检查变量加载
fs_cli -x "global_getvar PUBLIC_IP" # 应输出 222.222.222.222 fs_cli -x "sofia status" # 确认 external/internal Profile 状态为 RUNNING
-
测试内外网呼叫
- 内网测试:使用 IP 话机呼叫
1001
,验证媒体流直连且 SIP 头域无公网 IP。 - 公网测试:通过公网 IP 发起呼叫,抓包确认 SDP 中的
c=IN IP4 222.222.222.222
。
- 内网测试:使用 IP 话机呼叫
此配置集历史对话需求于一体,兼顾 安全性、可维护性 和 业务功能性,可直接部署于生产环境。