手动降级openssl:解决-Rails-部署的问题
简介
1、为什么要降 openssl 版本?
我的工程比较老,使用的还是 rails 3.2
、ruby 1.8
(自己源码编译的),生产环境的应用服务器是 passenger
。在安装 passenger
时发生了错误(passenger-install-nginx-module 的安装方式):提示需要 ruby
支持 openssl
。
1 | ossl_pkey_ec.c:815: error: ‘EC_GROUP_new_curve_GF2m’ undeclared (first use in this function) |
后面我查询了下面两篇文章,折腾了很久未能解决问题,最后无奈降级系统自带的 openssl
版本。
当前云服务器的系统是 centOS 6.10
,默认安装了 openssl 1.0.x
版本,我需要在 ruby-1.8
环境下使用 openssl 0.9.8
系列版本。
2、我还尝试编译 ruby 源码中自带的 openssl
1 | cd ruby-1.8.7/ext/openssl |
报错:
=== OpenSSL for Ruby configurator ===
=== Checking for system dependent stuff… ===
checking for t_open() in -lnsl… no
checking for socket() in -lsocket… no
checking for assert.h… yes
=== Checking for required stuff… ===
checking for openssl/ssl.h… no
=== Checking for required stuff failed. ===
Makefile wasn’t created. Fix the errors above.
系统自带的 openssl
版本(OpenSSL 1.0.1e-fips 11 Feb 2013)和 ruby
版本去编译 openssl
扩展库不兼容,无法通过编译。
可以通过下面命令查看 openssl
版本:
1 | openssl version |
下面我们正式进入战斗。
安装低版本 openssl
1、下载 openssl-0.9.8
1 | cd /usr/local |
2、编译
1 | ./config --prefix=/usr/local/ssl -fPIC no-asm |
正常情况下,我们配置一下默认安装路径即可,但是这里我们加了两个参数 -fPIC
、 no-asm
。
用
no-asm
是为了解决类似 “md5-x86_64.s:41: Error: 0xd76aa478 out range of signed 32bit displacement” 的报错。用
-fPIC
是为了解决类似 “/usr/local/ssl/lib/libssl.a: error adding symbols: Bad value” 的报错。
如果你使用 ./config --prefix=/usr/local/ssl
能够编译、安装正常就不需要加这两个参数。如果报错了,请先执行 make clean
操作。
1 | 我们都知道在生成一个动态库时需要指定 -fPIC,这是创建动态库所要求的,共享库被加载是在内存中的位置是不固定的,是一个相对的位置。 |
编译如果报找不到库的错误,请安装 libssl
1 | yum install libssl-dev |
3、备份之前 OpenSSL 版本的文件,以方便恢复
1 | mv -f /usr/bin/openssl /usr/bin/openssl.old |
4、增加软链,指向新版本的 OpenSSL 路径
1 | ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl |
5、写入 ld 配置文件ld.so.conf
1 | echo "/usr/local/ssl/lib">>/etc/ld.so.conf |
可以看下 vim /etc/ld.so.conf
文件内容。
6、添加 so 库的路径,添加完成之后,运行ldconfig
,将新增的 so 文件缓存到/etc/ld.so.cache
中。
1 | ldconfig -v |
最后,确认版本是否正确。
1 | openssl version -a |
OpenSSL 0.9.8e 23 Feb 2007
built on: Thu Jan 5 11:13:28 CST 2023
platform: linux-x86_64
检查一下,ruby
是否带 openssl
模块:
1 | ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION' |
理论上还不行,别着急,接下来我们重新编译 ruby。
编译 ruby+openssl
编译 ruby
+ openssl
模块:
1 | cd /usr/local/ruby-1.8.7 |
(可选操作)如果还是编译报错,可以尝试用下面这种方式进行修复:
1 | ruby 源码自带了 openssl 库,当然还有其他扩展库如 zlib |
编译完成之后,也是修复成功了。如果这一步你还是无法通过编译,先放弃这个操作,直接看下面的内容去检测一下。
检测一下编译后的 ruby
是否带 openssl
模块,使用如下命令。
1 | 检查 openssl zlib |
在控制台会输出对应的信息就代表成功了。如果没有成功会报类似如下的错误:
ruby: no such file to load – openssl (LoadError)
上面能够成功,我也觉得很神奇,不管怎么样我遇到的问题算是解决了。后来我在 官网 doc 上面找到了一些解释。
module OpenSSL
OpenSSL
(指的是 ruby 自带的 openssl) providesSSL
, TLS and general purpose cryptography. It wraps the OpenSSL (指的是系统的 openssl 库) library.Install
OpenSSL
comes bundled with the Standard Library of Ruby.This means the
OpenSSL
extension is compiled with Ruby and packaged on build. During compile time, Ruby will need to link against theOpenSSL
library on your system. However, you cannot use openssl provided by Apple to build standard library openssl.If you use OSX, you should install another openssl and run “
./configure –with-openssl-dir=/path/to/another-openssl“
. For Homebrew user, runbrew install openssl
and then “./configure –with-openssl-dir=
brew –prefix openssl“
.
最后,自己重新编译 passenger
,工程可以正常运行了。
~~
当你遇到问题的时候,不要慌张,试着让自己放下问题出去走一走,回过头再来看或许问题就引刃而解了。