OpenSSL与Net::SIP::SocketPool不兼容全版本SSL/TLS问题咨询
问题根因
新版OpenSSL(1.1.0及以上版本)默认将TLS1.0、TLS1.1等旧版协议标记为不安全,默认最低允许的TLS版本为TLS1.2,同时默认安全级别禁止使用旧协议对应的弱加密套件,不管是openssl命令行工具,还是依赖系统OpenSSL的Perl Net::SIP模块(底层调用IO::Socket::SSL),都会默认继承这个安全策略,所以才会出现ssl_choose_client_version:unsupported protocol报错。你手动加-tls1参数本质就是临时指定允许使用TLS1.0协议,绕过了默认限制。
解决方法
方法一:修改OpenSSL全局配置,默认兼容所有TLS版本
适用于需要全局所有依赖OpenSSL的程序都能访问旧版TLS服务的场景:
- 找到系统OpenSSL配置文件:Debian/Ubuntu系路径为
/etc/ssl/openssl.cnf,RHEL/CentOS/Fedora系路径为/etc/pki/tls/openssl.cnf - 编辑配置文件,找到
[openssl_init]配置段,添加如下配置:
[openssl_init] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] # 最低支持TLS1.0,如需兼容SSLv3可改成SSLv3 MinProtocol = TLSv1.0 CipherString = DEFAULT:@SECLEVEL=1
- 保存退出后,直接执行不带
-tls1参数的openssl s_client命令即可正常连接目标服务。
注意:全局降低OpenSSL安全级别存在安全风险,仅建议在隔离测试环境、或确认目标SIP服务无法升级TLS版本时使用。
方法二:不修改全局配置,单独为Net::SIP配置旧协议兼容(推荐)
不需要改动系统全局安全策略,直接在Net::SIP初始化的tls配置段传入IO::Socket::SSL的控制参数即可,仅对当前脚本生效:
修改你的Net::SIP初始化代码如下:
my $ua = Net::SIP::Simple->new( registrar => "sips:$host", domain => $host, from => $user, auth => [ $user,$pass ], tls => { SSL_fingerprint => "E6:6C:16:52:59:3F:9B:D2:7A:A4:4C:4A:FE:DE:12:75:30:2E:9E:A0", # 指定允许协商的TLS版本,写TLSv1_23代表自动兼容从TLS1.0开始的所有版本 SSL_version => 'TLSv1_23', # 降低安全级别,允许旧版协议对应的加密套件 SSL_cipher_list => 'DEFAULT:@SECLEVEL=1', } );
如果明确知道目标服务只支持TLS1.0,可以把
SSL_version的值直接改成TLSv1,握手速度会更快。
修改完成后重新运行脚本,Net::SIP::SocketPool就可以正常完成TLS握手,不会再报协议不支持的错误。
内容的提问来源于stack exchange,提问作者mohammedt moahsici
相关产品推荐
相关产品推荐

