使用公网FRPS代理服务器实现远端WEBRTC-SIP终端和内网FreeSWITCH通信,详细部署和技术挑战讨论

作者:james.zhu
来源:SIP实验室
原文:https://mp.weixin.qq.com/s/EmMxO7KjQ7tR80_iGNUvmQ

马孔多的老乞丐对猴子说,家,房子需要一个入户们,单元们,另外还要一个小区大门。这是为了安全。IPPBX也是一样。很多公网环境的使用要求越来越多,服务器端为了实现拓扑隐藏,需要投入更多的额外的成本。WebRTC可以和开源FreeSWITCH实现无缝的集成。

很多时候,WebRTC终端可能部署在异地和外网环境中。WebRTC外网注册和实现和内部SIP之间的通信就需要代理服务器或者SBC来实现转发扩展。如果用户不能使用SBC的话,可以考虑通过FRPS/FRPC方式实现和内网FreeSWITCH的信令转发处理,然后利用STUN实现媒体的转发处理。当然,用户为了支持以上的环境需求,需要部署多台服务器,并且确保这些转发代理服务器具有公网地址,通过公网转发实现和内网FreeSWITCH的音视频通信。部署了多台公网的服务器,用户需要关注更多的其他风险,例如安全问题,维护问题和扩展等问题。我们根据以上的这些挑战和大家分享关于使用FRPS实现的WEBRTC终端和内网FreeSWITCH的交互。

1. 概述

随着远程办公和分布式通信需求的增长,企业越来越需要构建能够支持外部WebRTC终端接入内部通信系统的解决方案。本文详细阐述了一种基于FreeSWITCH的完整解决方案,通过FRPS作为SIP信令代理服务器和STUN负责媒体转发,使外网的WebRTC终端能够安全、高效地注册到内网的FreeSWITCH服务器。

该解决方案充分考虑了网络安全、NAT穿透、会话管理和媒体传输等关键因素,为构建企业级VoIP系统提供了可靠的技术框架。本文将从系统架构、详细配置、安全性、扩展性以及维护挑战等多个维度进行深入探讨。

2. 系统架构

2.1 部署场景图例

                 互联网                          |               企业内网
                                                |
 +-------------+                                |
 | WebRTC      |                                |
 | 终端用户    |                                |
 +------+------+                                |
        |                                       |
        v                                       |
 +------+------+     +---------------+          |    +-------------+     +--------------+
 | STUN 服务器 +---->+ FRPS 代理服务器 +------------->+ FRPC 客户端 +---->+ FreeSWITCH   |
 +-------------+     +---------------+          |    +-------------+     +--------------+
        ^                    ^                  |            ^                  ^
        |                    |                  |            |                  |
 +------+------+     +------+------+           |    +-------+-------+   +------+-------+
 | WebRTC      |     | SIP 信令流  |           |    | 媒体流转发    |   | 数据库/认证  |
 | 信令/媒体流 |     |             |           |    |               |   |              |
 +-------------+     +-------------+           |    +---------------+   +--------------+

2.2 组件介绍

2.2.1 FreeSWITCH

FreeSWITCH是一个开源的通信平台,支持多种协议如SIP、WebRTC等,能够处理语音、视频和文本通信。在我们的架构中,FreeSWITCH部署在企业内网,负责处理所有的呼叫控制和媒体流处理。

2.2.2 FRPS/FRPC

FRPS (Fast Reverse Proxy Server) 是一个高性能的反向代理服务器,部署在公网上,用于将外部请求安全地转发到内网。FRPC是其客户端组件,部署在内网中,与FRPS建立持久连接。

2.2.3 STUN服务器

STUN (Session Traversal Utilities for NAT) 服务器帮助WebRTC客户端发现其公网IP地址和端口,解决NAT穿透问题,确保媒体流能够正确传输。

2.2.4 WebRTC终端

WebRTC终端是基于浏览器或专用应用的客户端,支持实时音视频通信,通过SIP协议注册到FreeSWITCH服务器。

3. 详细配置

3.1 FreeSWITCH配置

3.1.1 安装与基础配置

首先确保FreeSWITCH已正确安装并启用了必要的模块:

# 安装FreeSWITCH及相关模块
apt-get install freeswitch freeswitch-mod-sofia freeswitch-mod-verto freeswitch-mod-opus freeswitch-mod-vpx

# 确保mod_sofia和mod_verto已加载
fs_cli -x "load mod_sofia"
fs_cli -x "load mod_verto"

3.1.2 SIP配置

修改/etc/freeswitch/sip_profiles/external.xml文件,确保WebRTC支持:

<profile name="external">
  <settings>
    <param name="sip-port" value="5060"/>
    <param name="tls-port" value="5061"/>
    <param name="wss-binding" value=":7443"/>
    <param name="ws-binding" value=":7080"/>
    
    <!-- WebRTC 支持 -->
    <param name="liberal-dtmf" value="true"/>
    <param name="rtp-timeout-sec" value="300"/>
    <param name="rtp-hold-timeout-sec" value="1800"/>
    <param name="enable-timer" value="false"/>
    <param name="dtmf-duration" value="2000"/>
    <param name="dtmf-type" value="rfc2833"/>
    <param name="auto-rtp-bugs" value="clear"/>
    <param name="inbound-codec-prefs" value="OPUS,VP8,H264,G722,PCMU,PCMA"/>
    <param name="outbound-codec-prefs" value="OPUS,VP8,H264,G722,PCMU,PCMA"/>
    
    <!-- TLS 配置 -->
    <param name="tls" value="true"/>
    <param name="tls-only" value="false"/>
    <param name="tls-cert-dir" value="/etc/freeswitch/tls"/>
    <param name="tls-version" value="tlsv1.2"/>
</settings>
</profile>

3.1.3 WebRTC配置

创建或修改/etc/freeswitch/autoload_configs/verto.conf.xml

<configuration name="verto.conf" description="Verto Endpoint">
  <settings>
    <param name="debug" value="0"/>
    <param name="enable-binding-local" value="false"/>
    <param name="enable-binding-remote" value="false"/>
    <param name="userauth-no-params" value="false"/>
    <param name="root-password" value="securerootpassword"/>
    <param name="max-wire-size" value="65536"/>
    <param name="write-queue-size" value="0"/>
    <param name="attach-timeout" value="120"/>
</settings>

<profiles>
    <profile name="default">
      <param name="bind-local" value="0.0.0.0:8081"/>
      <param name="bind-local-secure" value="0.0.0.0:8082"/>
      <param name="force-register-domain" value="$${domain}"/>
      <param name="secure-combined" value="/etc/freeswitch/tls/wss.pem"/>
      <param name="inbound-codec-string" value="opus,vp8,h264,vp9"/>
      <param name="outbound-codec-string" value="opus,vp8,h264,vp9"/>
      <param name="rtp-ip" value="$${local_ip_v4}"/>
      <param name="ext-rtp-ip" value="auto-nat"/>
      <param name="local-network" value="192.168.0.0/16"/>
      <param name="outbound-codec-string" value="opus,vp8,h264"/>
      <param name="apply-candidate-acl" value="wan.auto"/>
      <param name="apply-candidate-acl" value="lan.auto"/>
    </profile>
</profiles>
</configuration>

3.1.4 TLS证书配置

WebRTC要求使用安全连接,需配置SSL证书:

# 生成自签名证书
mkdir -p /etc/freeswitch/tls
cd /etc/freeswitch/tls
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout wss.key -out wss.crt
cat wss.key wss.crt > wss.pem
chmod 600 wss.*

# 更新FreeSWITCH配置使用新证书
fs_cli -x "sofia profile external restart"
fs_cli -x "reload mod_verto"

3.2 FRPS代理服务器配置

3.2.1 安装FRPS

在公网服务器上安装FRPS:

# 下载FRPS
wget https://github.com/fatedier/frp/releases/download/v0.41.0/frp_0.41.0_linux_amd64.tar.gz
tar -zxvf frp_0.41.0_linux_amd64.tar.gz
cd frp_0.41.0_linux_amd64

# 配置FRPS
cp frps.ini /etc/frps.ini

# 创建systemd服务
cat > /etc/systemd/system/frps.service << EOF
[Unit]
Description=FRP Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frps.ini
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

# 安装frps
cp frps /usr/local/bin/
chmod +x /usr/local/bin/frps

# 启动服务
systemctl daemon-reload
systemctl enable frps
systemctl start frps

3.2.2 FRPS配置文件

编辑/etc/frps.ini

[common]
bind_addr = 0.0.0.0
bind_port = 7000
vhost_http_port = 80
vhost_https_port = 443

# SIP (UDP) 代理配置
bind_udp_port = 7001

# 控制台配置
dashboard_addr = 0.0.0.0
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = strongpassword

# 授权验证
authentication_method = token
token = your_auth_token_here

# 日志设置
log_file = /var/log/frps.log
log_level = info
log_max_days = 3

# 允许类型
allow_ports = 5060-5070,8000-9000,16384-32768

3.3 STUN服务器配置

3.3.1 安装STUN服务器

在公网服务器上安装STUN服务器:

# 安装STUN服务器
apt-get install coturn

# 配置turnserver
cat > /etc/turnserver.conf << EOF
listening-port=3478
listening-ip=YOUR_PUBLIC_IP
external-ip=YOUR_PUBLIC_IP
realm=yourdomain.com
fingerprint
no-tls
no-dtls
min-port=16384
max-port=32768
log-file=/var/log/turn.log
EOF

# 启动服务
systemctl enable coturn
systemctl start coturn

3.3.2 FreeSWITCH中配置ICE/STUN

修改/etc/freeswitch/sip_profiles/external.xml以支持STUN:

<param name="ext-rtp-ip" value="YOUR_PUBLIC_IP"/>
<param name="ext-sip-ip" value="YOUR_PUBLIC_IP"/>
<param name="stun-enabled" value="true"/>
<param name="stun-auto-disable" value="false"/>
<param name="rtcp-audio-interval-msec" value="5000"/>
<param name="rtcp-video-interval-msec" value="3000"/>
<param name="force-register-domain" value="YOUR_PUBLIC_IP"/>
<param name="force-subscription-domain" value="YOUR_PUBLIC_IP"/>
<param name="force-register-db-domain" value="YOUR_PUBLIC_IP"/>

3.4 WebRTC客户端配置

3.4.1 JavaScript示例代码

以下是基于SIP.js的WebRTC客户端示例代码:

// 引入SIP.js库
const domain = 'your_domain.com';
const wsServer = `wss://${domain}:7443`;

// 配置SIP UA
const configuration = {
uri: `sip:extension@${domain}`,
authorizationUser: 'extension',
password: 'password',
transportOptions: {
    wsServers: [wsServer],
    traceSip: true
  },
stunServers: ['stun:stun.yourdomain.com:3478'],
turnServers: [
    {
      urls: 'turn:turn.yourdomain.com:3478',
      username: 'turnuser',
      password: 'turnpassword'
    }
  ],
sessionDescriptionHandlerFactoryOptions: {
    peerConnectionOptions: {
      rtcConfiguration: {
        iceServers: [
          { urls: 'stun:stun.yourdomain.com:3478' },
          {
            urls: 'turn:turn.yourdomain.com:3478',
            username: 'turnuser',
            credential: 'turnpassword'
          }
        ]
      }
    }
  }
};

// 创建UA实例
const ua = newSIP.UA(configuration);

// 注册事件
ua.on('registered', () => {
console.log('Successfully registered');
});

ua.on('registrationFailed', (response, cause) => {
console.error('Registration failed', cause);
});

// 启动UA
ua.start();

3.4.2 HTML页面示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>WebRTC SIP客户端</title>
<script src="https://cdn.jsdelivr.net/npm/sip.js@0.20.0/dist/sip.min.js"></script>
</head>
<body>
<h1>WebRTC SIP客户端</h1>

<div id="login">
    <input type="text" id="username" placeholder="用户名">
    <input type="password" id="password" placeholder="密码">
    <button id="register">注册</button>
</div>

<div id="call-controls" style="display:none;">
    <input type="text" id="target" placeholder="呼叫目标">
    <button id="call">呼叫</button>
    <button id="hangup">挂断</button>
</div>

<div id="media">
    <audio id="remoteAudio" autoplay></audio>
    <video id="remoteVideo" autoplay></video>
    <video id="localVideo" muted autoplay></video>
</div>

<script src="app.js"></script>
</body>
</html>

4. 网络穿透与媒体流传输

WebRTC媒体流的传输是该解决方案的核心挑战之一。在我们的架构中,通过以下方式确保媒体流的高效传输:

  1. 1. ICE框架:利用ICE(Interactive Connectivity Establishment)框架进行NAT穿透,先尝试直连,再通过STUN服务器,最后通过TURN中继
  2. 2. STUN服务器:帮助WebRTC终端发现自己的公网IP和端口
  3. 3. 媒体优化
    • • 配置适当的编解码器优先级(OPUS音频、VP8/H.264视频)
    • • 启用RTCP反馈,优化媒体质量
    • • 合理设置抖动缓冲区,平衡延迟和音质

FreeSWITCH的媒体处理配置示例:

<param name="rtp-timeout-sec" value="30"/>
<param name="rtp-hold-timeout-sec" value="180"/>
<param name="media-option" value="resume-media-on-hold"/>
<param name="media-option" value="bypass-media-after-att-xfer"/>
<param name="jitterbuffer-msec" value="60"/>
<param name="rtp-timer-name" value="soft"/>

5. 安全性考量

在构建此类跨网络的通信系统时,安全性至关重要:

5.1 传输层安全

• 所有信令使用WSS(WebSocket Secure)和TLS确保加密传输

• 媒体流使用SRTP(Secure Real-time Transport Protocol)加密

• 证书管理与更新机制,防止证书过期导致服务中断

5.2 认证与授权

• 强密码策略与定期轮换

• 实施IP限制和访问控制列表

• 考虑双因素认证(2FA)

• 基于角色的访问控制(RBAC)

5.3 防护措施

FreeSWITCH安全配置:

<!-- 防SIP扫描攻击 -->
<param name="challenge-realm" value="auto_from"/>
<param name="apply-inbound-acl" value="trusted"/>
<param name="apply-register-acl" value="domains"/>
<param name="auth-calls" value="true"/>
<param name="auth-all-packets" value="false"/>
<param name="log-auth-failures" value="true"/>
<param name="drop-non-matching-registration" value="true"/>

<!-- 限制注册尝试频率 -->
<param name="max-registrations-per-extension" value="3"/>
<param name="accept-blind-reg" value="false"/>
<param name="accept-blind-auth" value="false"/>
<param name="multiple-registrations" value="false"/>

5.4 FRPS安全加固

# 强身份验证
authentication_method = token
token = complex_random_token_string

# 限制允许的端口范围
allow_ports = 5060-5070,8000-9000,16384-32768

# 启用日志审计
detailed_logs = true

# TLS加密
tls_only = true
tls_cert_file = /path/to/server.crt
tls_key_file = /path/to/server.key

6. 扩展性与未来规划

6.1 水平扩展

• FreeSWITCH集群:使用共享数据库实现会话状态同步

• 负载均衡:多FRPS实例+DNS轮询或专用负载均衡器

• 媒体服务器分离:考虑使用专用媒体服务器如Janus或MediaSoup处理大量媒体流

6.2 功能扩展

• WebRTC录制:结合FreeSWITCH的录制功能实现通话录制

• 实时转码:按需转换不同终端使用的编解码器

• 会议系统集成:可扩展为多方视频会议系统

• WebRTC<->SIP网关:实现与传统SIP终端互通

6.3 监控与分析

• 实施Prometheus+Grafana监控系统

• 开发自定义指标采集器,监控关键性能指标

• 通话质量监控(MOS评分、抖动、丢包率等)

7. 技术挑战与维护

7.1 常见问题与解决方案

问题描述可能原因解决方案
WebRTC注册失败TLS证书问题检查证书有效性和信任链
单向音频NAT穿透失败调整ICE配置,确保STUN服务可用
媒体质量差网络抖动或丢包调整抖动缓冲区,启用前向纠错
FRPS连接断开网络不稳定增加心跳频率,实现自动重连
高CPU使用率转码负担重统一编解码标准,或增加服务器资源

7.2 日常维护任务

• 日志分析:定期审查FreeSWITCH和FRPS日志

• 性能监控:实时监控系统资源使用情况

• 安全更新:及时应用系统和组件安全补丁

• 容量规划:根据使用模式预测资源需求

• 备份策略:定期备份配置和关键数据

7.3 升级策略

• 建立测试环境,先在测试环境验证升级

• 实施蓝绿部署模式,降低升级风险

• 制定详细的回滚计划,应对升级失败情况

• 采用配置管理工具(如Ansible)自动化部署过程

8. 结论

本文详细阐述了外网WebRTC终端通过SIP信令、FRPS代理和STUN媒体转发注册到内网FreeSWITCH的完整解决方案。这一架构充分考虑了安全性、可扩展性和维护性,为企业通信系统提供了强大的技术支持。

通过合理配置FreeSWITCH、FRPS和STUN服务器,企业可以构建一个安全、高效、可靠的WebRTC通信平台,满足远程办公和跨网络通信的需求。随着WebRTC技术的不断发展,该解决方案还可以进一步扩展,支持更多高级功能和更大规模的部署。

9. 参考资料

1. FreeSWITCH官方文档: https://freeswitch.org/confluence/

2. FRP项目文档: https://github.com/fatedier/frp

3. WebRTC官方文档: https://webrtc.org/getting-started/overview

4. SIP.js文档: https://sipjs.com/api/0.20.0/

5. RFC 5389: STUN协议规范: https://tools.ietf.org/html/rfc5389

6. RFC 5766: TURN协议规范: https://tools.ietf.org/html/rfc5766

7. RFC 8445: ICE协议规范: https://tools.ietf.org/html/rfc8445

8. Anthony Minessale II, “FreeSWITCH Cookbook”, Packt Publishing, 2012

9. Michael S. Collins, “FreeSWITCH 1.8”, Packt Publishing, 2017

10. Alan B. Johnston, “WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web”, Digital Codex LLC, 2013

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论