Update post-commit

This commit is contained in:
jack ning
2025-10-21 14:55:06 +08:00
parent 19d3b0626b
commit 4faddeca15
6 changed files with 1032 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
1 sip:14.103.165.199:5060;transport=udp
2 sip:14.103.165.199:5060;transport=tcp
3 sip:14.103.165.199:5080;transport=tcp

View File

@@ -0,0 +1,79 @@
#!define WITH_NAT
#!substdef "!MY_PUBLIC_IP!124.220.58.234!g"
#!substdef "!DISPATCHER_LIST!/etc/kamailio/dispatcher.list!g"
listen=udp:0.0.0.0:5060 advertise MY_PUBLIC_IP:5060
alias="sip.weiyuai.cn"
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "sanity.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "pv.so"
loadmodule "xlog.so"
loadmodule "dispatcher.so"
loadmodule "nathelper.so"
modparam("dispatcher", "list_file", "DISPATCHER_LIST")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "dst_avp", "$avp(dsdst)")
modparam("dispatcher", "cnt_avp", "$avp(dscnt)")
modparam("rr", "enable_full_lr", 1)
modparam("rr", "append_fromtag", 0)
modparam("tm", "fr_timer", 3000)
modparam("tm", "fr_inv_timer", 90000)
# NAT helper
modparam("nathelper", "received_avp", "$avp(rcv)"
)
route[DISPATCH] {
if(!ds_select_dst(1, 0)) {
send_reply(500, "No Upstream");
exit;
}
t_on_reply("NAT_REPLY");
t_relay();
exit;
}
onreply_route[NAT_REPLY] {
# Fix nat on replies
if(isflagset(FLT_NATS)) {
fix_nated_contact();
}
}
request_route {
if (!mf_process_maxfwd(10)) {
send_reply(483, "Too Many Hops");
exit;
}
if (!sanity_check("1511", "7")) {
send_reply(400, "Bad Request");
exit;
}
# NAT handling
force_rport();
if (nat_uac_test(19)) {
setflag(FLT_NATS);
fix_nated_contact();
}
if (is_method("OPTIONS") && ($ru == "sip:sip.weiyuai.cn" || $rU == "")) {
send_reply(200, "OK");
exit;
}
record_route();
route(DISPATCH);
}

View File

@@ -0,0 +1,214 @@
# Kamailio 部署与配置指南(反代 FreeSWITCH 的 5060/UDP
本文档指导你将 Nginx 的 5060/UDP 转发切换为由 Kamailio 负责的专业 SIP 代理,以解决 UDP/NAT 回包路径问题。Nginx 继续用于 HTTP/WS/WSS例如 WSS 到 FreeSWITCH
适用环境
- OS: Ubuntu 24.04(命令对 Debian/Ubuntu 通用)
- 公网 IPKamailio`124.220.58.234`
- FreeSWITCH 公网 IP`14.103.165.199`
- SIP 域名:`sip.weiyuai.cn`
- 协议/端口SIP/UDP 5060
> 若你的实际 IP/域名不同,请将文档中的示例值替换为你的真实值。
---
## 1. 释放 Nginx 的 5060/UDP如果之前由 Nginx 代理)
1) 编辑 `/etc/nginx/nginx.conf`,删除 `stream {}` 内监听 5060/udp 的 server 段。
2) 验证并重载:
```bash
sudo nginx -t && sudo systemctl reload nginx
sudo ss -lunp | grep -E '(:5060\s)' || echo "no udp:5060 listener"
```
---
## 2. 安装 Kamailio 与必要模块
```bash
# 若存在无效的第三方源导致 apt update 失败,先禁用(示例)
# sudo mv /etc/apt/sources.list.d/mysql.list /etc/apt/sources.list.d/mysql.list.disabled || true
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y kamailio kamailio-extra-modules
```
安装完成后,系统会创建 systemd 服务 `kamailio.service`
---
## 3. 配置 Kamailio最小可用代理到 FreeSWITCH
三个关键点:
- Kamailio 监听 0.0.0.0:5060并 advertise 公网 IP确保 Via/Record-Route 对外可用
- 转发所有 SIP 请求到 FreeSWITCH`14.103.165.199:5060`
- 基础 NAT 处理:`force_rport``fix_nated_contact`
### 3.1 上游列表 `/etc/kamailio/dispatcher.list`
```bash
sudo tee /etc/kamailio/dispatcher.list >/dev/null <<'EOF'
1 sip:14.103.165.199:5060
EOF
```
### 3.2 主配置 `/etc/kamailio/kamailio.cfg`
如下为最小、可直接使用的配置。若该文件已有内容,建议先备份再覆盖。
```bash
sudo tee /etc/kamailio/kamailio.cfg >/dev/null <<'EOF'
#!KAMAILIO
debug=2
log_stderror=no
children=4
enable_sctp=no
listen=udp:0.0.0.0:5060 advertise 124.220.58.234:5060
alias="sip.weiyuai.cn"
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
# Modules
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "sanity.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "pv.so"
loadmodule "xlog.so"
loadmodule "dispatcher.so"
loadmodule "nathelper.so"
# Module params
modparam("rr", "enable_full_lr", 1)
modparam("rr", "append_fromtag", 0)
modparam("tm", "fr_timer", 30000)
modparam("tm", "fr_inv_timer", 120000)
modparam("sanity", "autodrop", 0)
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("nathelper", "received_avp", "$avp(rcv)")
route[DISPATCH] {
if(!ds_select_dst(1, 0)) {
send_reply(500, "No Upstream");
exit;
}
t_on_reply("NAT_REPLY");
if(!t_relay()) {
sl_reply_error();
}
exit;
}
onreply_route[NAT_REPLY] {
if(isflagset(5)) {
fix_nated_contact();
}
}
request_route {
if (!sanity_check("1511", "7")) {
send_reply(400, "Bad Request");
exit;
}
# Basic NAT handling
force_rport();
if (nat_uac_test(19)) {
setflag(5);
fix_nated_contact();
}
# Stay in the signaling path
record_route();
route(DISPATCH);
}
EOF
```
> 如 FreeSWITCH 实际对外监听为 `5080/udp`,请将 dispatcher.list 中的端口改为 5080。
---
## 4. 启动与验证
```bash
# 语法检查
sudo kamailio -c -f /etc/kamailio/kamailio.cfg
# 启动服务
sudo systemctl enable --now kamailio
sudo systemctl status --no-pager -l kamailio
# 确认监听 5060/udp
sudo ss -lunp | grep -E '(:5060\s)' || true
```
### 4.1 本机快速测试OPTIONS
```bash
printf 'OPTIONS sip:weiyuai.cn SIP/2.0\r\nVia: SIP/2.0/UDP 124.220.58.234:5060;branch=z9hG4bK-9999;rport\r\nMax-Forwards: 70\r\nFrom: <sip:ping@sip.weiyuai.cn>;tag=9999\r\nTo: <sip:ping@sip.weiyuai.cn>\r\nCall-ID: 9999@sip.weiyuai.cn\r\nCSeq: 1 OPTIONS\r\nContact: <sip:ping@124.220.58.234:5060>\r\nContent-Length: 0\r\n\r\n' | nc -u -w2 124.220.58.234 5060 | sed -n '1,80p'
```
如果看到 `SIP/2.0 200 OK``Record-Route` 中包含 Kamailio公网/内网地址),说明路径正常。
---
## 5. 需要同时检查的外部条件
- 云安全组/防火墙:
- Kamailio 机124.220.58.234)入站放行 UDP/5060
- FreeSWITCH 机14.103.165.199)入站允许来自 124.220.58.234 的 UDP/5060
- FreeSWITCH
- external_sip_ip 与 external_rtp_ip 设置为 14.103.165.199(公网)
- 外部 profile 监听端口确认与上游一致5060 或 5080
- ACL 允许 124.220.58.234
- 客户端:
- 注册到 `sip:用户名@sip.weiyuai.cn:5060`,失败时抓包对照 Kamailio/FreeSWITCH 日志
---
## 6. 常见问题排查
- `config file ok` 但服务起不来:
- `journalctl -xeu kamailio` 查看错误详细
- 返回 4xx/5xx 或无回包:
- Kamailio`journalctl -u kamailio -f`
- FreeSWITCH 日志:检查是否收到请求、是否 ACL 拒绝
- 核对安全组/端口是否放通
- Via/Contact 显示内网地址:
- 确保 Kamailio 配置了 `advertise 公网IP`
- FreeSWITCH external_sip_ip/external_rtp_ip 设置是否正确
---
## 7. 回滚方案(改回直连 FreeSWITCH
- 将 DNS A 记录 `sip.weiyuai.cn` 指向 `14.103.165.199`
- 在 14.103.165.199 放行 UDP/5060或 5080
- 关闭 Kamailio`sudo systemctl disable --now kamailio`
---
## 8. 进阶建议(可选)
- 负载均衡/高可用:在 `/etc/kamailio/dispatcher.list` 中加入多台 FreeSWITCH设置失败转移与探测
- 抗扫描/限速:启用 `pike``htable`,对异常源做封禁
- 媒体穿透:如遇复杂 NAT考虑配合 TURN/ICE或引入 `rtpengine`(或 `rtpproxy`
- 安全限制来源网段、TLS/SIPS、对注册/呼叫做鉴权策略
---
完成后请用外网软电话进行注册与呼叫测试若需要我可根据你的现网参数进一步完善配置例如5080/udp、多上游、SIP 头策略、限速等)。

View File

@@ -0,0 +1,89 @@
#!KAMAILIO
debug=2
log_stderror=no
children=4
enable_sctp=no
listen=udp:0.0.0.0:5060 advertise 124.220.58.234:5060
# Enable TCP listeners for SIP on 5060 and external TCP on 5080
listen=tcp:0.0.0.0:5060 advertise 124.220.58.234:5060
listen=tcp:0.0.0.0:5080 advertise 124.220.58.234:5080
alias="sip.weiyuai.cn"
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
# Modules (tm must be loaded before modules depending on it)
loadmodule "tm.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "sanity.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "pv.so"
loadmodule "xlog.so"
loadmodule "dispatcher.so"
loadmodule "nathelper.so"
# Module params
modparam("rr", "enable_full_lr", 1)
modparam("rr", "append_fromtag", 0)
modparam("tm", "fr_timer", 30000)
modparam("tm", "fr_inv_timer", 120000)
modparam("sanity", "autodrop", 0)
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("nathelper", "received_avp", "$avp(rcv)")
route[DISPATCH] {
# Select upstream set based on received transport and port
if ($proto == "udp" && $Rp == 5060) {
if(!ds_select_dst(1, 0)) { send_reply(500, "No Upstream UDP5060"); exit; }
} else if ($proto == "tcp" && $Rp == 5060) {
if(!ds_select_dst(2, 0)) { send_reply(500, "No Upstream TCP5060"); exit; }
} else if ($proto == "tcp" && $Rp == 5080) {
if(!ds_select_dst(3, 0)) { send_reply(500, "No Upstream TCP5080"); exit; }
} else {
if(!ds_select_dst(1, 0)) { send_reply(500, "No Upstream"); exit; }
}
t_on_reply("NAT_REPLY");
if(!t_relay()) {
sl_reply_error();
}
exit;
}
onreply_route[NAT_REPLY] {
if (isflagset(5)) {
# Only attempt to fix Contact on provisional/success replies that actually carry Contact
if ($rs >= 100 && $rs < 300 && is_present_hf("Contact")) {
fix_nated_contact();
}
}
}
request_route {
if (!sanity_check("1511", "7")) {
send_reply(400, "Bad Request");
exit;
}
# Basic NAT handling
force_rport();
if (nat_uac_test(19)) {
setflag(5);
if (is_present_hf("Contact")) {
fix_nated_contact();
}
}
# Stay in the signaling path
record_route();
route(DISPATCH);
}

168
deploy/kamailio/kamctlrc Normal file
View File

@@ -0,0 +1,168 @@
## The Kamailio configuration file for the control tools.
##
## Here you can set variables used in the kamctl and kamdbctl setup
## scripts. Per default all variables here are commented out, the control tools
## will use their internal default values.
## the SIP domain
# SIP_DOMAIN=kamailio.org
## chrooted directory
# CHROOT_DIR="/path/to/chrooted/directory"
## database type: MYSQL, PGSQL, ORACLE, DB_BERKELEY, DBTEXT, or SQLITE
## by default none is loaded
##
## If you want to setup a database with kamdbctl, you must at least specify
## this parameter.
# DBENGINE=MYSQL
## database host
# DBHOST=localhost
## database port
# DBPORT=3306
## database name (for ORACLE this is TNS name)
# DBNAME=kamailio
## database path used by dbtext, db_berkeley or sqlite
# DB_PATH="/usr/local/etc/kamailio/dbtext"
## database read/write user
# DBRWUSER="kamailio"
## password for database read/write user
# DBRWPW="kamailiorw"
## database read only user
# DBROUSER="kamailioro"
## password for database read only user
# DBROPW="kamailioro"
## database access host (from where is kamctl used)
# DBACCESSHOST=192.168.0.1
## database super user (for ORACLE this is 'scheme-creator' user)
# DBROOTUSER="root"
## password for database super user
## - important: this is insecure, targeting the use only for automatic testing
## - known to work for: mysql
# DBROOTPW="dbrootpw"
## option to ask confirmation for all database creation steps
# DBINITASK=yes
## database character set (used by MySQL when creating database)
#CHARSET="latin1"
## user name column
# USERCOL="username"
## SQL definitions
## If you change this definitions here, then you must change them
## in db/schema/entities.xml too.
## FIXME
# FOREVER="2030-05-28 21:32:15"
# DEFAULT_Q="1.0"
## Program to calculate a message-digest fingerprint
# MD5="md5sum"
## awk tool
# AWK="awk"
## gdb tool
# GDB="gdb"
## If you use a system with a grep and egrep that is not 100% gnu grep compatible,
## e.g. solaris, install the gnu grep (ggrep) and specify this below.
##
## grep tool
# GREP="grep"
## egrep tool
# EGREP="egrep"
## sed tool
# SED="sed"
## tail tool
# LAST_LINE="tail -n 1"
## expr tool
# EXPR="expr"
## Describe what additional tables to install. Valid values for the variables
## below are yes/no/ask. With ask (default) it will interactively ask the user
## for an answer, while yes/no allow for automated, unassisted installs.
## If to install tables for the modules in the EXTRA_MODULES variable.
# INSTALL_EXTRA_TABLES=ask
## If to install presence related tables.
# INSTALL_PRESENCE_TABLES=ask
## If to install uid modules related tables.
# INSTALL_DBUID_TABLES=ask
## Define what module tables should be installed.
## If you use the postgres database and want to change the installed tables, then you
## must also adjust the STANDARD_TABLES or EXTRA_TABLES variable accordingly in the
## kamdbctl.base script.
## Kamailio standard modules
# STANDARD_MODULES="standard acc lcr domain group permissions registrar usrloc msilo
# alias_db uri_db speeddial avpops auth_db pdt dialog dispatcher
# dialplan"
## Kamailio extra modules
# EXTRA_MODULES="imc cpl siptrace domainpolicy carrierroute userblocklist htable purple sca"
## type of aliases used: DB - database aliases; UL - usrloc aliases
## - default: none
# ALIASES_TYPE="DB"
## control engine: RPCFIFO
## - default RPCFIFO
# CTLENGINE="RPCFIFO"
## path to FIFO file for engine RPCFIFO
# RPCFIFOPATH="/run/kamailio/kamailio_rpc.fifo"
## check ACL names; default on (1); off (0)
# VERIFY_ACL=1
## ACL names - if VERIFY_ACL is set, only the ACL names from below list
## are accepted
# ACL_GROUPS="local ld int voicemail free-pstn"
## check if user exists (used by some commands such as acl);
## - default on (1); off (0)
# VERIFY_USER=1
## verbose - debug purposes - default '0'
# VERBOSE=1
## do (1) or don't (0) store plaintext passwords
## in the subscriber table - default '1'
# STORE_PLAINTEXT_PW=0
## Kamailio START Options
## PID file path - default is: /run/kamailio/kamailio.pid
# PID_FILE=/run/kamailio/kamailio.pid
## Kamailio Startup Configuration File
## Default is: kamailio.cfg
# STARTUP_CONFIG_FILE=kamailio.cfg
## Extra start options - default is: not set
## example: start Kamailio with 64MB shared memory: STARTOPTIONS="-m 64"
# STARTOPTIONS=

479
deploy/kamailio/readme.md Normal file
View File

@@ -0,0 +1,479 @@
# Kamailio
专业的 SIP 代理,处理 SIP 的 Via/Record-Route、rport、NAT 以及会话路由
使用 Nginx 继续处理 HTTP/WS/WSS 反向代理
## 架构说明
- **Kamailio**: 专业 SIP 代理服务器,负责 SIP 信令路由、NAT 穿透、会话管理
- **Nginx**: 反向代理,负责 HTTP/WebSocket(WS/WSS) 的代理和 TLS 终结
- **FreeSWITCH**: 后端媒体服务器,处理实际的语音/视频通话
## 安装
### Ubuntu/Debian 系统安装步骤
#### 1. 添加 Kamailio 官方仓库
```bash
# 更新系统包列表
sudo apt update
# 安装必要的工具
sudo apt install -y gnupg2 wget
# 添加 Kamailio 官方 GPG 密钥
wget -O- https://deb.kamailio.org/kamailiodebkey.gpg | sudo apt-key add -
# 添加 Kamailio 仓库(以 Ubuntu 22.04 为例)
# 注意根据你的系统版本选择对应的代号jammy/focal/bullseye等
echo "deb http://deb.kamailio.org/kamailio57 jammy main" | sudo tee /etc/apt/sources.list.d/kamailio.list
# 更新包列表
sudo apt update
```
**常见系统代号:**
- Ubuntu 22.04 LTS: `jammy`
- Ubuntu 20.04 LTS: `focal`
- Debian 11: `bullseye`
- Debian 10: `buster`
#### 2. 安装 Kamailio 及必要模块
```bash
# 安装 Kamailio 核心包
sudo apt install -y kamailio
# 安装 WebSocket 支持模块
sudo apt install -y kamailio-websocket-modules
# 安装 TLS/SSL 支持模块
sudo apt install -y kamailio-tls-modules
# 安装 JSON 和 HTTP 模块(可选,用于 API 集成)
sudo apt install -y kamailio-json-modules kamailio-http-modules
# 安装 MySQL/PostgreSQL 模块(如需数据库支持)
sudo apt install -y kamailio-mysql-modules
# 或
# sudo apt install -y kamailio-postgres-modules
# 安装额外的实用模块
sudo apt install -y kamailio-extra-modules
```
#### 3. 验证安装
```bash
# 查看 Kamailio 版本
kamailio -v
# 检查已安装的模块
ls /usr/lib/x86_64-linux-gnu/kamailio/modules/
# 检查服务状态
sudo systemctl status kamailio
```
#### 4. 启用开机自启
```bash
# 启用 Kamailio 开机自启
sudo systemctl enable kamailio
# 启动 Kamailio
sudo systemctl start kamailio
# 重启 Kamailio
sudo systemctl restart kamailio
# 停止 Kamailio
sudo systemctl stop kamailio
```
## 配置
### 配置文件位置
- **主配置文件**: `/etc/kamailio/kamailio.cfg`
- **本地配置**: `/etc/kamailio/kamailio-local.cfg` (可选,用于本地化配置)
- **TLS 配置**: `/etc/kamailio/tls.cfg`
- **默认配置**: `/etc/default/kamailio`
### 1. 基础配置 (`/etc/default/kamailio`)
```bash
# 编辑默认配置
sudo nano /etc/default/kamailio
```
```bash
# 启用 Kamailio
RUN_KAMAILIO=yes
# 配置文件路径
CFGFILE=/etc/kamailio/kamailio.cfg
# 运行用户
USER=kamailio
GROUP=kamailio
# SIP UDP 端口
SIP_UDP_PORT=5060
# SIP TCP 端口
SIP_TCP_PORT=5060
# SIP TLS 端口
SIP_TLS_PORT=5061
# 监听地址(留空表示监听所有接口)
SIP_LISTEN_ADDR=
# 日志级别 (0=ALERT, 1=CRIT, 2=ERR, 3=WARN, 4=NOTICE, 5=INFO, 6=DEBUG)
LOG_LEVEL=3
# 内存大小
MEMORY=64
```
### 2. 主配置文件 (`/etc/kamailio/kamailio.cfg`)
创建或编辑主配置文件:
```bash
sudo cp /etc/kamailio/kamailio.cfg /etc/kamailio/kamailio.cfg.bak
sudo nano /etc/kamailio/kamailio.cfg
```
```cfg
#!KAMAILIO
####### Global Parameters #########
### 日志配置
debug=3
log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL0
fork=yes
children=4
### 网络配置
# 替换为你的实际公网 IP
#!define PUBLICIP "14.103.165.199"
#!substdef "!PUBLICIP!14.103.165.199!g"
# 本地 IP内网 IP如果没有 NAT 则与 PUBLICIP 相同)
#!define LOCALIP "127.0.0.1"
# FreeSWITCH 地址
#!define FREESWITCH_IP "14.103.165.199"
#!define FREESWITCH_PORT 5080
### 监听配置
# SIP UDP
listen=udp:0.0.0.0:5060
# SIP TCP
listen=tcp:0.0.0.0:5060
# SIP TLS (如需要)
# listen=tls:0.0.0.0:5061
### 协议配置
disable_tcp=no
enable_tls=no
tcp_connection_lifetime=3605
tcp_accept_no_cl=yes
tcp_rd_buf_size=16384
### DNS 配置
dns=no
rev_dns=no
dns_try_ipv6=no
### 别名配置
# 替换为你的实际域名
alias="sip.weiyuai.cn"
alias="weiyuai.cn"
####### 模块加载 #########
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "nathelper.so"
loadmodule "rtpproxy.so"
####### 模块参数 #########
### jsonrpcs 参数
modparam("jsonrpcs", "pretty_format", 1)
### tm 参数
modparam("tm", "failure_reply_mode", 3)
modparam("tm", "fr_timer", 30000)
modparam("tm", "fr_inv_timer", 120000)
### rr 参数
modparam("rr", "enable_full_lr", 1)
modparam("rr", "append_fromtag", 1)
### nathelper 参数
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", 7)
modparam("nathelper", "sipping_from", "sip:pinger@weiyuai.cn")
### rtpproxy 参数 (如果使用 RTPProxy)
# modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:22222")
####### 路由逻辑 #########
# 主请求路由
request_route {
# 基本的防洪和安全检查
route(REQINIT);
# NAT 检测
route(NATDETECT);
# 处理 OPTIONS (心跳检测)
if (is_method("OPTIONS")) {
sl_send_reply("200", "OK");
exit;
}
# 记录路由处理
if (is_method("INVITE|SUBSCRIBE")) {
record_route();
}
# 转发到 FreeSWITCH
route(FREESWITCH);
}
# 初始化检查路由
route[REQINIT] {
# 检查最大转发次数
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483", "Too Many Hops");
exit;
}
# 基本的 SIP 消息合法性检查
if (!sanity_check("1511", "7")) {
xlog("L_WARN", "Malformed SIP message from $si:$sp\n");
exit;
}
}
# NAT 检测路由
route[NATDETECT] {
force_rport();
if (nat_uac_test("19")) {
if (is_method("REGISTER")) {
fix_nated_register();
} else {
if (is_first_hop()) {
set_contact_alias();
}
}
setflag(5); # NAT flag
}
}
# FreeSWITCH 转发路由
route[FREESWITCH] {
# 设置目标为 FreeSWITCH
$du = "sip:" + FREESWITCH_IP + ":" + FREESWITCH_PORT;
# 添加日志
xlog("L_INFO", "Forwarding $rm from $fu to FreeSWITCH: $du\n");
# NAT 处理
if (isflagset(5)) {
if (is_method("INVITE")) {
# 如果使用 RTPProxy取消注释下面这行
# rtpproxy_offer();
}
}
# 转发请求
if (!t_relay()) {
sl_reply_error();
}
exit;
}
# 应答路由
onreply_route {
# NAT 处理
if (isflagset(5)) {
if (is_method("INVITE")) {
# 如果使用 RTPProxy取消注释下面这行
# rtpproxy_answer();
}
handle_rport_n_received();
}
xlog("L_INFO", "Reply $rs $rr from $si:$sp\n");
}
# 失败路由
failure_route {
if (t_is_canceled()) {
exit;
}
xlog("L_INFO", "Failure route triggered: $rm from $fu\n");
}
```
### 3. TLS 配置(可选,如需支持 SIPS
编辑 `/etc/kamailio/tls.cfg`:
```bash
sudo nano /etc/kamailio/tls.cfg
```
```cfg
[server:default]
method = TLSv1.2+
verify_certificate = no
require_certificate = no
private_key = /etc/letsencrypt/live/weiyuai.cn/privkey.pem
certificate = /etc/letsencrypt/live/weiyuai.cn/fullchain.pem
```
### 4. 配置检查和启动
```bash
# 检查配置文件语法
sudo kamailio -c -f /etc/kamailio/kamailio.cfg
# 如果没有错误,重启服务
sudo systemctl restart kamailio
# 查看日志
sudo tail -f /var/log/syslog | grep kamailio
# 或者使用 journalctl
sudo journalctl -u kamailio -f
```
### 5. 防火墙配置
```bash
# 开放 SIP 端口
sudo ufw allow 5060/udp comment 'Kamailio SIP UDP'
sudo ufw allow 5060/tcp comment 'Kamailio SIP TCP'
sudo ufw allow 5061/tcp comment 'Kamailio SIP TLS'
# 如果使用 RTPProxy还需要开放 RTP 端口范围
# sudo ufw allow 10000:20000/udp comment 'RTP Media'
# 重载防火墙
sudo ufw reload
# 查看防火墙状态
sudo ufw status
```
## 与 Nginx 的集成架构
### 请求流程
1. **WebSocket 客户端 (浏览器)**`wss://sip.weiyuai.cn/ws`
2. **Nginx (443)** → TLS 终结,转发 WebSocket → **FreeSWITCH (7443/5066)**
3. **FreeSWITCH** ← SIP 信令 → **Kamailio (5060)** → NAT 穿透、路由
4. **Kamailio** ← SIP 信令 → **其他 SIP 端点** (外部 SIP 客户端、运营商等)
### 工作原理
- **WebSocket 流量**: Nginx 处理 WS/WSS直接转发到 FreeSWITCH
- **SIP 信令流量**: Kamailio 处理 UDP/TCP/TLS SIP负责路由和 NAT
- **媒体流量 (RTP)**: 直接在 FreeSWITCH 和客户端之间传输,或通过 TURN/coturn
## 测试和验证
### 1. 测试 Kamailio SIP 端口
```bash
# 使用 netcat 测试 UDP 端口
nc -u -v 14.103.165.199 5060
# 测试 TCP 端口
nc -v 14.103.165.199 5060
# 使用 sipsak 工具测试(需要安装)
sudo apt install -y sipsak
sipsak -v -s sip:14.103.165.199:5060
```
### 2. 查看 Kamailio 统计信息
```bash
# 使用 kamctl 工具
sudo kamctl stats
# 查看活动连接
sudo kamctl fifo get_statistics all
# 查看内存使用
sudo kamctl fifo get_statistics shmem:
```
### 3. 调试模式
```bash
# 临时提高日志级别到 DEBUG
sudo kamcmd cfg.set_now_int core debug 6
# 恢复默认级别
sudo kamcmd cfg.set_now_int core debug 3
```
## 常见问题
### 1. Kamailio 无法启动
- 检查配置文件语法: `kamailio -c`
- 查看详细错误日志: `journalctl -u kamailio -n 100`
- 确认端口未被占用: `netstat -tuln | grep 5060`
### 2. NAT 穿透问题
- 确保 `nathelper` 模块已加载
- 配置正确的公网 IP (`PUBLICIP`)
- 考虑使用 RTPProxy 或 TURN 服务器处理 RTP
### 3. FreeSWITCH 连接问题
- 检查 FreeSWITCH 的 ACL 配置,允许 Kamailio IP
- 确认 FreeSWITCH 监听正确的端口 (5080)
- 查看 FreeSWITCH 日志: `fs_cli -x "console loglevel debug"`
## 参考资源
- [Kamailio 官方文档](https://www.kamailio.org/docs/)
- [Kamailio Wiki](https://www.kamailio.org/wiki/)
- [FreeSWITCH + Kamailio 集成指南](https://freeswitch.org/confluence/display/FREESWITCH/Kamailio)
- [NAT 穿透最佳实践](https://www.kamailio.org/docs/modules/stable/modules/nathelper.html)