Common Lisp使用Drakma库访问安全站点报OpenSSL错误问题咨询
错误原因
Drakma本身不直接实现TLS协议逻辑,所有HTTPS请求会转交依赖库cl+ssl处理,cl+ssl通过CFFI调用系统层面的OpenSSL动态库完成加密握手,访问HTTP站点时不需要加载TLS相关依赖,因此不会触发异常。
两个连续报错的触发逻辑如下:
- 首先触发的
CFFI:LOAD-FOREIGN-LIBRARY-ERROR是根因:旧版本cl+ssl硬编码的OpenSSL库搜索列表仅包含libcrypto.so.1.1、libcrypto.so.1.0.0、通用软链接libcrypto.so三个目标,而2022年之后发布的主流Linux发行版默认预装OpenSSL 3.x,对应的动态库文件名为libcrypto.so.3,不在搜索范围内,cl+ssl找不到可加载的加密库就会抛出该错误。 - 后续的OpenSSL版本识别错误是连带异常:cl+ssl加载库失败后,会尝试调用OpenSSL导出的
SSLeay(旧版接口)、OpenSSL_version_num(新版接口)读取版本号,因为没有成功加载任何库文件,两个接口都无对应内存地址可调用,因此抛出版本探测失败的提示。
修复方案
按操作成本从低到高排序,可任选一种方案修复:
- 更新Quicklisp发行版到最新版
最新版cl+ssl已经在搜索列表中加入了OpenSSL 3.x对应的库文件名,优先执行以下命令更新Quicklisp所有包:
更新完成后重启Lisp环境,重新加载Drakma再测试HTTPS请求即可,多数新系统环境下该方案可直接解决问题,不需要额外修改配置。(ql:update-dist "quicklisp") - 手动指定OpenSSL库加载路径
如果更新后仍然报错,可先在系统终端执行ldconfig -p | grep libcrypto.so(Linux)、brew list openssl | grep libcrypto(macOS)查询本机已安装的libcrypto动态库实际路径,在加载Drakma前执行以下代码手动指定库目录,以Ubuntu 22.04的默认OpenSSL 3路径为例:
Windows环境可直接将对应版本的(push #p"/usr/lib/x86_64-linux-gnu/" cffi:*foreign-library-directories*) (cl+ssl:reload)libcrypto-1_1-x64.dll/libcrypto-3-x64.dll放到Lisp可执行文件所在目录,cl+ssl会自动识别加载。 - 安装兼容的OpenSSL 1.1运行库
如果当前cl+ssl版本过旧无法适配OpenSSL 3,可直接安装cl+ssl默认支持的OpenSSL 1.1版本,不会和系统默认的OpenSSL 3.x冲突,不同系统安装方式:- Debian/Ubuntu系:执行
sudo apt install libssl1.1,若官方源无该包可手动下载对应架构的deb包安装,不要替换系统自带的OpenSSL 3文件避免破坏系统依赖 - RHEL/Fedora系:执行
sudo dnf install openssl1.1 - Arch系:从AUR安装
openssl-1.1包 - macOS:执行
brew install openssl@1.1
安装完成后重启Lisp环境即可正常访问HTTPS站点。
- Debian/Ubuntu系:执行
内容的提问来源于stack exchange,提问作者Michael Erbaturakis
相关产品推荐
相关产品推荐

