リバースプロキシが使用しているcipher suiteの対処をした
ちゃんとしたSSL化をしてみる
今回の経緯と目的
現状としてGoogle Chrome等で検証を行ってみると、encrypt自体はされているものの状態として望ましくない感じっていうことが実はあった。
これに対応するためにオプションにOpenSSL 1.0.2で使用できるcipher suiteの指定をしてみたが、起動してもエラーとなって使えない状況となっていた。
そのためOpenSSL 1.1.1を使えるようにすることで、ここら辺を打開できるか試してみようっていう試み。
サーバの状態
現状として、使用しているサーバーはCentOS7で、CentOS7のOpenSSLはバージョンが古い(サポート期限なんてとっくに切れている)。
使用しているCentOSとOpenSSLのバージョンはこんな感じ。
OpenSSLのバージョンを調べると、2019年12月31日にサポート期限が切れているのがわかる。
$ cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) $ openssl version OpenSSL 1.0.2k-fips 26 Jan 2017
stoneをmakeするためにopenssl-develパッケージをインストールしていたけど、これも1.0.2となっている。
$ sudo yum info openssl-devel インストール済みパッケージ 名前 : openssl-devel アーキテクチャー : x86_64 エポック : 1 バージョン : 1.0.2k リリース : 21.el7_9 容量 : 3.1 M リポジトリー : installed 提供元リポジトリー : updates 要約 : Files for development of applications which will use OpenSSL URL : http://www.openssl.org/ ライセンス : OpenSSL 説明 : OpenSSL is a toolkit for supporting cryptography. The openssl-devel : package contains include files needed to develop applications which : support various cryptographic algorithms and protocols.
OpenSSL 1.1.1をインストール
適当に見た感じでは、OpenSSL 1.1.1では openssl-devel 1.0.2に含まれるヘッダーファイルが含まれているっぽい。
とはいえ、CentOS7にOpenSSL 1.1.1をインストールする場合はソースから行う必要があるみたいなので、システム全体じゃなくて作業用のユーザーのみ入れ替えを行う感じでインストールを行う。
リポジトリパスを追加すればyumとかのコマンドで行けたかもしれないけど、詳しくは見ていない。
参考 : とりあえずこの辺り
CentOS 7.6 にソースコードから OpenSSL 1.1.1c をインストールする - らくがきちょう
インストールが終わると、OpenSSL 1.1.1が使用可能になったことがわかる。
ただし、root等の別ユーザーやシステムとしてはOpenSSL 1.0.2を使用している状態となっている。
$ openssl version OpenSSL 1.1.1j 16 Feb 2021 $ sudo openssl version OpenSSL 1.0.2k-fips 26 Jan 2017
stoneのmakeやり直し
Makefile編集
stoneのMakefileを編集して、インストールしたOpenSSL 1.1.1をとりあえず使用するように変更する。
きれいな編集はしていないけど、編集内容はこんな感じ。
Makefile内に使用するopensslコマンドのパスを変更して、SSL_LIBSについてもlibディレクトリのパスを追加している。
linuxタグのオプションについては不要かと思ったけど、「-D_GNU_SOURCE」を追加している。
23c23 < < SSL= /usr/local/ssl --- > SSL= /usr/local/openssl/bin/ 26c27 < SSL_LIBS= -lssl -lcrypto --- > SSL_LIBS= -L/usr/local/openssl/lib/ -lssl -lcrypto 99c100 < $(MAKE) FLAGS="-O -Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_EPOLL $(FLAGS)" LIBS="-lpthread $(LIBS)" stone --- > $(MAKE) FLAGS="-O -Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 $(SSL_FLAGS) -DUSE_EPOLL -D_GNU_SOURCE $(FLAGS)" LIBS="-lpthread $(LIBS)" stone
stone.c編集
stone.cについてもOpenSSL 1.1.1を使用するために修正が必要となる。
ここにある通り、stone.c内のSSL_state()をSSL_get_state()に置き換えを行う。
make実行
makeを行うと、OpenSSL 1.0.2からOpenSSL 1.1.1を使用することに変更したために以下のような警告が発生する。 とりあえず警告自体は無視することにした。
makeを実行する前にOpenSSL 1.1.1のための環境変数も設定する。
$ export C_INCLUDE_PATH=/usr/local/openssl/include/ $ make linux-ssl make TARGET=linux ssl_stone LIBS="-ldl" make[1]: ディレクトリ `/Local/stone' に入ります make FLAGS="-DUSE_POP -DUSE_SSL -DCONST_SSL_METHOD -DOPENSSL_NO_TLS1 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 " LIBS="-ldl -L/usr/local/openssl/lib/ -lssl -lcrypto" linux make[2]: ディレクトリ `/Local/stone' に入ります make FLAGS="-O -Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_SSL -DCONST_SSL_METHOD -DOPENSSL_NO_TLS1 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DUSE_EPOLL -D_GNU_SOURCE -DUSE_POP -DUSE_SSL -DCONST_SSL_METHOD -DOPENSSL_NO_TLS1 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 " LIBS="-lpthread -ldl -L/usr/local/openssl/lib/ -lssl -lcrypto" stone make[3]: ディレクトリ `/Local/stone' に入ります cc -D_GNU_SOURCE -O -Wall -DCPP='"/usr/bin/cpp -traditional"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_SSL -DCONST_SSL_METHOD -DOPENSSL_NO_TLS1 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -DUSE_EPOLL -D_GNU_SOURCE -DUSE_POP -DUSE_SSL -DCONST_SSL_METHOD -DOPENSSL_NO_TLS1 -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3 -o stone stone.c -lpthread -ldl -L/usr/local/openssl/lib/ -lssl -lcrypto stone.c: 関数 ‘asyncHealthCheck’ 内: stone.c:2087:5: 警告: ‘ERR_remove_state’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/err.h:261) [-Wdeprecated-declarations] ASYNC_END; ^ stone.c: 関数 ‘asyncConn’ 内: stone.c:4228:5: 警告: ‘ERR_remove_state’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/err.h:261) [-Wdeprecated-declarations] ASYNC_END; ^ stone.c: 関数 ‘asyncAcceptConnect’ 内: stone.c:7123:5: 警告: ‘ERR_remove_state’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/err.h:261) [-Wdeprecated-declarations] ASYNC_END; ^ stone.c: 関数 ‘repeater’ 内: stone.c:8067:5: 警告: ‘ERR_remove_state’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/err.h:261) [-Wdeprecated-declarations] ERR_remove_state(0); ^ stone.c: 関数 ‘sslopts’ 内: stone.c:9355:2: 警告: ‘TLSv1_2_server_method’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/ssl.h:1890) [-Wdeprecated-declarations] if (isserver) opts->meth = TLSv1_2_server_method(); ^ stone.c:9356:2: 警告: ‘TLSv1_2_client_method’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/ssl.h:1891) [-Wdeprecated-declarations] else opts->meth = TLSv1_2_client_method(); ^ stone.c:9360:2: 警告: ‘TLSv1_1_server_method’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/ssl.h:1884) [-Wdeprecated-declarations] if (isserver) opts->meth = TLSv1_1_server_method(); ^ stone.c:9361:2: 警告: ‘TLSv1_1_client_method’ は廃止されました (宣言位置 /usr/local/openssl/include/openssl/ssl.h:1885) [-Wdeprecated-declarations] else opts->meth = TLSv1_1_client_method(); ^ make[3]: ディレクトリ `/Local/stone' から出ます make[2]: ディレクトリ `/Local/stone' から出ます make[1]: ディレクトリ `/Local/stone' から出ます
makeしたstoneの確認
依存している共有ライブラリの確認
lddコマンドを使用してライブラリにopenssl1.1.1のものが含まれているかを確認。 以下の例だと「libssl.so.1.1」「libcrypto.so.1.1」がopenssl1.1.1のもの。
ldd ./stone linux-vdso.so.1 => (0x00007ffd6ed8c000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f95bfde1000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f95bfbdd000) libssl.so.1.1 => /usr/local/openssl/lib/libssl.so.1.1 (0x00007f95bf94b000) libcrypto.so.1.1 => /usr/local/openssl/lib/libcrypto.so.1.1 (0x00007f95bf45f000) libc.so.6 => /lib64/libc.so.6 (0x00007f95bf091000) /lib64/ld-linux-x86-64.so.2 (0x00007f95bfffd000) libz.so.1 => /lib64/libz.so.1 (0x00007f95bee7b000)
起動確認
新しいバイナリで同じようにリバースプロキシを立ち上げた場合に使用されるcipher suiteを確認。
こんな感じでConnectionの項目が変わっている。
ということで、TLS 1.2で怒られない感じのcipher suiteを使用したリバースプロキシの立ち上げにはこれで成功した感じ。
とはいえ、NginxとかApacheをおとなしく使うほうが導入の手間は少ないと思う。
Docker使えばすぐに立ち上がるしね。