ねじまきまきまき -Random Note-

やったこと忘れないための雑記

リバースプロキシが使用しているcipher suiteの対処をした

ちゃんとしたSSL化をしてみる

今回の経緯と目的

現状としてGoogle Chrome等で検証を行ってみると、encrypt自体はされているものの状態として望ましくない感じっていうことが実はあった。 f:id:neji_shiki:20210312153927p:plain

これに対応するためにオプションに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とかのコマンドで行けたかもしれないけど、詳しくは見ていない。

参考 : とりあえずこの辺り

 # CentOS7にOpenSSL1.1.1をインストール

 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を使用するために修正が必要となる。

 参考tcpリピータのstone - 極限環境材料化学研究室

ここにある通り、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の項目が変わっている。 f:id:neji_shiki:20210312153932p:plain

ということで、TLS 1.2で怒られない感じのcipher suiteを使用したリバースプロキシの立ち上げにはこれで成功した感じ。

とはいえ、NginxとかApacheをおとなしく使うほうが導入の手間は少ないと思う。

Docker使えばすぐに立ち上がるしね。