Kamailio 启动报错 “invalid curve” 与 “freeing already freed pointer” 的终极解决方案

一、问题现象

在启动 Kamailio 时,journalctl -u kamailio -f 持续输出如下错误:

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 连接。
操作步骤:

  1. 编辑 Kamailio 配置文件(通常为 /etc/kamailio/kamailio.cfg)。
  2. 找到 loadmodule "db_mysql.so" 所在行,在其下方添加:
    modparam("db_mysql", "opt_ssl_mode", 1)
    
    示例:
    #!ifdef WITH_MYSQL
    loadmodule "db_mysql.so"
    modparam("db_mysql", "opt_ssl_mode", 1)
    #!endif
    
  3. 保存文件。
✅ 缓解 TLS 双重释放警告

在 TLS 模块配置区添加 modparam("tls", "tls_threads_mode", 1)

  1. 找到 # ----- tls params ----- 区域。
  2. 添加如下配置:
    modparam("tls", "tls_threads_mode", 1)
    
    完整示例:
    #!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 上下文,避免共享内存被错误释放。

五、验证与重启

  1. 检查配置文件语法

    kamailio -c -f /etc/kamailio/kamailio.cfg
    

    输出应为 config file ok,无错误。

  2. 重启 Kamailio

    systemctl restart kamailio
    
  3. 实时查看日志

    journalctl -u kamailio -f
    

    应不再出现 invalid curvefreeing already freed pointer 错误,Kamailio 正常 fork 子进程。

六、其他注意事项

  • 如果你的业务要求 MySQL 连接必须使用 SSL,请不要禁用 opt_ssl_mode,而应该升级 OpenSSL 库并统一 MySQL 服务器的椭圆曲线配置。例如在 MySQL 配置文件 my.cnf 中添加:
    [mysqld]
    ssl_cipher = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    
  • tls_threads_mode=1 对性能几乎无影响,建议长期保留。
  • 若禁用 SSL 后希望恢复加密连接,可将 opt_ssl_mode 设为 23(尝试 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 连接数据库),请参考第六节的补充说明进行调整。


如果对你有帮助,请点赞、收藏、关注,支持我分享更多优质内容。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐