降 openssl,解决了一个 Rails 部署的问题
1、为什么要降 openssl 版本?我的工程比较老,使用的还是rails 3.2ruby 1.8(自己源码编译的),生产环境的应用服务器是passenger。在安装passenger时发生了错误(passenger-install-nginx-module 的安装方式):提示需要ruby支持openssl。后面我查询了下面两篇文章,折腾了很久未能解决问题,最后无奈降级系统自带的openssl版本
简介
1、为什么要降 openssl 版本?
我的工程比较老,使用的还是 rails 3.2
、ruby 1.8
(自己源码编译的),生产环境的应用服务器是 passenger
。在安装 passenger
时发生了错误(passenger-install-nginx-module 的安装方式):提示需要 ruby
支持 openssl
。
ossl_pkey_ec.c:815: error: ‘EC_GROUP_new_curve_GF2m’ undeclared (first use in this function)
ossl_pkey_ec.c:815: error: (Each undeclared identifier is reported only once
ossl_pkey_ec.c:815: error: for each function it appears in.)
make[1]: *** [ossl_pkey_ec.o] Error 1
make[1]: Leaving directory `/home/vagrant/ruby-1.8.7-p357/ext/openssl'
make: *** [all] Error 1
后面我查询了下面两篇文章,折腾了很久未能解决问题,最后无奈降级系统自带的 openssl
版本。
-
https://www.cnblogs.com/grimm/p/5568129.html
当前云服务器的系统是 centOS 6.10
,默认安装了 openssl 1.0.x
版本,我需要在 ruby-1.8
环境下使用 openssl 0.9.8
系列版本。
2、我还尝试编译 ruby 源码中自带的 openssl
cd ruby-1.8.7/ext/openssl
ruby extconf.rb
报错:
=== 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
版本:
openssl version
下面我们正式进入战斗。
安装低版本 openssl
1、下载 openssl-0.9.8
cd /usr/local
wget https://www.openssl.org/source/openssl-0.9.8e.tar.gz --no-check-certificate
tar -zxvf openssl-0.9.8e.tar.gz
cd openssl-0.9.8e
2、编译
./config --prefix=/usr/local/ssl -fPIC no-asm
make
make install
正常情况下,我们配置一下默认安装路径即可,但是这里我们加了两个参数 -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
操作。
我们都知道在生成一个动态库时需要指定 -fPIC,这是创建动态库所要求的,共享库被加载是在内存中的位置是不固定的,是一个相对的位置。
那么在生成静态库时通常不指定 -fPIC, 可是在64bit编译使用静态库就会提示需要 -fPIC 重新编译该库。
由于 openssl 编译静态库时,没有使用 -fPIC 选项,使得编译出来的静态库没有重定位能力。
这样在 64bit 机器上编译出来的静态库如果不指定-fPIC选项几乎全部不能使用。
因此需要重新加上 -fPIC 从新编译 openssl。
编译如果报找不到库的错误,请安装 libssl
yum install libssl-dev
3、备份之前 OpenSSL 版本的文件,以方便恢复
mv -f /usr/bin/openssl /usr/bin/openssl.old
mv -f /usr/include/openssl /usr/include/openssl.old
4、增加软链,指向新版本的 OpenSSL 路径
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl
5、写入 ld 配置文件ld.so.conf
echo "/usr/local/ssl/lib">>/etc/ld.so.conf
可以看下 vim /etc/ld.so.conf
文件内容。
6、添加 so 库的路径,添加完成之后,运行ldconfig
,将新增的 so 文件缓存到/etc/ld.so.cache
中。
ldconfig -v
最后,确认版本是否正确。
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
模块:
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
理论上还不行,别着急,接下来我们重新编译 ruby。
编译 ruby+openssl
编译 ruby
+ openssl
模块:
cd /usr/local/ruby-1.8.7
# 我之前编译过
make clean
# --prefix 指定ruby安装目录
# --with-openssl-dir 指定openssl目录(刚安装的 openssl)
./configure --enable-pthread --prefix=/usr/local --with-openssl-dir=/usr/local/ssl
make
make install
(可选操作)如果还是编译报错,可以尝试用下面这种方式进行修复:
# ruby 源码自带了 openssl 库,当然还有其他扩展库如 zlib
cd /usr/local/ruby-1.8.7/ext/openssl
ruby extconf.rb
make && make install
编译完成之后,也是修复成功了。如果这一步你还是无法通过编译,先放弃这个操作,直接看下面的内容去检测一下。
检测一下编译后的 ruby
是否带 openssl
模块,使用如下命令。
# 检查 openssl zlib
ruby -ropenssl -rzlib -e "puts :success"
# 用下面的也可以
ruby -ropenssl -e "puts :success"
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
在控制台会输出对应的信息就代表成功了。如果没有成功会报类似如下的错误:
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
,工程可以正常运行了。
~~
当你遇到问题的时候,不要慌张,试着让自己放下问题出去走一走,回过头再来看或许问题就引刃而解了。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)