openssl-3.0.3のRPMビルド
opensslは1系と3系があるようで、今まで1.1.1k とか 1.1.1oを使ってたけど、
3.0をいつでも導入できるようにしておきたいと思ったので、RPMビルドしてdnfでインストールできるようにした。
かなりハマりどころが多かったのでメモしておく。
ビルド環境
- OS : Rocky Linux 8
うまくいったときの手順
Specファイル作成
下記の通りspecファイルを作成
$ rpmdev-newspec openssl3
重要な点をコメントで記載している。
Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl3
Version: 3.0.3
Release: 1%{?dist}
License: Apache License v2.0
URL: https://www.openssl.org/
Source: https://www.openssl.org/source/%{name}-%{version}.tar.gz
BuildRequires: perl-IPC-Cmd, perl-Pod-Html
Requires: %{name}-libs
%description
The OpenSSL Project develops and maintains the OpenSSL software - a robust, commercial-grade, full-featured toolkit
for general-purpose cryptography and secure communication.
The project's technical decision making is managed by the OpenSSL Technical Committee (OTC)
and the project governance is managed by the OpenSSL Management Committee (OMC).
The project operates under formal Bylaws.
%package devel
Summary: A general purpose cryptography library with TLS implementation
Group: Development
%description devel
Files for development of applications which will use OpenSSL
%package libs
Summary: A general purpose cryptography library with TLS implementation
Group: Development/Libraries
%description libs
Libraries for openssl 3.0.3
%global debug_package %{nil}
# /usr/bin/openssl3 となるように prefixを設定
%global prefix /usr
# opensslのインストールディレクトリは/usr/local/sslとする
%global openssldir /usr/local/ssl
# そのままだとディレクトリが存在しないといわれるので、-n で名前指定
%prep
%setup -n openssl-%{version}
%build
# NOTES-UNIX.md の内容に沿った configure オプションは↓の通り
./Configure --prefix=%{prefix} --openssldir=%{openssldir} '-Wl,-rpath,$(LIBRPATH)'
%make_build
%install
%make_install
# /usr/bin , /usr/lib64 を配置
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_libdir}
# opensslの実行バイナリをリネーム (そのままだとデフォルトのopenssl(1.1~)と競合するため)
mv %{buildroot}%{_bindir}/openssl %{buildroot}%{_bindir}/%{name}
%clean
rm -rf $RPM_BUILD_ROOT
# libssl.so.1 や libcrypto.so.1 などはいらないため、パッケージに含めなくてもエラーが出ないようにする。
%define _unpackaged_files_terminate_build 0
%files
%doc doc/
%{_bindir}/openssl3
%{prefix}/share/man/man1
%{prefix}/share/man/man5
%{prefix}/share/man/man7
%{prefix}/share/doc/openssl/html/man1/*
%{prefix}/share/doc/openssl/html/man5/*
%{prefix}/share/doc/openssl/html/man7/*
%{openssldir}/openssl.cnf*
%{openssldir}/ct*
%{openssldir}/misc/*
%files devel
%{prefix}/include
%{prefix}/share/man/man3
%{prefix}/share/doc/openssl/html/man3/*
%files libs
%{_libdir}/engines-3
%{_libdir}/libssl.so.3
%{_libdir}/libcrypto.so.3
%{_libdir}/ossl-modules
%post
%{_sysbindir}/ldconfig
%postun
%{_sysbindir}/ldconfig
%changelog
* Mon Jun 13 2022 cokemaniaIIDX
- Version3.0 の最初のリリース
rpmbuild実行
# rpmbuild -ba openssl3.spec
完了までだいたい8分くらいかかる(man3 のページ数が異常に多い)。
インストールできるか確認
RPMS/x86_64
にopenssl3-3.0.3-1.el8.x86_64.rpm
ができているので、これを指定してdnf installを試みる。
openssl3-3.0.3をインストールする際に、libssl.so.3 , libcrypto.so.3がないとインストールできないと言われるので、
先にopenssl3-libs-3.0.3
をインストールする。
# dnf install openssl3-libs-3.0.3-1.el8.x86_64.rpm -y
# dnf install openssl3-3.0.3-1.el8.x86_64.rpm
Last metadata expiration check: 1:12:43 ago on Wed Jun 15 05:10:47 2022.
Dependencies resolved.
============================================================================================
Package Architecture Version Repository Size
============================================================================================
Installing:
openssl3 x86_64 3.0.3-1.el8 @commandline 5.0 M
Transaction Summary
============================================================================================
Install 1 Package
Total size: 5.0 M
Installed size: 22 M
Is this ok [y/N]: y
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : openssl3-3.0.3-1.el8.x86_641/1
Running scriptlet: openssl3-3.0.3-1.el8.x86_641/1
/var/tmp/rpm-tmp.u49moA: line 1: fg: no job control
warning: %post(openssl3-3.0.3-1.el8.x86_64) scriptlet failed, exit status 1
Error in POSTIN scriptlet in rpm package openssl3
Verifying : openssl3-3.0.3-1.el8.x86_641/1
Installed:
openssl3-3.0.3-1.el8.x86_64
Complete!
無事インストールできた!
確認
- version確認
[root@7e73e7d8486c x86_64]# openssl3 version
OpenSSL 3.0.3 3 May 2022 (Library: OpenSSL 3.0.3 3 May 2022)
[root@7e73e7d8486c x86_64]# openssl version
OpenSSL 1.1.1k FIPS 25 Mar 2021
3と1がちゃんと共存している。
- opensslコマンド確認
LetsEncryptで発行しているTLS証明書をopensslコマンドを使って情報表示できるか確認
# openssl3 x509 -noout -dates -in CERTS/fullchain2.pem
notBefore=May 21 10:19:47 2022 GMT
notAfter=Aug 19 10:19:46 2022 GMT
ちゃんと確認できた!
ハマったところ
インストール時にコンフリクトが発生してしまう
現環境(RockyLinux8)ではopenssl-1.1.1kがデフォルトでインストールされていて、
共有ライブラリのopenssl-libs-1.1.1kも同様にインストールされている。
opensslという名前でビルドすると、
dnfでインストールするときに、既にインストールされている1.1.1kのものを上書きしようとして(? 挙動の詳細はよくわかってない)、
インストールできなくなってしまう。
解決策としては、パッケージの名前をopensslではなく、openssl3
としてビルドする。
opensslはopensslだけど別物としてインストールすればコンフリクトは回避できるよねという理屈
実際、dnf search opensslすると、
Rocky8ではepelで提供されているopensslとopenssl3の2つがヒットする。
dnf install openssl3 で、openssl-1.1.1がインストールされている状態でも、
openssl3がインストールできる。
epelを見習って、openssl3という名前で再ビルドしたところ、うまくいった。
fedoraの場合
fedoraはLinuxディストリビューションの中でも「最新性」を追及しているみたい。
実際、fedoraの最新版(37)コンテナをpullしてみて、opensslのインストールを試みると、
デフォルトでopenssl3.0.3がインストールできることが分かった!
$ docker run -it fedora:37
[root@7b36009b31bc /]#
[root@7b36009b31bc /]# dnf install openssl
Last metadata expiration check: 0:00:36 ago on Wed Jun 15 05:45:11 2022.
Dependencies resolved.
=============================================================================
Package Architecture Version Repository Size
=============================================================================
Installing:
openssl x86_64 1:3.0.3-1.fc37 rawhide 1.1 M
Upgrading:
openssl-libs x86_64 1:3.0.3-1.fc37 rawhide 2.1 M
Transaction Summary
=============================================================================
Install 1 Package
Upgrade 1 Package
Total download size: 3.3 M
Is this ok [y/N]:
この場合、opensslがデフォルトで3.0以上なので、
opensslの名前でビルドしたパッケージでも問題なくインストールできた。
libssl.so.1.1 を必要とされてしまう
openssl-libsは、様々なパッケージに参照されているようで、
このパッケージは容易にアップデートや変更、ましてや削除なんかはできないものである。
mysqlやpython、nginxなどもソースからビルドする際は--openssl=
でopensslを指定して
./Configureを実行することからも、この事実は明白。
先述のハマりポイントと関連して、CentOS7やRockyLinux8など、
openssl-1.1 がデフォルトのディストリビューションの場合、
openssl-libs-1.1がデフォルトで入っているため、
共有ライブラリにはopenssl-libs-1.1の中身が格納されている。
多くのパッケージはこのopenssl-libs-1.1のライブラリを参照しているため、
ビルドしたopenssl(3.0.3)をインストールしようとすると、
libssl.so.1 が必要とされていますが、どのパッケージからもインストールできません。
と言われてしまう。
こちらの問題も、やはりパッケージ名がopensslのため、
共有ライブラリのlibssl.so等が置き換わってしまって、
インストール済みのほかのパッケージに影響を及ぼしてしまうから、
インストールができなくなっていると推察できる。
解決策としては、やはり名前をopenssl3としてビルドを実行する。
これでopensslのライブラリ群も、openssl3-libsとしてインストールされるため、
競合が発生しなくなる。
rpmビルド実行時に、openssl-1.1と同じファイルをインストールできるけど、
これらも競合の発生を防ぐため、パッケージは含めないようにした。
↓このへん
warning: Installed (but unpackaged) file(s) found:
/usr/bin/c_rehash
/usr/lib64/libcrypto.a
/usr/lib64/libcrypto.so
/usr/lib64/libssl.a
/usr/lib64/libssl.so
/usr/lib64/pkgconfig/libcrypto.pc
/usr/lib64/pkgconfig/libssl.pc
/usr/lib64/pkgconfig/openssl.pc
これに関しては、epelのリポジトリのopenssl3のrpmパッケージの中身を参考にした。
# rpm -ql openssl3-libs-3.0.1-1.el8.x86_64.rpm
/usr/lib/.build-id
/usr/lib64/engines-3
/usr/lib64/libcrypto.so.3
/usr/lib64/libssl.so.3
/usr/lib64/ossl-modules
/usr/lib64/ossl-modules/legacy.so
↑こんなかに入ってないし、OKでしょう。
おわりに
rpmbuild初心者ながら、opensslの最新版rpmパッケージの作成に成功した。
いろいろなパッケージがopensslのライブラリを利用しているため、競合が多く
ビルドの難易度は非常に高かったが、何とか完成まで持っていけて良かった。
課題点:
実は、epelのrpmのようにdnf install openssl3
を実行した際に依存関係としてopenssl3-libsもインストールされるようにしたかったが、
やり方がわからず、、
SPECファイルの書き方が悪く、Requireでは無理なのか?
もしくは、yumリポジトリに両方入れておけば、リポジトリ参照してインストールする際に一緒にインストールしてくれるのだろうか、、
この辺りは、この後yumリポジトリサーバを自作するので、そこに格納してみて挙動を確かめてみる。
参考資料
-
- RPMパッケージ作成のノウハウはここにすべて書いてある。
-
philyuchkoff/openssl-RPM-Builder
- philyuchkoffさんのRPMビルダーのリポジトリ。非常に参考になりました。
-
RPM build errors: Empty %files file debugsourcefiles.list への対応
- debuginfoがバグって作成できなかった際の治し方。