標準パッケージのApache httpdのmod_sslだけ入れ替えてTLS1.3に対応する


TLS1.3 使いたい(けど理由はない)

CentOS 7 系では、パッケージ管理されている Apache httpd が openssl 1.0.x 系だから TLS1.3 が使えない1……でも使いたい、理由はないけどなんとなく使いたい、という気持ちに応えるのが趣旨であります。

ググってみると、自分で build してみよう! という記事が多いですが、パッケージ管理されている httpd 用のパッケージが使えなくなってしまいます。

……とかなんとか理由をつけて、需要なさそうだけどとりあえず面白い気がしたのでやってみよう! といういつものパターンです。

流れ

TLS1.3 を使うには openssl 1.1.1 が必要です2。まだ 1.1.1 が入っている環境は少ないので、まずそれを作ります。それから mod_ssl を作る、という流れです。

  1. まず openssl のソースコードを入手して make する。他で使うこともあるかもしれないので make install もする
  2. パッケージ管理でインストールされたバージョン3と同じ httpd のソースコードを入手して make する。こちらは本体は使わないので install しない
  3. mod_ssl を抜き出して httpd のモジュール位置に置く
  4. mod_ssl 用の設定を加える

免責

楽しそうだから作っただけなので、ここで作ったものを本番環境で使うのはお勧めしません。すべて自己責任でお願いします。

openssl 1.1.1 を build する

build に必要なパッケージを入れる

はじめに gcc を入れる。何をするにも必要だしすでに入っている人も多いかと思いますが。

sudo yum install gcc

openssl のソースコード一式をダウンロードします。下のURLは、2020年12月9日現在の最新バージョン 1.1.1i へのURLになっています。

curl https://www.openssl.org/source/openssl-1.1.1i.tar.gz -O

バージョンの部分は、つねに最新のものに置き換えてください。

サクッと build してインストール。configure じゃないんだね。知らなかった。

tar zxvf openssl-1.1.1i.tar.gz
cd openssl-1.1.1i
./config
make
sudo make install_sw

インストールできたか確認する

オプションを指定しなかったら openssl 1.1.1 は /usr/local 以下にインストールされる。

ライブラリ

ライブラリは lib64 にあるはず。

$ ls -la /usr/local/lib64
total 11076
drwxr-xr-x  4 root root     204 Dec  9 21:27 ./
drwxr-xr-x 13 root root     142 Jan 21  2020 ../
drwxr-xr-x  2 root root      55 Dec  9 21:27 engines-1.1/
-rw-r--r--  1 root root 5630034 Dec  9 21:27 libcrypto.a
lrwxrwxrwx  1 root root      16 Dec  9 21:27 libcrypto.so -> libcrypto.so.1.1*
-rwxr-xr-x  1 root root 3334216 Dec  9 21:27 libcrypto.so.1.1*
-rw-r--r--  1 root root 1017776 Dec  9 21:27 libssl.a
lrwxrwxrwx  1 root root      13 Dec  9 21:27 libssl.so -> libssl.so.1.1*
-rwxr-xr-x  1 root root  672536 Dec  9 21:27 libssl.so.1.1*
drwxr-xr-x  2 root root      61 Jan 21  2020 pkgconfig/

/usr/local/lib64 が ld に設定されていないなら設定します。

(原理などはこちらの記事が詳しかった→ CentOS7でldconfigを使って共有ライブラリを追加する

echo "/usr/local/lib64" > usr.local.lib64.conf
sudo cp usr.local.lib64.conf /etc/ld.so.conf.d
sudo ldconfig

コマンドラインツール

コマンドラインツールは、その下の bin にあります。

$ /usr/local/bin/openssl version
OpenSSL 1.1.1i  8 Dec 2020

Apache httpd を build する

では次に mod_ssl を作ります。ほしいのは mod_ssl だけですが、まるっと httpd を build します。

ホンモノをいれる

パッケージの httpd が入っていないなら入れましょう。

sudo yum install httpd

必要なパッケージをいれる

httpd の build に必要なパッケージを入れます。

sudo yum install apr-devel apr-util-devel pcre-devel

build する

必要なのは mod_ssl だけなので、影響しなさそうなオプションは気にしない気にしない。

curl http://ftp.riken.jp/net/apache//httpd/httpd-2.4.46.tar.bz2 -O
tar jxvf httpd-2.4.46.tar.bz2
cd httpd-2.4.46
./configure --with-ssl=/usr/local/lib64
make

ちゃんと openssl 1.1.1 を呼んでいるかな

mod_ssl のヘッダを見てみます。

readelf -d modules/ssl/.libs/mod_ssl.so
Dynamic section at offset 0x48d48 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libssl.so.1.1]
 0x0000000000000001 (NEEDED)             Shared library: [libcrypto.so.1.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]
 0x000000000000000c (INIT)               0xa940
 0x000000000000000d (FINI)               0x3ade0
 0x0000000000000019 (INIT_ARRAY)         0x247df0
:
:

libssl.so.1.1 を呼んでいればよし、そうでなければ ldconfig がうまくいっていない可能性が高いので見直してみてください。

mod_ssl を設置、読み込むように設定

まず設置します。

sudo cp modules/ssl/.libs/mod_ssl.so /etc/httpd/modules/

cond/httpd.conf か、パッケージで導入したときと同じように conf.modules.d/00-ssl.conf を作るかして、以下の行を追加します。

LoadModule ssl_module modules/mod_ssl.so

ssl.conf を作る

ssl.conf も自分で作らないといけません。最低限必要な部分は詰め込んであるはずなので、あとはお好みでカスタマイズしてください。

conf.d/ssl.conf
Listen 443 https

SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin

SSLCryptoDevice builtin
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite !DSS:ECDSA+AESGCM:EECDH+AESGCM

起動

これであとは virtualhost の設定、SSLの鍵・証明書があれば動くはず!

sudo systemctl start httpd.service

確認

起動したら、たぶん大丈夫。ssllabs さんで確認します。

お、いけてますね。

openssl も 1.1.1X が使われていることがわかります。

まとめ

やってみたら意外と簡単でした。

楽しそうだから、という理由でやったので効果はあまり考えてないのですが、TLS1.3 では接続速度が改善されたそうです。あまり興味がないのでパフォーマンス検証はしていないのですが。

openssl のバージョンに関係なく、暗号化方式にRSAではなくECDSAを使うと接続速度が速くなりますが、OpenSSL 1.1.0 以降だとECDSAを含む楕円曲線暗号の処理が速くなったそうなので、必然的に 1.1.1 以降を使う TLS1.3 ではより効果が期待できそうです。

TLS1.3 を普通に使える日がはやくくるといいですね。


  1. Amazon Linux 2 も CentOS ベースなのでまだ openssl 1.0.2 なんすよね。 

  2. これが入ってるなら、こんな手間暇かかる作業は必要ないはず。 

  3. majorとminorがいっしょの、最新のものを使えばいけるんじゃないかなあと思ってます。