2019年5月31日金曜日

【備忘録】LibreSSL 2.9.2 + Postfix 3.4.5 + nginx 1.17.0 へのアップグレード

Postfix 3.4系は、OpenSSL 1.0.1以下のサポートを打ち切ったため、Redhat Linux ES 6(まだ現役の場合も多いハズ)の標準 OpenSSL 1.0.1にいれると悲劇が・・・というつぶやきがありますね。なら、LibreSSLなら問題ないはずだよね?ってことでやってみました。ついでに nginx もバージョンアップしておきました。

サーバー環境:Redhat Linux ES 6

過去記事


LIBRESSL自体は簡単


./configure
make
sudo make install

openssl version
LibreSSL 2.9.2

です。何も苦労はしません。
上記では /usr/local 以下にインストールされるようになっているので、
/usr/local/lib/libssl.so(シンボリックリンク) の実体が
/usr/local/lib/libssl.so.47.0.5
ならOKということになります。

LibreSSL 2.8.x では
/usr/local/lib/libssl.so.46.0.x 
だったので、2.9.x 系は、libssl.so.47.0.x ってことですね。


動作中の NGINXへの影響はありません


NGINXについては、コンパイル時にその時利用するlibreSSLを組み込むため、影響をうけません。
 --with-openssl=../libressl-2.9.2
など。

nginx -V 
...
built with LibreSSL バージョン
...

のように組み込まれていることがわかります。


動作中の POSTFIXについては影響を受けませんが注意が必要です。


動作中のものはメモリ上に展開されて実行されているため、即座に影響は受けませんが、postfixを再起動したときには少なくても影響を受ける可能性があります。

今回 2.8.x --> 2.9.x へのアップグレードのため影響は受けませんでした。

ldd /usr/sbin/postfix | grep libssl
 libssl.so.46 => /usr/local/lib/libssl.so.46.0.x

のように 2.8.x 系は libssl.so.46 ですが、2.9.xは libssl.so.47 (2.9.2 は libssl.so.47.0.5 が実体)となっているためです。もし 2.9.2 --> 2.9.3 にアップデートした場合には、おなじ libssl.so.47 の実体を参照するので影響をうけるというわけです。

NGINXのアップグレード


先に nginx の方をやってしまいます。
【備忘録】LibreSSL 2.8.1 + Postfix 3.3.1 + nginx 1.15.5 へのアップグレード
を参考にして

 --with-openssl=../libressl-2.9.2

の部分を上記のように libssl-2.9.2 ライブラリを使いように気をつけてください。

objs/nginx -V
...
built with LibreSSL 2.9.2
...

とうまく組み込むことができれば、
/usr/local/nginx で起動するように作っていると仮定すると、

/usr/local/nginx-1.17.0 にインストールされたことになります。

/etc/init.d/nginx stop
cd /usr/local/nginx
rm nginx
ln -s nginx-1.17.0 nginx
/etc/init.d/nginx start

のように前のバージョンに手軽に戻すことができるようにしておきましょう。それが出来るのがソースからコンパイルする利点の一つでもあります。

POSTFIX のアップグレード



を参考にして src/tls/tls.h に対して、OPENSSLのバージョンをごまかす設定を追加します。今回は、1.0.1 以下だと TLSが組み込まれなくなるので注意が必要です。

src/tls/tls.h の設定をしなかった場合


../../lib/libtls.a(tls_certkey.o): In function `use_chain':
/usr/local/src/postfix/postfix-3.4.5/src/tls/tls_certkey.c:159: undefined reference to `SSL_CTX_use_cert_and_key'
/usr/local/src/postfix/postfix-3.4.5/src/tls/tls_certkey.c:162: undefined reference to `SSL_use_cert_and_key'
../../lib/libtls.a(tls_server.o): In function `tls_server_init':
/usr/local/src/postfix/postfix-3.4.5/src/tls/tls_server.c:521: undefined reference to `SSL_CTX_set_num_tickets'
collect2: ld はステータス 1 で終了しました
make: *** [smtpd] エラー 1
make: *** [update] エラー 1

のように make エラーになります。

src/tls/tls.h に設定追加


#include <openssl/ssl.h>
の下に

#undef OPENSSL_VERSION_NUMBER
#define OPENSSL_VERSION_NUMBER  0x1000900fUL

を追加します。今回 OpenSSL 1.0.9 だと名乗ることにしました。
LibreSSLは 1.0.1g をベースにカスタマイズされてきたため、あまりバージョンをあげて OpenSSL独自の機能を使っておかしなことにならないように注意したほうがいいかなと思ったためです。

なお tls.hには

#if (OPENSSL_VERSION_NUMBER < 0x1000200fUL)   
#error "OpenSSL releases prior to 1.0.2 are no longer supported"
#endif
  
 /* Backwards compatibility with OpenSSL < 1.1.0 */
#if OPENSSL_VERSION_NUMBER < 0x10100000L 
 /* Backwards compatibility with OpenSSL < 1.1.1 */
#if OPENSSL_VERSION_NUMBER < 0x1010100fUL  
  * Backwards compatibility with OpenSSL < 1.1.1a.
#if OPENSSL_VERSION_NUMBER < 0x1010101fUL

のように、1.0.2 未満だとエラーになりますし、1.1.0 未満、1.1.1未満、1.1.1a 未満それぞれに対する互換設定もあるので、1.0.9 あたりしておこうかなと思ったわけです。

make makefiles CCARGS="-DUSE_TLS -I/usr/local/include"  AUXLIBS="-L/usr/local/lib -lssl -lcrypto -lz -ldl"
make

などを指定して make するわけですが、
./tls.h:99:1: 警告: "OPENSSL_VERSION" が再定義されました
のように警告はでます。確信犯的にやっているわけなので無視します。

ldd bin/postfix | grep libssl
libssl.so.47 => /usr/local/lib/libssl.so.47
(libssl.so.47 の実体は、 libssl.so.47.0.5)

のように LibreSSL 2.9.2 のライブラリを参照していることを確認した上で、/etc/postfix をバックアップし

make upgrade

をしてアップグレードします。
念の為
/etc/postfix/master.cf 
の末尾をチェックしてください(*)。

それから
/etc/init.d/postfix restart
をして再起動します。

*今回、
fatal: master_spawn: exec /usr/libexec/postfix/smtppostlog: No such file or directory
と出てうまく動かないトラブルが発生しました。

理由は
master.cf の末尾に
postlog   unix-dgram n  -       n       -       1       postlogd
が今回から追加されたわけなのですが、その前の行で改行されていなかったからか
smtp-hogehoge   unix   -   -   n   -   -    smtppostlog   unix-dgram n  -       n       -       1       postlogd
となってしまっていたのでした。

正しくは

smtp-hogehoge   unix   -   -   n   -   -    smtp
postlog   unix-dgram n  -       n       -       1       postlogd

のようにする必要がありました。

なおメールログには
postfix/smtpd[12446]: warning: run-time library vs. compile-time header version mismatch: OpenSSL 2.0.0 may not be compatible with OpenSSL 1.0.0
が定期的にでます。

LibreSSL 2.9.2 だからです。postfix的には 2.9.2 だけをみて 1.0.1 互換ないかもしれないよって親切に教えてくれているわけです。でも確信犯的に LibreSSLを使っているので無視です。早く postfix が LibreSSLに対応してくれないかなぁ。

2019年5月31日 @kimipooh