
本番環境、テスト環境両方ともdnf、yumでパッケージインストールだけで済めば良いのですが、そうでない場合がありますよね?
良くあるパターンとしては、PHPはパッケージでインストールしたOpenSSLを使用して、ApacheだけソースコードからビルドしてインストールしたOpenSSLを使いたい場合です。
PHPは外部にさらすわけではないので、ローカルのOpenSSLにリンクさせ、外部に解放するApacheは最新のOpenSSLにリンクさせたいってニーズがあるかと思います。
よくLD_LIBRARY_PATHやld.so.confにライブラリの検索パスを定義して解決する手法を見ますが、これをやってしまうとシステム全体に影響が出てしまい、ある意味PHPとApacheの住み分けができなくなってしまいます。
そこで理想的な解決手段として取り得るのが、実行バイナリにシェアードライブラリの検索パスを埋め込み、実行時にシェアードライブラリを探しに行くパスを指定してしまうことです。この手法を用いるとPHP用のOpenSSL、Apache用のOpenSSLと言った複数バージョンのOpenSSLを使い分けることが可能となります。ただし、ハードルが少し高く、PHP、Apache両方ともソースコードからビルドする必要があります。
なぜかというと、検索パスの指定、実行バイナリへの埋め込みはバイナリを生成するコンパイル時にしかできないからです。それでは、実際の例を見ていきましょう。
PHPのインストール
周辺ライブラリのインストール
dnf config-manager --set-enabled powertools dnf install epel-release dnf install libtool \ gcc-c++ \ gcc-toolset-11-gcc-c++ dnf install wget \ tar \ gcc \ make \ zlib \ zlib-devel \ expat \ expat-devel \ libtool \ pcre \ pcre-devel -y dnf install readline \ readline-devel -y dnf install autoconf \ uw-imap \ uw-imap-devel \ libzip \ libzip-devel \ zlib \ zlib-devel \ curl \ libcurl \ libcurl-devel \ libssh \ libssh-config \ libssh-devel \ gd \ gd-devel \ libpng \ libpng-devel \ freetype \ freetype-devel \ fontconfig \ fontconfig-devel \ libjpeg-turbo \ libjpeg-turbo-devel \ libXpm \ libXpm-devel \ libtiff \ libtiff-devel \ libxslt \ libxslt-devel \ re2c \ libxml2 \ libxml2-devel \ libwebp \ libwebp-devel \ oniguruma \ oniguruma-devel \ sqlite-devel
wget https://imagemagick.org/archive/ImageMagick.tar.gz tar xvfz ImageMagick.tar.gz cd ImageMagick-7.1.1-43 ./configure --prefix=/var/home/lib/imagic make all make install
PHPソースコードのダウンロード・展開
wget https://www.php.net/distributions/php-8.1.31.tar.gz tar xvfz php-8.1.31.tar.gz
PHPコンパイル・インストール
./configure \ --prefix=/var/home/ap/php \ --enable-fpm \ --with-config-file-path=/var/home/ap/php/etc \ --enable-libgcc \ --with-openssl \ --with-zlib \ --with-zlib-dir=/usr \ --enable-gd \ --with-freetype \ --with-jpeg \ --with-xpm \ --with-webp \ --enable-bcmath \ --with-bz2 \ --enable-calendar \ --with-curl \ --enable-dba=shared \ --enable-exif \ --with-curl \ --enable-gd-jis-conv \ --with-gettext \ --enable-mbstring \ --with-mysqli=mysqlnd \ --with-pdo-mysql=mysqlnd \ --enable-pcntl \ --with-readline \ --enable-soap \ --enable-sockets \ --with-xsl \ --with-imap \ --with-imap-ssl \ --with-libdir=lib64 \ --with-kerberos \ --enable-opcache \ --enable-shared make all make install
各種拡張モジュールのインストール
wget https://pecl.php.net/get/apcu-5.1.22.tgz ※ https://pecl.php.net/package/APCu tar xvfz apcu-5.1.22.tgz cd apcu-5.1.22/ /var/home/ap/php/bin/phpize ./configure --enable-apcu --with-php-config=/var/home/ap/php/bin/php-config make all make install Installing shared extensions: /var/home/ap/php/lib/php/extensions/no-debug-non-zts-20210902/ Installing header files: /var/home/ap/php/include/php/
※https://pecl.php.net/package/imagick wget https://pecl.php.net/get/imagick-3.7.0.tgz tar xvfz imagick-3.7.0.tgz cd imagick-3.7.0 /var/home/ap/php/bin/phpize PKG_CONFIG_PATH=/var/home/lib/imagic/lib/pkgconfig/ \ ./configure --prefix=/var/home/ap/php/lib/php/extensions/no-debug-non-zts-20210902 --with-libdir=/var/home/lib/imagic/lib --with-php-config=/var/home/ap/php/bin/php-config make all cp modules/imagick.so /var/home/ap/php/lib/php/extensions/no-debug-non-zts-20210902/
シェアードライブラリのリンク先を確認する
cd /var/home/ap/php/bin ldd ./php linux-vdso.so.1 (0x00007ffe377dc000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fc6452ee000) libc-client.so.2007 => /lib64/libc-client.so.2007 (0x00007fc644fd8000) libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fc644dc0000) libreadline.so.7 => /lib64/libreadline.so.7 (0x00007fc644b71000) libncurses.so.6 => /lib64/libncurses.so.6 (0x00007fc644946000) libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007fc644719000) librt.so.1 => /lib64/librt.so.1 (0x00007fc644511000) libbz2.so.1 => /lib64/libbz2.so.1 (0x00007fc644300000) libutil.so.1 => /lib64/libutil.so.1 (0x00007fc6440fc000) libm.so.6 => /lib64/libm.so.6 (0x00007fc643d7a000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fc643b76000) libxml2.so.2 => /lib64/libxml2.so.2 (0x00007fc64380e000) libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fc6435b9000) libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fc6432ce000) libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fc6430b7000) libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fc642eb3000) libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007fc642c1e000) libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007fc642733000) libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x00007fc64241f000) libz.so.1 => /lib64/libz.so.1 (0x00007fc642207000) libcurl.so.4 => /lib64/libcurl.so.4 (0x00007fc641f78000) libpng16.so.16 => /lib64/libpng16.so.16 (0x00007fc641d43000) libwebp.so.7 => /lib64/libwebp.so.7 (0x00007fc641ad5000) libjpeg.so.62 => /lib64/libjpeg.so.62 (0x00007fc64186c000) libXpm.so.4 => /lib64/libXpm.so.4 (0x00007fc641659000) libX11.so.6 => /lib64/libX11.so.6 (0x00007fc641315000) libfreetype.so.6 => /lib64/libfreetype.so.6 (0x00007fc641059000) libonig.so.5 => /lib64/libonig.so.5 (0x00007fc640dd5000) libxslt.so.1 => /lib64/libxslt.so.1 (0x00007fc640b94000) libexslt.so.0 => /lib64/libexslt.so.0 (0x00007fc64097d000) libgcrypt.so.20 => /lib64/libgcrypt.so.20 (0x00007fc64065f000) libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007fc64043e000) libc.so.6 => /lib64/libc.so.6 (0x00007fc640068000) libpam.so.0 => /lib64/libpam.so.0 (0x00007fc63fe58000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc63fc38000) /lib64/ld-linux-x86-64.so.2 (0x00007fc645517000) liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fc63fa11000) libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fc63f800000) libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fc63f5fc000) libnghttp2.so.14 => /lib64/libnghttp2.so.14 (0x00007fc63f3d5000) libidn2.so.0 => /lib64/libidn2.so.0 (0x00007fc63f1b7000) libssh.so.4 => /lib64/libssh.so.4 (0x00007fc63ef47000) libpsl.so.5 => /lib64/libpsl.so.5 (0x00007fc63ed36000) libldap-2.4.so.2 => /lib64/libldap-2.4.so.2 (0x00007fc63eae7000) liblber-2.4.so.2 => /lib64/liblber-2.4.so.2 (0x00007fc63e8d7000) libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007fc63e6ca000) libxcb.so.1 => /lib64/libxcb.so.1 (0x00007fc63e4a1000) libaudit.so.1 => /lib64/libaudit.so.1 (0x00007fc63e270000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fc63e045000) libunistring.so.2 => /lib64/libunistring.so.2 (0x00007fc63dcc4000) libsasl2.so.3 => /lib64/libsasl2.so.3 (0x00007fc63daa6000) libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007fc63d885000) libXau.so.6 => /lib64/libXau.so.6 (0x00007fc63d681000) libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007fc63d47b000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007fc63d1f7000)
上記、リンクの情報を見ていただければ、パッケージでインストールしたOpenSSLにリンクしていることが確認できます。
それでは、続いてソースコードからインストールしたOpenSSLにリンクするApacheのインストールを行ってみましょう。
注)OpenSSL3.3.2が/var/home/lib/opensslにインストールされていることを前提とします。
Apacheのインストール
周辺ライブラリのインストール
dnf install jansson \ jansson-devel \ wget \ tar \ gcc \ make \ zlib \ zlib-devel \ expat \ expat-devel \ libtool \ pcre \ pcre-devel -y
wget https://dlcdn.apache.org//apr/apr-1.7.4.tar.gz tar xvfz apr-1.7.4.tar.gz cd apr-1.7.4 ./configure \ --prefix=/var/home/lib/apr \ --enable-shared \ --enable-threads \ --enable-posix-shm make all make install mv /var/home/lib/apr /var/home/lib/apr1.7.4 ln -s /var/home/lib/apr1.7.4 /var/home/lib/apr
wget https://dlcdn.apache.org//apr/apr-util-1.6.3.tar.gz tar xvfz apr-util-1.6.3.tar.gz cd apr-util-1.6.3 ./configure \ --prefix=/var/home/lib/apr-util \ --with-apr=/var/home/lib/apr/bin/apr-1-config make all make install mv /var/home/lib/apr-util /var/home/lib/apr-util1.6.3 ln -s /var/home/lib/apr-util1.6.3 /var/home/lib/apr-util
dnf install libxml2 libxml2-devel libev libev-devel jansson jansson-devel c-ares c-ares-devel wget https://github.com/nghttp2/nghttp2/releases/download/v1.62.1/nghttp2-1.62.1.tar.gz tar xvfz nghttp2-1.62.1.tar.gz cd nghttp2-1.62.1 ./configure --prefix=/var/home/lib/nghttp2 \ --enable-lib-only gmake (約3分かかる) gmake install mv /var/home/lib/nghttp2 /var/home/lib/nghttp2-1.62.1 ln -s /var/home/lib/nghttp2-1.62.1 /var/home/lib/nghttp2
Apacheソースコードのダウンロード・展開
wget https://dlcdn.apache.org/httpd/httpd-2.4.62.tar.gz tar xvfz httpd-2.4.62.tar.gz
Apacheコンパイル・インストール
LDFLAGSに-Wl,-rpathをセットすることでバイナリに検索パスを埋め込むことができます。
cd httpd-2.4.62 LDFLAGS="-Wl,-rpath=/var/home/lib/openssl/lib64" \ ./configure \ --prefix=/var/home/ap/apache \ --with-apr=/var/home/lib/apr \ --with-apr-util=/var/home/lib/apr-util \ --enable-ssl \ --enable-so \ --enable-mods-shared=all \ --enable-mpms-shared=all \ --with-ssl=/var/home/lib/openssl \ --with-nghttp2=/var/home/lib/nghttp2 LDFLAGS="-Wl,-rpath=/var/home/lib/openssl/lib64" \ make all LDFLAGS="-Wl,-rpath=/var/home/lib/openssl/lib64" \ make install mv /var/home/ap/apache /var/home/ap/apache2.4.62 ln -s /var/home/ap/apache2.4.62 /var/home/ap/apache
シェアードライブラリのリンク先を確認する
cd /var/home/ap/apache/modules ldd mod_ssl.so linux-vdso.so.1 (0x00007ffca9539000) libssl.so.3 => /var/home/lib/openssl/lib64/libssl.so.3 (0x00007f8a30190000) libcrypto.so.3 => /var/home/lib/openssl/lib64/libcrypto.so.3 (0x00007f8a2fa40000) libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f8a2f838000) librt.so.1 => /lib64/librt.so.1 (0x00007f8a2f630000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f8a2f407000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8a2f1e7000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f8a2efe3000) libc.so.6 => /lib64/libc.so.6 (0x00007f8a2ec0d000) libz.so.1 => /lib64/libz.so.1 (0x00007f8a2e9f5000) /lib64/ld-linux-x86-64.so.2 (0x00007f8a306cf000)
上記を参照いただければわかりますが、ソースコードからインストールしたOpenSSLにリンクしていることがわかります。
ちなみに下記コマンドでmod_ssl.soの中を見ると以下の結果が得られます。
readelf -d mod_ssl.so Dynamic section at offset 0x3ad10 contains 33 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libssl.so.3] 0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.3] 0x0000000000000001 (NEEDED) Shared library: [libuuid.so.1] 0x0000000000000001 (NEEDED) Shared library: [librt.so.1] 0x0000000000000001 (NEEDED) Shared library: [libcrypt.so.1] 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0] 0x0000000000000001 (NEEDED) Shared library: [libdl.so.2] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000000e (SONAME) Library soname: [mod_ssl.so] 0x000000000000000f (RPATH) Library rpath: [/var/home/lib/openssl/lib64] 0x000000000000000c (INIT) 0xb160 0x000000000000000d (FINI) 0x2b048 0x0000000000000019 (INIT_ARRAY) 0x239e30 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) 0x000000000000001a (FINI_ARRAY) 0x239e38 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) 0x000000006ffffef5 (GNU_HASH) 0x1f0 0x0000000000000005 (STRTAB) 0x3518 0x0000000000000006 (SYMTAB) 0x218 0x000000000000000a (STRSZ) 10185 (bytes) 0x000000000000000b (SYMENT) 24 (bytes) 0x0000000000000003 (PLTGOT) 0x23b000 0x0000000000000002 (PLTRELSZ) 12648 (bytes) 0x0000000000000014 (PLTREL) RELA 0x0000000000000017 (JMPREL) 0x7ff8 0x0000000000000007 (RELA) 0x6198 0x0000000000000008 (RELASZ) 7776 (bytes) 0x0000000000000009 (RELAENT) 24 (bytes) 0x000000006ffffffe (VERNEED) 0x6128 0x000000006fffffff (VERNEEDNUM) 3 0x000000006ffffff0 (VERSYM) 0x5ce2 0x000000006ffffff9 (RELACOUNT) 302 0x0000000000000000 (NULL) 0x0
mod_ssl.so内にLibrary rpathが定義されており、ソースコードからインストールしたOpenSSLのディレクトリを検索しに行くようパスが埋め込まれています。
このようにするとシステム上に複数バージョンのOpenSSLを同居させ、それぞれのアプリケーションから使い分けすることができるようになります。
以上となります。お疲れ様でした!