本指南旨在帮助对 SIP(会话发起协议)零基础的用户快速搭建并运行一个基于 Kamailio 和 RTPengine 的 SIP 服务端。以下内容将从零开始,逐步引导您完成配置和运行。
确保您的系统已安装 Docker 和 Docker Compose。如果尚未安装,请参考以下链接:
以下是完整的 docker-compose.yml
配置示例:
version: '3.8'
services:
sip_server:
image: ghcr.io/kamailio/kamailio:5.8.4-xenial
container_name: sip_server
network_mode: host
volumes:
- ./kamailio.cfg:/etc/kamailio/kamailio.cfg
depends_on:
- rtpengine
rtpengine:
image: fonoster/rtpengine:0.3.17
container_name: rtpengine
network_mode: host
environment:
- RTPENGINE_PUBLIC_IP=<您的外部 IP>
- RTPENGINE_BIND_HTTP_PORT=2225
- RTPENGINE_BIND_NG_PORT=2223
将 <您的外部 IP>
替换为您的主机外部 IP。
确保在配置文件中启用了 NAT 相关定义:
#!define WITH_NAT
#!define WITH_RTPENGINE
在 Kamailio 配置文件中,#!define
是用于启用或禁用某些功能的预处理指令。
WITH_NAT
和 WITH_RTPENGINE
是用于启用 NAT 处理和 RTP 引擎支持的功能开关,具体作用如下:
这个指令用于启用 NAT(Network Address Translation) 支持。NAT 是一种用于网络地址转换的技术,它允许内网设备通过共享外网 IP 进行通信。在 SIP 通信中,NAT 可能会导致问题,因为 SIP 报文中的 IP 地址和端口通常是私有的,需要转换为公网地址。
- 启用此选项后,Kamailio 会自动检测和处理 NAT 环境中的 SIP 消息,包括处理外部网络的 IP 地址和端口映射。
- 通常与
RTPEngine
(或类似的媒体代理)结合使用,以确保媒体流能够在 NAT 环境中正确传递。 - 该功能需要在配置中启用
WITH_RTPENGINE
或其他 NAT 相关工具(如 RTPProxy)。
这个指令用于启用 RTPEngine 支持,RTPEngine 是一个专门为 SIP 提供的媒体代理,用于处理媒体流(如音频、视频)和解决 NAT 问题。RTPEngine 作为 Kamailio 的一部分,用于在 NAT 环境中实现流量的转发和地址的映射。
- 启用
WITH_RTPENGINE
后,Kamailio 可以与 RTPEngine 配合工作,使用 RTPEngine 处理 SIP 媒体流的 NAT 穿透。 - 当 SIP 消息通过 Kamailio 时,RTPEngine 将帮助管理媒体流,尤其是在 NAT 环境下确保数据流畅地通过。
- 通常,您还需要在 Kamailio 配置文件中指定 RTPEngine 的地址和端口,并通过
rtpengine_manage
等指令与其交互。
这两个选项通常一起使用,尤其是在需要跨 NAT 进行 SIP 通信时,确保 SIP 信令和媒体流能够顺利通过防火墙或路由器。
设置 Kamailio 在所有网络接口上监听 SIP 流量,并广播外部地址:
listen=0.0.0.0:5060 advertise <您的外部 IP>:5060
listen
是 Kamailio 配置中用来指定 Kamailio 监听的 IP 地址和端口的指令。0.0.0.0
表示 Kamailio 将监听所有可用的本地 IP 地址(包括所有网卡和接口)。这样配置后,Kamailio 不限于某一个特定的网络接口,它将接收从任意 IP 地址到达的 SIP 请求。5060
是 SIP 协议的默认端口号。配置成5060
表示 Kamailio 将监听该端口上的 SIP 请求。5060 端口通常用于未加密的 SIP 流量。
所以,listen=0.0.0.0:5060
的意思是:Kamailio 将在所有网络接口上监听 5060 端口上的 SIP 流量。
advertise
是用于指定 Kamailio 向外部通告其公共 IP 地址的指令。这个地址通常是在 NAT(网络地址转换)环境下的公共 IP 地址,或者是您希望对外显示的地址。<您的外部 IP>
应该替换为您服务器的外部公共 IP 地址(即公网 IP),它是对外部通信方可见的地址。5060
是 Kamailio 向外部宣告的端口号。通常,您希望广告的是公共 IP 地址及其相应的 SIP 端口,这样外部设备可以通过该 IP 地址来连接您的 SIP 服务。
advertise <您的外部 IP>:5060
的意思是:Kamailio 将向外界宣布自己在公网中的 IP 地址和端口,以便外部的 SIP 客户端可以正确地向它发送请求。
listen
设置 Kamailio 监听的 IP 地址和端口,通常在 NAT 环境下,Kamailio 会绑定到0.0.0.0
使其可以接受来自所有网络接口的流量。advertise
则指定了 Kamailio 对外的公共 IP 地址和端口,它用于告诉外部设备如何访问 Kamailio 服务,尤其是在存在 NAT 或防火墙的情况下,确保外部客户端能够使用正确的 IP 地址和端口与 Kamailio 通信。
- 如果 Kamailio 运行在一个有 NAT 的环境中(例如内网服务器通过防火墙或路由器与外网通信),
listen=0.0.0.0:5060
使 Kamailio 可以接收所有传入的 SIP 请求,无论它们来自哪个网络接口。 advertise <您的外部 IP>:5060
确保 Kamailio 对外广播的 IP 地址是正确的,通常是服务器的公共 IP 地址,确保外部 SIP 客户端能够通过该 IP 地址和端口连接到 Kamailio 服务。
在 request_route
中添加以下处理逻辑:
request_route {
if (is_method("INVITE")) {
# 启用 RTPengine
rtpengine_offer();
}
if (is_method("BYE")) {
# 停止 RTPengine
rtpengine_delete();
}
}
如需强制启用 NAT 处理,可使用以下配置:
#!ifdef WITH_RTPENGINE
# if(nat_uac_test("8")) {
# rtpengine_manage("SIP-source-address replace-origin replace-session-connection");
# } else {
# rtpengine_manage("replace-origin replace-session-connection");
# }
rtpengine_manage("replace-origin replace-session-connection ICE=force");
#!else
运行以下命令启动服务:
docker-compose up -d
RTPengine 是一个专为 SIP 系统设计的媒体代理。以下是常用配置及环境变量说明:
rtpengine:
image: fonoster/rtpengine:0.3.17
container_name: rtpengine
network_mode: host
environment:
- RTPENGINE_PUBLIC_IP=<您的外部 IP>
- RTPENGINE_BIND_HTTP_PORT=2225
- RTPENGINE_BIND_NG_PORT=2223
RTPENGINE_PUBLIC_IP
:外部 IP 地址(必填)。RTPENGINE_BIND_HTTP_PORT
:HTTP 接口端口,默认值为 8080。RTPENGINE_BIND_NG_PORT
:NG 接口端口,默认值为 22222。RTPENGINE_PORT_MIN
/RTPENGINE_PORT_MAX
:媒体端口范围,默认值为 10000-10500。RTPENGINE_LOG_LEVEL
:日志级别,默认值为 7(详细日志)。RTPENGINE_CLOUD
:云服务名称(如 AWS、GCP 等),默认为*
。
更多配置可参考以下链接:
-
如何确认服务正常运行?
- 使用
docker ps
确认容器是否已启动。 - 检查 Kamailio 日志:
docker logs sip_server
。 - 检查 RTPengine 日志:
docker logs rtpengine
。
- 使用
-
如何调试 SIP 流量?
- 使用工具 Wireshark 捕获并分析 SIP 和 RTP 流量。
- 使用
sngrep
实时查看 SIP 报文。
通过以上步骤,您应该可以成功配置并运行一个支持 NAT 和 RTP 的 SIP 服务端。