Closed5

古いRubyを使うためOpenSSL 1.1.1をXubuntu 22.04に入れる

ピン留めされたアイテム
zundazunda

rbenvにOpenSSL 1.1を入れてもらう

ruby-build 20220710からrbenvがOpenSSL 1.1を入れてくれるようになったようです。これで下記の作業は必要なくなりそう。

$ cd ~/.rbenv/plugins/ruby-build/
$ git pull
$ rbenv install 3.0.2
Downloading openssl-1.1.1q.tar.gz...
  :
zundazunda

OpenSSL 1.1.1をインストールする

https://www.openssl.org/source/ より、メンテナンス用のユーザーとして作業する

ダウンロード。電子署名の検証に使ったsqコマンドについてはこちら

$ mkdir -p ~/c/src/local/packages
$ cd ~/c/src/local/packages
$ curl -sO https://www.openssl.org/source/openssl-1.1.1o.tar.gz 
$ curl -sO https://www.openssl.org/source/openssl-1.1.1o.tar.gz.asc
$ curl -sO https://keys.openpgp.org/vks/v1/by-fingerprint/8657ABB260F056B1E5190839D9C4D26D0E604491
$ sq verify --signer-cert 8657ABB260F056B1E5190839D9C4D26D0E604491 --detached openssl-1.1.1o.tar.gz.asc openssl-1.1.1o.tar.gz
Good signature from D9C4D26D0E604491
1 good signature.

展開、設定、ビルド、テスト

$ tar zvxf packages/openssl-1.1.1o.tar.gz 
$ cd openssl-1.1.1o/
$ ./config --prefix=/opt/openssl-1.1.1
$ make
$ make test

インストール

$ sudo make install

システムのルートCAストアを利用する (詳細は下記)

$ sudo mv /opt/openssl-1.1.1/ssl/certs /opt/openssl-1.1.1/ssl/certs.installed
$ sudo ln -s /etc/ssl/certs /opt/openssl-1.1.1/ssl/certs
zundazunda

rbenvでRubyをインストールする

3.1未満のRubyはXubuntu 22.04のOpenSSL 3ではビルドできない。

$ rbenv uninstall 3.0.4
$ rbenv install 3.0.4
  :
BUILD FAILED (Ubuntu 22.04 using ruby-build 20220412-1-g5c814ed)
  :
The Ruby openssl extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `apt-get install -y libssl-dev` to fetch missing dependencies.
  :

上記でインストールしたOpenSSL 1.1.1を利用する。

$ RUBY_CONFIGURE_OPTS='--with-openssl-dir=/opt/openssl-1.1.1' rbenv install 3.0.4

rbenvでインストールされたRubyを利用する

C拡張ライブラリがOpenSSL 1.1.1を利用している場合には、実行時に共有オブジェクトの位置を教えてあげる必要があるようです。

$ export LD_LIBRARY_PATH=/opt/openssl-1.1.1/lib:$LD_LIBRARY_PATH
$ bundle exec ruby …
zundazunda

この項は、インストールしたOpenSSLでシステムのルートCAストアを利用するようにすることで不要になりました。bundlerは証明書をピンしているのではなく提供されていない環境でも利用できるようにしているようです。

古いbundlerのピンしているルートCA証明書に新しいものを加える

bundle installが、rubygems.orgのSSL証明書を検証できずに止まりました。

$ rbenv install 2.6.6
$ rbenv local 2.6.6
$ bundle install --path=vendor/bundle
  :
Retrying fetcher due to error (2/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rubygems.org/.
  :

bundlerがルートCA証明書をピンしているようです。

$ for p in `find ~/.rbenv/versions/2.6.6/ -name *CA*`; do dirname $p; done | grep rubygems.org | sort -u
/home/zunda/.rbenv/versions/2.6.6/lib/ruby/2.6.0/bundler/ssl_certs/index.rubygems.org
/home/zunda/.rbenv/versions/2.6.6/lib/ruby/2.6.0/bundler/ssl_certs/rubygems.org
/home/zunda/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ssl_certs/index.rubygems.org
/home/zunda/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ssl_certs/rubygems.org

rubygems.orgのSSL証明書のルートはGlobalSign Root CA - R3のようです。

$ :| openssl s_client -connect rubygems.org:443 2>/dev/null
CONNECTED(00000003)
---
Certificate chain
 0 s:CN = rubygems.org
   i:C = BE, O = GlobalSign nv-sa, CN = GlobalSign Atlas R3 DV TLS CA 2022 Q1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jan 22 16:45:18 2022 GMT; NotAfter: Feb 23 16:45:17 2023 GMT
 1 s:C = BE, O = GlobalSign nv-sa, CN = GlobalSign Atlas R3 DV TLS CA 2022 Q1
   i:OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Oct 20 12:00:00 2021 GMT; NotAfter: Oct 20 00:00:00 2024 GMT
---
  :

システムの持ってるルート証明書をコピーしてきちゃおう。

$ for p in `find ~/.rbenv/versions/2.6.6/ -name *CA*`; do dirname $p; done | grep rubygems.org | sort -u | xargs -i cp /etc/ssl/certs/GlobalSign_Root_CA_-_R3.pem {}

これで、bundle installが完走するようになりました。

zundazunda

ルートCAの管理

opensslコマンド

./config --prefix=/opt/openssl-1.1.1で設定したopensslはそのままではシステムのルートCAを参照しない。

/opt/openssl-1.1.1/ssl/certs/にはファイルがない。Ubuntuが管理していると思われる/etc/ssl/certsにはUbuntuが管理しているルートCAが含まれているようだ。システムが管理しているopensslの参照先にもUbuntuが管理しているルートCAが含まれているようだ。少なくともISRG Root X1の提供元はca-certificatesのようだ。

$ LD_LIBRARY_PATH=/opt/openssl-1.1.1/lib:$LD_LIBRARY_PATH /opt/openssl-1.1.1/bin/openssl version -d
OPENSSLDIR: "/opt/openssl-1.1.1/ssl"
$ ls -l /opt/openssl-1.1.1/ssl/certs/ISRG_Root_X1.pem 
ls: cannot access '/opt/openssl-1.1.1/ssl/certs/ISRG_Root_X1.pem': No such file or directory
$ ls -l /etc/ssl/certs/ISRG_Root_X1.pem 
lrwxrwxrwx 1 root root 51 May 16  2021 /etc/ssl/certs/ISRG_Root_X1.pem -> /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt
$ openssl version -d
OPENSSLDIR: "/usr/lib/ssl"
$ ls -l /usr/lib/ssl/certs/ISRG_Root_X1.pem 
lrwxrwxrwx 1 root root 51 May 16  2021 /usr/lib/ssl/certs/ISRG_Root_X1.pem -> /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt
$ dpkg -S /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt 
ca-certificates: /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt

システムのopensslはLet's Encryptの証明書を検証できる。

$ :| openssl s_client -connect mastodon.zunda.ninja:443 > /dev/null
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = mastodon.zunda.ninja
verify return:1
DONE

この記事でインストールしたopensslはLet's Encryptの証明書を検証できない。

$ :| LD_LIBRARY_PATH=/opt/openssl-1.1.1/lib:$LD_LIBRARY_PATH /opt/openssl-1.1.1/bin/openssl s_client -connect mastodon.zunda.ninja:443 > /dev/null
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = mastodon.zunda.ninja
verify return:1
DONE

Ruby

$ ruby -ropen-uri -e "p URI.open('https://mastodon.zunda.ninja/')"
#<Tempfile:/tmp/open-uri20220625-7148-d4cj1t>
$ rbenv local 2.6.6
$ ruby -ropen-uri -e "p URI.open('https://mastodon.zunda.ninja/')"
Traceback (most recent call last):
  :
	 1: from /home/zunda/.rbenv/versions/2.6.6/lib/ruby/2.6.0/net/protocol.rb:44:in `ssl_socket_connect'
/home/zunda/.rbenv/versions/2.6.6/lib/ruby/2.6.0/net/protocol.rb:44:in `connect_nonblock': SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate) (OpenSSL::SSL::SSLError)

この記事でインストールしたopensslにシステムのルートCAを見せる

$ sudo mv /opt/openssl-1.1.1/ssl/certs /opt/openssl-1.1.1/ssl/certs.installed
$ sudo ln -s /etc/ssl/certs /opt/openssl-1.1.1/ssl/certs

これでこの記事でインストールしたopensslでもルートCAを参照することができるようになる。

$ :| LD_LIBRARY_PATH=/opt/openssl-1.1.1/lib:$LD_LIBRARY_PATH /opt/openssl-1.1.1/bin/openssl s_client -connect mastodon.zunda.ninja:443 > /dev/null
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = mastodon.zunda.ninja
verify return:1
DONE
$ rbenv local 2.6.6
$ ruby -ropen-uri -e "p URI.open('https://mastodon.zunda.ninja/')"
#<Tempfile:/tmp/open-uri20220625-7484-20nmko>
このスクラップは2023/10/08にクローズされました