Kamailio 启动报错 "invalid curve" 与 "freeing already freed pointer" 的终极解决方案
一、问题现象
在启动 Kamailio 时,journalctl -u kamailio -f 持续输出如下错误:
bash
CRITICAL: <core> [core/mem/q_malloc.c:519]: qm_free(): BUG: freeing already freed pointer (0x7f408c0ff3e0), called from tls: tls_init.c: ser_free(323), first free tls: tls_init.c: ser_free(323) - ignoring
ERROR: db_mysql [km_my_con.c:163]: db_mysql_new_connection(): driver error: SSL connection error: error:0800008D:elliptic curve routines::invalid curve
ERROR: <core> [db.c:319]: db_do_init2(): could not add connection to the pool
ERROR: auth_db [auth_db_mod.c:161]: child_init(): unable to connect to the database
ERROR: <core> [core/sr_module.c:874]: init_mod_child(): error while initializing module auth_db
ERROR: <core> [core/pt.c:338]: fork_process(): init_child failed for process ...
CRITICAL: <core> [main.c:1716]: main_loop(): Cannot fork
Kamailio 启动失败,无法正常提供服务。
二、环境信息
- Kamailio 版本:5.5.4 (x86_64/linux)
- 操作系统:Ubuntu 20.04 / 22.04 (基于日志 host-192-168-200-6)
- 数据库:MySQL (192.168.100.4:3306)
- 编译选项:
USE_TLS,USE_MYSQL,USE_AUTH等均已开启
三、原因分析
1. MySQL SSL 连接错误(invalid curve)
Kamailio 的 db_mysql 模块在连接 MySQL 时尝试使用 SSL/TLS 加密,但客户端与服务器之间协商的**椭圆曲线(Elliptic Curve)**不匹配,导致 SSL 握手失败。
常见于:
- 服务器端 MySQL 强制要求 SSL,但客户端 OpenSSL 版本过旧或曲线不支持。
- Kamailio 编译时链接的 OpenSSL 库与 MySQL 服务器支持的曲线不一致。
2. TLS 模块双重释放警告(freeing already freed pointer)
Kamailio 多进程模式下,TLS 模块(tls.so)内部的 OpenSSL 共享上下文未正确保护,导致同一个内存指针被多次释放。该问题在 Kamailio 5.5.x 中较为常见,通常不会直接导致崩溃,但会产生大量 CRITICAL 日志,并可能引发偶发性段错误。
四、解决方案
✅ 修复 MySQL SSL 连接错误
在配置文件中添加 modparam("db_mysql", "opt_ssl_mode", 1) 禁用 MySQL 客户端的 SSL 连接。
操作步骤:
-
编辑 Kamailio 配置文件(通常为
/etc/kamailio/kamailio.cfg)。 -
找到
loadmodule "db_mysql.so"所在行,在其下方添加:cfgmodparam("db_mysql", "opt_ssl_mode", 1)示例:
cfg#!ifdef WITH_MYSQL loadmodule "db_mysql.so" modparam("db_mysql", "opt_ssl_mode", 1) #!endif -
保存文件。
✅ 缓解 TLS 双重释放警告
在 TLS 模块配置区添加 modparam("tls", "tls_threads_mode", 1)。
-
找到
# ----- tls params -----区域。 -
添加如下配置:
cfgmodparam("tls", "tls_threads_mode", 1)完整示例:
cfg#!ifdef WITH_TLS # ----- tls params ----- modparam("tls", "tls_threads_mode", 1) modparam("tls", "config", "/etc/kamailio/tls.cfg") #!endif
注 :
tls_threads_mode=1可让 Kamailio 为每个进程创建独立的 OpenSSL 上下文,避免共享内存被错误释放。
五、验证与重启
-
检查配置文件语法:
bashkamailio -c -f /etc/kamailio/kamailio.cfg输出应为
config file ok,无错误。 -
重启 Kamailio:
bashsystemctl restart kamailio -
实时查看日志:
bashjournalctl -u kamailio -f应不再出现
invalid curve及freeing already freed pointer错误,Kamailio 正常 fork 子进程。
六、其他注意事项
-
如果你的业务要求 MySQL 连接必须使用 SSL,请不要禁用
opt_ssl_mode,而应该升级 OpenSSL 库并统一 MySQL 服务器的椭圆曲线配置 。例如在 MySQL 配置文件my.cnf中添加:ini[mysqld] ssl_cipher = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 -
tls_threads_mode=1对性能几乎无影响,建议长期保留。 -
若禁用 SSL 后希望恢复加密连接,可将
opt_ssl_mode设为2或3(尝试 SSL 但不强制),但需确保曲线匹配。
七、总结
| 错误现象 | 根本原因 | 解决方案 |
|---|---|---|
SSL connection error: invalid curve |
MySQL 客户端 SSL 曲线不匹配 | modparam("db_mysql", "opt_ssl_mode", 1) |
freeing already freed pointer |
TLS 多进程共享 OpenSSL 上下文 | modparam("tls", "tls_threads_mode", 1) |
以上两个参数修改后,Kamailio 即可正常启动。如果你的环境有特殊要求(如必须使用 SSL 连接数据库),请参考第六节的补充说明进行调整。
如果对你有帮助,请点赞、收藏、关注,支持我分享更多优质内容。