来自Ruby on CentOS 6.6的“未初始化的常量OpenSSL :: PKey :: EC”

时间:2015-09-25 20:37:35

标签: ruby openssl centos jwt openid-connect

我有一个使用openid_connect gem的Rails服务器应用程序。当我尝试在CentOS 6.6上运行它时,我得到:

uninitialized constant OpenSSL::PKey::EC

这是完整的堆栈跟踪:

$ rails server
/home/foo/.rvm/gems/ruby-2.1.3/gems/json-jwt-1.5.1/lib/json/jwk/jwkizable.rb:69:in `<top (required)>': uninitialized constant OpenSSL::PKey::EC (NameError)
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/json-jwt-1.5.1/lib/json/jwt.rb:102:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object/id_token.rb:1:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object.rb:7:in `block in <top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object.rb:6:in `each'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/response_object.rb:6:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect/connect_object.rb:52:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/openid_connect-0.9.2/lib/openid_connect.rb:85:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:76:in `require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:72:in `each'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:72:in `block in require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:61:in `each'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler/runtime.rb:61:in `require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/bundler-1.10.6/lib/bundler.rb:134:in `require'
    from /home/foo/tmp/openid_connect_sample/config/application.rb:7:in `<top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:53:in `require'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:53:in `block in <top (required)>'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:50:in `tap'
    from /home/foo/.rvm/gems/ruby-2.1.3/gems/railties-3.2.22/lib/rails/commands.rb:50:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

这是什么意思,我怎么能超越它?

2 个答案:

答案 0 :(得分:3)

这个问题源于Red Hat拒绝在CentOS默认构建的OpenSSL中包含(出于专利诉讼的原因)某些椭圆曲线(EC)算法。

注意:根据@Cal's answer,CentOS 6.7没有此问题。

openid_connect gem取决于json-jwt gem,后者使用其中一种未包含的算法。

因此,您需要重建包含所需算法的新版OpenSSL。

以下是我遵循的步骤(改编自here)在我的机器上构建新的OpenSSL:

  1. cd /usr/src
  2. wget https://www.openssl.org/source/openssl-1.0.1l.tar.gz
  3. yum install autoconf automake(您可能已经安装了这些)
  4. tar zxvf openssl-1.0.1l.tar.gz
  5. cd openssl-1.0.1l
  6. export CFLAGS="-fPIC"
  7. ./config --prefix=/opt/openssl shared enable-ec enable-ecdh enable-ecdsa
  8. make all
  9. make install
  10. 现在,您的Ruby可能仍然与旧的OpenSSL库链接,因此您需要重建它以链接到新的。

    您使用的是rvm吗?那么太棒了!您安装的任何新Rubies都将针对新的OpenSSL构建。 rvm remove你的Ruby并重新安装它(或者只是安装一个不同的ruby版本)。

    不使用rvm然后我猜你需要以传统的方式重建Ruby。但你可能已经知道该怎么做了,对吧?如果没有,您需要查看其他教程,因为我们无法在此处介绍。

    现在重新安装bunder并执行bundle install,您的rails server现在应该成功运行。

    (如果有人提供更正或澄清,请发表评论,我会根据需要进行修改。)

答案 1 :(得分:1)

我遇到了与CentOS 6.6相同的问题。但我不想重新编译自定义openssl和ruby来解决这个问题。我没有采取很好的笔记,因为我尝试了很多东西,但似乎更新了所有最新的&amp; CentOS 6.7的最佳软件包解决了这个问题。

以下是我的一些相关软件包版本:

openssl098e-0.9.8e-18.el6_5.2.x86_64                                                            
openssl-1.0.1e-42.el6.x86_64                                                                
openssl-1.0.1e-42.el6.i686
openssl-devel-1.0.1e-42.el6.x86_64
glibc-2.12-1.166.el6_7.3.x86_64
kernel-2.6.32-573.7.1.el6.x86_64

更新这些软件包,重新启动并重新安装我的软件包之后,json-jwt gem工作得很好。

这是我们的生产机器,我相信ruby标准库是从源代码编译的,然后创建为自定义RPM。

我们的构建服务器使用RVM,这最终变得更加痛苦。 RVM安装程序一直在为二进制文件提取二进制文件,同样的失败再次出现。

Found remote file https://rvm.io/binaries/centos/6/x86_64/ruby-1.9.3-p484.tar.bz2

我强制执行这样的源重新编译:

rvm reinstall --disable-binary ruby-1.9.3-p484

我注意到一条非常精彩的信息:

 #applying patch .rvm/patches/ruby/ssl_no_ec2m.patch.

该补丁文件有一些C宏条件似乎排除了一些与EC相关的代码。

这很有效!我还注意到ruby的openssl.so中有很多与EC相关的符号。之前打包的centos ruby​​ 有这些:

$ cd ~/.rvm/rubies/ruby-1.9.3-p484/lib/ruby/1.9.1/x86_64-linux
$ strings openssl.so |grep _EC
PEM_write_bio_ECPKParameters
i2d_ECPKParameters
PEM_read_bio_ECPKParameters
d2i_ECPKParameters
PEM_write_bio_ECPrivateKey
i2d_ECPrivateKey_bio
i2d_EC_PUBKEY_bio
PEM_write_bio_EC_PUBKEY
PEM_read_bio_ECPrivateKey
PEM_read_bio_EC_PUBKEY
d2i_ECPrivateKey_bio
d2i_EC_PUBKEY_bio
OPENSSL_1.0.1_EC
EVP_PKEY_assign_EC_KEY
OP_SINGLE_ECDH_USE

如果我不得不猜测,重新编译我的新openssl 1.0.1包必须触发一些C宏,这些宏打开了某种不受法律保护的替代算法。

如果你检查你的openssl.so是否符号,并且它没有所有这些与_EC相关的东西,那可能是个问题。