
简介本资源是一份面向企业通信架构师、云网络工程师及系统集成商的官方级培训材料聚焦Microsoft Teams Direct Routing与Azure托管SBCSession Border Controller的端到端部署实践解决PSTN语音接入、多租户中继配置、转码许可等关键集成难题。文件为单个5.63MB的PPTX课件内容结构完整涵盖作者背景、前置条件清单Office 365租户、Azure订阅、AudioCodes Mediant CE设备及CA证书、Azure资源逐项配置流程资源组、VNet、NSG、存储账户上传VHD、VM镜像部署、AudioCodes设备双模型企业/托管中继配置要点、SILK载荷调优与转码许可计算规则以及Office 365租户配对、用户启用与语音路由验证等实操模块。已有92人学习下载内容由NBConsult高级解决方案架构师Warren du Toit主笔兼具技术深度与工程落地性特别提供Syslog日志分析、INI配置备份等排错提示是实施Teams语音直连方案不可多得的权威参考。1. Microsoft Teams Direct Routing Azure 托管 SBC不是“配个IP就能打通电话”的玄学而是要亲手把 AudioCodes CE VHD 拆开、重签名、调性能、压 License 的硬核工程你手头刚拿到一份叫Microsoft Teams Direct Routing with SBC hosted in Azure.pptx的培训材料——别急着点开幻灯片。它表面是 PPT内里是一套完整可落地的Azure 上部署 AudioCodes Mediant CE 作为 Teams Direct Routing 边界控制器的实战路径图。这不是概念宣讲而是 Warren du ToitNBConsult 高级云网络架构师在 Ignite 会场实操后反向整理的血泪笔记从 Office 365 租户配 License 开始到 Azure 虚拟机跑起 AudioCodes CE 镜像再到config.ini里改 SILK payload、调performance_profile、算清「50 张 SBC 许可 ≠ 50 路并发」的 License 坑——每一步都卡在真实生产环境的边界上。适合两类人一是正被客户逼着两周内上线 Teams 语音直连 PSTN 的系统集成商工程师二是想把 Azure 网络能力从 IaaS 深耕到 VoIP 层的云架构师。如果你以为这只是“在 Azure 里装个 SBC 虚拟机”那等你第一次看到SIP 403 Forbidden: Invalid certificate chain或Media path failed: no codec match时就会明白为什么这份材料被标注为「官方优质资源」——它不教你怎么截图只告诉你哪一行 INI 配错了会导致整条中继静音。2. Azure 基础设施层不是建完 VM 就完事VHD 上传、镜像生成、NSG 规则必须按 VoIP 流量特征定制2.1 创建 Resource Group 与 Virtual Network命名规则决定后续排错效率Azure 资源组Resource Group不是容器是权限和生命周期管理单元。我们不建议用teams-sbc-rg这类泛称而应采用rg-teams-dr-prod-westeurope-01格式rg-业务域-环境-区域-序号。原因很实际——当客户有多个 Direct Routing 实例时PowerShell 脚本批量查日志或删资源时靠-like *dr*会误杀测试环境。Virtual Network 同理地址空间必须避开 Teams 客户端默认使用的192.168.0.0/16和10.0.0.0/8Teams 客户端可能在本地 NAT 后使用这些网段推荐用172.28.0.0/16子网划分至少预留/26给 SBC VMAudioCodes CE 最小要求 4 vCPU / 16GB RAM需足够 IP。关键点VNet 必须启用Enable DNS forwarding否则 AudioCodes 设备无法解析teams.microsoft.com和sipfed.online.lync.com的 SRV 记录——这是后续 SIP 中继注册失败的隐形杀手。az group create --name rg-teams-dr-prod-westeurope-01 --location westeurope az network vnet create \ --resource-group rg-teams-dr-prod-westeurope-01 \ --name vnet-teams-dr-prod \ --address-prefixes 172.28.0.0/16 \ --dns-servers 168.63.129.16 \ --tags PurposeDirectRouting OwnerVoiceTeam提示168.63.129.16是 Azure 平台 DNS 转发器地址非此地址会导致 AudioCodes CE 的nslookup sipfed.online.lync.com返回NXDOMAIN进而使中继注册卡在REGISTERING状态。2.2 Public IP 与 Network Security GroupVoIP 不是 HTTP端口开放逻辑完全不同Public IP 必须分配给 SBC VM 的 NIC而非 Load Balancer且类型选Static非 Dynamic——Teams Direct Routing 要求 SBC 的公网 IP 在Teams Admin Center Voice Direct Routing SBCs页面中静态填写IP 变更即导致中继断连。NSG 规则常被误配为“放行所有 TCP/UDP”这是翻车高发区。AudioCodes CE 与 Teams 通信实际依赖以下最小端口集方向协议端口用途是否必需InboundUDP5061SIP TLS中继信令✅ 必须InboundUDP10000-20000RTP/RTCP 媒体流Teams 动态分配✅ 必须OutboundTCP/UDPAnySBC 主动连接 Teams 云如证书 OCSP 检查✅ 必须InboundTCP22SSH 管理仅限调试期⚠️ 生产环境应禁用# 创建 NSG 并附加入站规则 az network nsg create --resource-group rg-teams-dr-prod-westeurope-01 --name nsg-sbc-inbound az network nsg rule create \ --resource-group rg-teams-dr-prod-westeurope-01 \ --nsg-name nsg-sbc-inbound \ --name Allow-SIP-TLS \ --priority 100 \ --direction Inbound \ --access Allow \ --protocol Tcp \ --source-port-range * \ --destination-port-range 5061 \ --source-address-prefixes * \ --destination-address-prefixes VirtualNetwork az network nsg rule create \ --resource-group rg-teams-dr-prod-westeurope-01 \ --nsg-name nsg-sbc-inbound \ --name Allow-RTP-Range \ --priority 110 \ --direction Inbound \ --access Allow \ --protocol Udp \ --source-port-range * \ --destination-port-range 10000-20000 \ --source-address-prefixes * \ --destination-address-prefixes VirtualNetwork注意--destination-address-prefixes VirtualNetwork表示该规则只允许流量进入 VNet 内部即 SBC VM而非整个 Azure 区域。这是 VoIP 安全基线——禁止公网直接访问 SBC 的管理界面HTTP/HTTPS 端口。2.3 Storage Account 上传 VHD不是拖进去就完事必须校验 SHA256 且设为 Page BlobAudioCodes 官方提供的.vhd文件如MediantCE-8.2.0-azure.vhd体积通常超 8GB。Azure Storage Account 必须创建为General Purpose v2类型并启用Hierarchical NamespaceADLS Gen2——虽非强制但能加速后续 PowerShell 脚本调用Get-AzStorageBlobContent下载配置文件。关键动作上传前用sha256sum MediantCE-8.2.0-azure.vhd计算校验值上传后通过 Azure Portal 或 CLI 验证 blob 的Content-MD5是否匹配VHD 上传若中断Azure 不会自动重试损坏的 VHD 会导致 VM 创建后蓝屏。# PowerShell 示例上传并验证 $ctx (Get-AzStorageAccount -ResourceGroupName rg-teams-dr-prod-westeurope-01 -Name stteamsdrprod01).Context $localVhdPath C:\downloads\MediantCE-8.2.0-azure.vhd $blobName mediant-ce-8.2.0-azure.vhd # 上传为 Page BlobVHD 必须 $uploadTask Set-AzStorageBlobContent -File $localVhdPath -ContainerName vhds -Blob $blobName -Context $ctx -BlobType PageBlob -StandardBlobTier Premium_LRS -Verbose # 验证 SHA256需提前保存本地校验值 $expectedSha a1b2c3d4e5f6... # 替换为实际值 $uploadedBlob Get-AzStorageBlob -Container vhds -Blob $blobName -Context $ctx $actualSha $uploadedBlob.ICloudBlob.Properties.ContentMD5 if ($expectedSha -ne $actualSha) { throw VHD upload corrupted! Expected SHA256: $expectedSha, got: $actualSha }提示-StandardBlobTier Premium_LRS是必须项。AudioCodes CE 对磁盘 IOPS 敏感标准 LRS 存储的随机读写延迟10ms会导致媒体包乱序表现为通话单通或断续。Premium LRS 提供稳定 5000 IOPS满足 CE 设备最低要求。3. AudioCodes Mediant CE 部署与初始化从 VHD 到可 ping 通的 VM中间隔着三个必须手动干预的环节3.1 创建 VM Image不能直接用 VHD 创建 VM必须先转为托管镜像Azure 不允许直接从上传的 VHD 启动 VM除非用az vm create --use-unmanaged-disk但 AudioCodes CE 不支持非托管磁盘。正确路径是VHD → 托管镜像 → VM。这步常被跳过导致 VM 启动后网卡无 IP 或eth0未激活。原因在于 AudioCodes CE VHD 内置的 Linux initrd 依赖 Azure 特定的walinuxagent和udev规则只有通过az image create注册为镜像Azure 才会在 VM 启动时注入正确的 cloud-init 配置。az image create \ --resource-group rg-teams-dr-prod-westeurope-01 \ --name img-audiocodes-ce-820 \ --source https://stteamsdrprod01.blob.core.windows.net/vhds/mediant-ce-8.2.0-azure.vhd \ --os-type linux \ --hyper-v-generation V2 \ --storage-sku Premium_LRS注意--hyper-v-generation V2是强制项。AudioCodes CE 8.x 仅支持 Gen2 VMUEFI 启动若用 Gen1VM 会卡在 BIOS 初始化阶段串口日志显示No bootable device。3.2 部署 VM 并配置 NIC必须绑定 Public IP 且禁用 Accelerated NetworkingVM 规格选择Standard_D4s_v34 vCPU / 16GB RAM是 AudioCodes CE 8.2 的官方最低要求。但关键在 NIC 配置Public IP 必须绑定到 NIC而非 VM 本身且必须关闭Accelerated Networking——这是绝大多数初学者踩坑的根源。AudioCodes CE 的内核驱动acp模块与 Azure 的 SR-IOV 硬件卸载不兼容开启后会导致eth0收不到任何 SIP 包Wireshark 抓包显示no packets received。az vm create \ --resource-group rg-teams-dr-prod-westeurope-01 \ --name vm-sbc-prod-01 \ --image img-audiocodes-ce-820 \ --size Standard_D4s_v3 \ --admin-username audiocodes \ --generate-ssh-keys \ --vnet-name vnet-teams-dr-prod \ --subnet default \ --public-ip-address pip-sbc-prod-01 \ --nsg nsg-sbc-inbound \ --os-disk-size-gb 128 \ --tags SBCVersion8.2.0 DeploymentDirectRouting # 关闭 Accelerated Networking必须 az network nic update \ --resource-group rg-teams-dr-prod-westeurope-01 \ --name vm-sbc-prod-01VMNic \ --accelerated-networking false3.3 首次登录与基础网络验证用audiocodes账户而非 rootAudioCodes CE 默认禁用 root SSH 登录必须用预置账户audiocodes密码在文档中提供首次登录后强制修改。登录后第一件事不是配 SIP而是验证三层连通性# 检查网卡状态必须 UP 且有 IPv4 地址 ip addr show eth0 | grep inet # 测试到 Teams 云的连通性关键 ping -c 3 sipfed.online.lync.com # 应返回 IP 且无丢包 telnet sipfed.online.lync.com 5061 # 应显示 Connected证明 TLS 握手可达 # 检查 DNS 解析必须返回 SRV 记录 nslookup -typeSRV _sipfederationtls._tcp.teams.microsoft.com # 正确响应示例sipfed.online.lync.com service 10 100 5061 sipfed.online.lync.com.提示若nslookup返回*** Cant find _sipfederationtls._tcp.teams.microsoft.com: Non-existent domain说明 VNet DNS 设置错误见 2.1 节此时 SIP 中继永远无法注册。4. AudioCodes CE 配置核心config.ini里改 7 行决定中继是“通”还是“哑”4.1 License 激活不是上传 lic 文件就生效必须重启acp服务AudioCodes CE 的 License 文件.lic需上传至/usr/local/audiocodes/license/目录但仅上传不触发激活。必须执行sudo systemctl restart acp sudo systemctl status acp | grep Active: # 应显示 active (running)验证 License 是否生效sudo /usr/local/audiocodes/bin/acp_license_info # 输出中必须包含 # Concurrency: 50 # Transcoding: 25 ← 注意Transcoding 并发数 Concurrency / 2注意License 文件名必须为license.lic固定名且权限为600。若命名为mylicense.licacp_license_info会显示No license found。4.2 SIP Trunk 配置企业模型 vs 托管模型trunk_type决定路由逻辑AudioCodes CE 支持两种 Direct Routing 模式由trunk_type参数控制参数企业模型Enterprise托管模型Hostingtrunk_typeenterprisehosting适用场景单一租户PBX 直连 TeamsMSP 托管多租户每个租户独立中继SIP URI 格式usercontoso.comusercontoso.com;transporttls需加 transport 参数路由策略由 Teams Admin Center 的 Voice Routing Policy 控制由 AudioCodes CE 的route_pattern规则控制配置片段/usr/local/audiocodes/config/config.ini[trunk_1] name Teams-Trunk-01 trunk_type enterprise signaling_ip 172.28.1.10 signaling_port 5061 transport tls domain contoso.com ; 企业模型下Teams 会自动发送 REGISTER 到此 IP:Port[trunk_2] name PSTN-Trunk-01 trunk_type pstn signaling_ip 192.168.100.50 ; 你的本地 PBX IP signaling_port 5060 transport udp4.3 媒体参数调优SILK Payload 修改是解决“单通”的后悔药Teams 默认使用 SILK 编解码器窄带 8kHz / 宽带 16kHz。若 AudioCodes CE 未显式声明支持媒体协商会 fallback 到 G.711但 Teams 客户端可能拒绝 G.711尤其移动 App。必须在config.ini的[media]区块中强制声明[media] codec_priority_list silknb,silkwb,g711a,g711u silk_nb_payload_type 103 silk_wb_payload_type 104 ; Teams 使用 payload type 103/104若此处不匹配Wireshark 显示 RTP: Unknown payload type提示修改后必须执行sudo /usr/local/audiocodes/bin/acp_reload_config重载配置不能 reboot——reboot 会丢失所有 runtime 状态中继需重新注册耗时 2-3 分钟。5. 避坑AudioCodes CE Teams Direct Routing 的五个血泪现场5.1 现象SBC 在 Teams Admin Center 显示 “Registered”但用户拨号无响应原因config.ini中trunk_1的signaling_ip填写了私网 IP如10.0.0.10而 Teams 云只能访问 SBC 的公网 IP。Teams 发送 SIP INVITE 到私网 IP自然超时。解决signaling_ip必须填 SBC 的公网 IP即pip-sbc-prod-01的 IP并在 AudioCodes CE 的network配置中将该公网 IP 绑定到eth0的 secondary address主 IP 仍为 VNet 内网 IP。5.2 现象通话建立后 30 秒自动挂断日志显示BYE reasonTimeout原因Azure NSG 缺少对Outbound方向的Keep-Alive流量放行。Teams 云每 25 秒发送 SIP OPTIONS 包探测中继存活若 NSG 拦截SBC 认为链路中断。解决在 NSG 中添加出站规则允许Any协议到Internet优先级低于入站规则如 200。5.3 现象启用 Transcoding 后并发数暴跌License 显示Used: 50/25原因Transcoding 按 call leg 计费一个双向通话消耗 2 个 transcoding license上行 下行。50 张 Transcoding License 仅支持 25 路并发。解决在config.ini中关闭不必要的 transcodingtranscoding_enabled false或升级 License。5.4 现象audiocodes INI Edit工具无法连接浏览器提示ERR_CONNECTION_REFUSED原因AudioCodes CE 的 Web 管理界面默认绑定到127.0.0.1:80未监听0.0.0.0。解决SSH 登录后执行sudo /usr/local/audiocodes/bin/acp_webserver_config --bind 0.0.0.0:80再sudo systemctl restart acp_webserver。5.5 现象Teams 用户拨打 PSTN 号码对方听到忙音SBC 日志无 SIP 消息原因Office 365 租户未启用Enterprise Voice或用户未分配Phone SystemLicense。解决PowerShell 执行Set-CsUser -Identity usercontoso.com -EnterpriseVoiceEnabled $true -HostedVoiceMail $true # 并确认 License 已分配Get-MsolUser -UserPrincipalName usercontoso.com | fl Licenses6. 进阶验证用sipcmd模拟 Teams 云注册把黑匣子变成透明管道6.1 构建最小化 SIP 注册验证脚本与其等 Teams Admin Center 的“绿色 Registered”图标不如用开源工具sipcmd主动模拟 Teams 云的注册行为。这能绕过 Teams 后端缓存5 秒内定位信令层问题。# 在任意 Linux 机器非 SBC安装 sipcmd wget https://github.com/asipto/sipcmd/releases/download/v1.2.0/sipcmd-1.2.0-linux-x86_64.tar.gz tar -xzf sipcmd-1.2.0-linux-x86_64.tar.gz cd sipcmd-1.2.0-linux-x86_64 # 执行注册测试替换 YOUR_SBC_PUBLIC_IP ./sipcmd -u testusercontoso.com \ -w contoso.com \ -h YOUR_SBC_PUBLIC_IP \ -p 5061 \ -t tls \ -x reg 3600 \ -v预期成功输出INFO: Sending REGISTER to YOUR_SBC_PUBLIC_IP:5061 INFO: Received 200 OK for REGISTER INFO: Registration successful, expires in 3600 seconds若失败-v参数会打印完整 SIP 消息可直接比对401 Unauthorized→ SBC 证书未被 Teams 信任检查 CA 证书是否上传且cert_name配置正确403 Forbidden→config.ini中domain与 Teams 租户域名不匹配Timeout→ NSG 阻断 UDP 5061 或 SBC 未监听该端口netstat -tuln | grep 50616.2 媒体路径抓包Wireshark 过滤规则表当通话单通时SIP 信令正常但 RTP 不通必须抓包。在 SBC VM 上执行sudo tcpdump -i eth0 -w /tmp/sbc-media.pcap port 10000-20000 and udp # 生成 pcap 后下载到本地用 Wireshark 分析常用 Wireshark 过滤表达式场景过滤表达式说明查看所有 RTP 流rtp确认是否有 RTP 包发出查看 Teams 客户端发来的 RTPip.addr 52.114.132.100 rtpTeams 云媒体服务器 IP 段需查最新查看 SBC 回传的 RTPip.addr 172.28.1.10 rtpSBC 内网 IP检查编解码协商sip sip.Method INVITE查看 SDP 中maudio行的 codec提示Teams 云媒体服务器 IP 不固定但主要分布在52.114.0.0/16、52.120.0.0/16。若ip.addr 52.114.132.100无 RTP说明 Teams 未发送媒体——问题在 Teams 侧或 SIP 路由策略。6.3 License 使用率实时监控用acp_license_info cron 自动告警生产环境必须监控 License 使用率。我一般会写一个脚本每 5 分钟检查并在超 80% 时发邮件#!/bin/bash # /opt/monitor/sbc-license-check.sh USED$(sudo /usr/local/audiocodes/bin/acp_license_info 2/dev/null | grep Used: | awk {print $2} | sed s/\///) TOTAL$(sudo /usr/local/audiocodes/bin/acp_license_info 2/dev/null | grep Total: | awk {print $2}) USAGE_PCT$((USED * 100 / TOTAL)) if [ $USAGE_PCT -gt 80 ]; then echo ALERT: SBC License usage at ${USAGE_PCT}% on $(hostname) | mail -s SBC License Warning admincontoso.com fi加入 crontab*/5 * * * * /opt/monitor/sbc-license-check.sh从那以后我每次部署新 SBC都强制走一遍sipcmd注册测试 tcpdump抓包验证哪怕客户说“只要 Admin Center 显示绿色就行”。因为绿色图标只代表 SIP REGISTER 成功不代表媒体通、License 足、DNS 准——而用户投诉的“打不通”90% 出现在这三处。希望帮到你。本文还有配套的精品资源点击获取