Kamailio新手指南

Kamailio典型地仅支持Linux操作系统,直接在操作系统上安装也很方便。当然,最方便的是直接使用Docker启动Kamailio。Docker可以在Windows、macOS和Linux等宿主机操作系统上运行,所以,不管你使用何种操作系统,都可以很方便地运行Kamailio。

下面,我们使用kamailio/kamailio-ci:5.5.2-alpine这个Docker镜象,来自 https://hub.docker.com/r/kamailio/kamailio-ci 。以下命令可以启动Docker镜象:

docker run --name kamailio --rm kamailio/kamailio-ci:5.5.2-alpine -m 64 -M 8

启动后,可以看到类似如下输出:

Listening on
             udp: 127.0.0.1:5060
             udp: 172.17.0.4:5060
             tcp: 127.0.0.1:5060
             tcp: 172.17.0.4:5060
Aliases:
             tcp: 3ea18bb32dc7:5060
             tcp: localhost:5060
             udp: 3ea18bb32dc7:5060
             udp: localhost:5060

表示Kamailio已经运行并监听了上面的IP地址和端口,但这时Kamailio是无法正常使用的。因为Docker容器本身运行在NAT网络环境。不过,这时候可以进入容器内部查看相关的配置文件,如:

docker exec -it kamailio sh
cat /etc/kamailio/kamailio.cfg

如果你的宿主机是Linux,可以以host模式启动:

docker run --net=host --name kamailio --rm kamailio/kamailio-ci:5.5.2-alpine

这时候,就可以尝试用SIP客户端1注册了。随便注册两个不同的账号(Kamailio默认脚本没有鉴权),还可以互打。

在Mac和Windows上host模式可能不适用,可以继续以NAT模式启动,并将端口映射出来,如:

docker run --name kamailio --rm \
-p 5060:6060/udp -p 5060:6060 \
kamailio/kamailio-ci:5.5.2-alpine -m64 -M8

但使用NAT模式时,需要修改Kamailio的配置文件,这时候,我们可以先进入Shell,修改完配置文件后,再启动Kamailio。以下命令启动容器并进入Shell(由于使用了--entrypoint参数覆盖了自启动入口,不会启动Kamailio):

docker run --name kamailio --rm \
-p 5060:6060/udp -p 5060:6060 \
--entrypoint=/bin/sh -it \
kamailio/kamailio-ci:5.5.2-alpine -m64 -M8

在容器Shell内执行ip ad可以看到网卡eth0的IP地址,记下来(如笔者的是172.17.0.4),然后执行如下命令启动Kamailio:

kamailio

默认Kamailio将会启动到后台。可以安装个ngrep2方便抓包查看SIP消息:

apk add ngrep
ngrep -p -q -Wbyline port 5060

apk是Alpine Linux上的软件包管理工具。如果你在国内,安装可能比较慢。可以尝试使用国内镜象,比如我们下面使用阿里云的镜象站:

echo "http://mirrors.aliyun.com/alpine/v3.13/main/" > /etc/apk/repositories
echo "http://mirrors.aliyun.com/alpine/v3.13/community/" >> /etc/apk/repositories
apk add ngrep  # 这样就会快很多

但这种方式运行的Kamilio通常不能正常接打电话,那是因为,Docker网络是一个NAT。为解决这一问题,我们需要让容器内的Kamailio知道自己的“外网”地址。如果你用过FreeSWITCH,你肯定熟悉,FreeSWITCH的SIP Profile配置中有一个ext-sip-ip,在Kamailio中也类似,只不过,它叫advertise IP。在下面的示例中,192.168.7.7是我的宿主机的IP。

先停掉Kamailio:killall kamailio

修改配置文件:vi /etc/kamailio/kamailio.cfg,找到# listen=udp:10.0.0.10:5060一行,在后面增加如下两行:

listen=udp:172.17.0.4:5060 advertise 192.168.7.7:5060
listen=tcp:172.17.0.4:5060 advertise 192.168.7.7:5060

重新启动Kamailio可以看到监听地址变了:

# kamailio

Listening on
             udp: 172.17.0.4:5060 advertise 192.168.7.7:5060
             tcp: 172.17.0.4:5060 advertise 192.168.7.7:5060
Aliases:
             tcp: 4e2e9ac37dcf:5060
             udp: 4e2e9ac37dcf:5060

小技巧

  • kamailio默认会启动到后台,如果在配置文件中增加fork=false,则会启动到前台,可以直接用Ctrl + C退出,而无需killall。这在学习时比较方便。
  • Docker的NAT模式,UDP通道映射有时保持不好,经常需要重新注册才能打通电话,这时可以换TCP注册。
  • 启动到前台时,建议修改配置文件,增加Kamailio的日志级别(如debug=3)以查看更多日志。
  • 如果启动容器时有同名的容器存在,或映射端口冲突,则不能启动。可以换一个名字启动或端口,或者用docker ps查看所有运行的容器,用docker stop停止及docker rm删掉不需要的容器。

在上面的例子中,我们直接在容器内修改Kamailio的配置文件,在容器重建时会丢失修改。为了能长期保存劳动成果,可以将宿主机上的文件或文件夹映射到容器里面。不过,前提我们得先有个文件夹,下面,我们先启动个临时容器,从里面复制一个出来。

docker create --name kamailio kamailio/kamailio-ci:5.5.2-alpine
docker cp kamailio:/etc/kamailio /tmp/
docker rm kamailio
ls -l /tmp/kamailio

重新启动容器,并通过-v参数将宿主机的目录映射到容器里面。如果想让Kamailio自动启动,可以去掉--entrypoint参数一行,否则,需要手动启动。

docker run --name kamailio --rm \
-p 5060:6060/udp -p 5060:6060 \
-v /tmp/kamailio:/etc/kamailio \
--entrypoint=/bin/sh -it \
kamailio/kamailio-ci:5.5.2-alpine -m64 -M8

这样,就可以随时在宿主机上用你喜欢的编辑器编辑配置文件并在容器内部重启Kamailio了。其中,/tmp/是你宿主机上的文件夹路径,在此只为了说明方便,在真正用的时候也不要使用这个路径,因为它本质上也是“临时的”。

祝贺你成功运行了Kamailio。如果你还觉得不过瘾,下面是Kamailio的一些资源列表:

Footnotes

  1. 可以参考笔者的微信公众号文章:我用过的那些SIP客户端 https://mp.weixin.qq.com/s/9fCf8xf_A4K6UNwZRKmhjw

  2. 目前,该Kamailio镜象仅有X86_64版的,在M1芯片(ARM芯片)的Mac上可以正常运行,但是ngrep之类的抓包工具不好用。