OpenSSLをソースからビルドしてNginxで使用する
はじめに
今まではパッケージマネージャのアップデートでOpenSSLのバージョンをアップデートしていましたが、先日はじめてソースからビルドして使用してみたので、そのやり方をまとめます。
TL;DR
:warning: 読むのがめんどくさい、急いでいる人向けです。記事を最後まで読む人はTL;DRは読み飛ばしてください
$ wget https://www.openssl.org/source/openssl-x.x.x.tar.gz
$ tar xzvf openssl-x.x.x.tar.gz
$ cd openssl-x.x.x
$ ./config shared zlib
$ make
$ sudo make install
$ /usr/local/ssl/bin/openssl version
+ PATH="/usr/local/ssl/bin:$PATH"
$ source ~/.bashrc
$ openssl version
$ wget http://nginx.org/download/nginx-x.xx.x.tar.gz
$ tar xzvf nginx-x.xx.x.tar.gz
$ cd nginx-x.xx.x
$ ./configure --with-http_ssl_module --with-http_v2_module --with-openssl=展開したOpenSSLのディレクトリのパス
$ make
$ sudo make install
+ PATH="/usr/local/nginx/sbin:$PATH"
$ source ~/.bashrc
$ nginx -V
サーバを再起動する
$ sudo nginx
うまくいかない場合は以下に続く記事をお読みください。
ソースからビルドする理由
個人的には以下の3つが挙げられます
- どのバージョンを使用しているか確認しづらい
- Nginxで最新バージョンのOpenSSLを使用しているか不安
- 使用するバージョンを選べない
CentOSではOpenSSLの本当のバージョンを簡単に調べることができません。
以下のコマンドを実行すればバージョンを確認できますが、これは本当のバージョンではない可能性があります。yumでインストールされたパッケージは、アップデートを行っても、バージョンの表示が更新されないものがあります。OpenSSLがその例です。
$ openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013 # <= これは本当のバージョンではない
また、本当のバージョンを確認する方法として、rpmを使用するという記事が紹介されていましたが、ぼくが確認した限りでは、上記と同じく更新されていないバージョンが表示されてしまいました。
$ rpm -q openssl
OpenSSL 1.0.1e-fips 11 Feb 2013 # <= これも本当のバージョンではない
また、これだと、最新バージョンのOpenSSLをインストールしていても、Nginxがその最新バージョンのOpenSSLを使用しているかどうか不安という点も挙げられます。
$ nginx -V
nginx version: nginx/x.xx.x
built by gcc x.x.x xxxxxxxx (Red Hat x.x.x) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013 # <= バージョンが違う
TLS SNI support enabled
configure arguments: ...
さらに、OpenSSLのバージョンは、1.0.2系、1.1.0系など複数ありますが、どのバージョンにアップデートされるかわからないので、自分のインストールしたいバージョンを選べません。
常に最新版をインストールしておきたいのですが、一昨日(2017年2月16日)に更新された1.1.0eを、ぼくが昨日インストールしてみたら、ライブラリがインストールされなかったり、コンパイルエラーになったりしたので、そういう状況のときに柔軟に対応したいという思いがあります。
前置きが長くなってしまいましたが、つまりはソースからビルドしたほうが何かと融通が効くのでソースからビルドすることにしました。
環境
- CentOS 7
OpenSSLのインストール
ダウンロード
まずは公式のダウンロードページからOpenSSLをインストールします。インストール可能な最新版(安定版)のダウンロードリンクが表でまとまっているので、そこからインストールしたいバージョンを選んでダウンロードします。リンクをクリックして直接ダウンロードしてもいいのですが、今回はリモートからダウンロードすることを想定して、wget
を使用します。.tar.gz
のリンク先をコピーして以下のコマンドを実行します。
$ wget https://www.openssl.org/source/openssl-x.x.x.tar.gz
x.x.x
にはバージョンが入ります。必ずこの形式とは限らないので、公式サイトのリンクをコピペしてください。なお、実行するとカレントディレクトリにファイルがダウンロードされますが、カレントディレクトリはどこでも良いです。邪魔にならないところでダウンロードしてください。
圧縮ファイルを展開
ダウンロードされたファイルは圧縮ファイルなので、以下のコマンドで展開します。
$ tar xzvf openssl-x.x.x.tar.gz
ファイルは先ほどダウンロードしたファイル名を指定してください。
展開されたら、そのディレクトリに移動します。ちなみに圧縮ファイルのほうはもう必要ないので削除してOKです。
$ cd openssl-x.x.x
ビルド
展開したディレクトリに移動したら設定を行い、ビルドします。
$ ./config shared zlib
$ make
$ sudo make install
config
を実行するときのオプションについては、このディレクトリ内にあるINSTALL
ファイルを参照してください。通常はshared
とzlib
で問題ないかと思います。
ビルドには時間がかかりますが、エラーが出なければ成功です。
確認
インストールされていることを確認するには以下のコマンドを実行します。
$ /usr/local/ssl/bin/openssl version
OpenSSL x.x.x xx xxx xxxx
自分がインストールしたバージョンが表示されていればOKです。
パスを通す
しかし、元々プリインストールされているOpenSSLがある場合は、openssl
コマンドがそちらを参照してしまうので、今回ソースからビルドしたほうのOpenSSLを使用するためには、パスを通す必要があります。.bashrc
に以下の一行を追加します。
+ PATH="/usr/local/ssl/bin:$PATH"
:warning: +
は入力しません。
追加したら、.bashrc
を再読込します。
$ source ~/.bashrc
再読込したら、openssl
コマンドでバージョンを確認します。
$ openssl version
OpenSSL x.x.x xx xxx xxxx
このときに表示されたバージョンがソースからビルドしたバージョンになっていればOKです。
Nginxでの使用
おそらくこのままでは、NginxはプリインストールされたOpenSSLを参照してしまいます。NginxでもソースからビルドしたOpenSSLを使用したい場合は、Nginxをソースからビルドする必要があります。インストールする際に、使用するOpenSSLを、ソースからビルドしたほうのパスに指定しておけばOKです。
ここでは最低限のインストールコマンドだけを載せておきます。Nginxをソースからビルドする方法の詳細は以下の記事を参照してください。
Nginxでレスポンスヘッダの一部を隠蔽する方法
$ wget https://nginx.org/download/nginx-x.xx.x.tar.gz
$ tar xzvf nginx-x.xx.x.tar.gz
$ cd nginx-x.xx.x
$ ./configure --with-http_ssl_module --with-http_v2_module --with-openssl=展開したOpenSSLのディレクトリのパス
$ make
$ sudo make install
x.xx.x
にはNginxのバージョンを指定します。バージョンは公式サイトのダウンロードページで確認してください。ダウンロードリンクをコピペするのが確実です。
展開したOpenSSLのディレクトリのパス
には、OpenSSLのインストール手順で展開した後のOpenSSLのディレクトリのあるパスを指定してください。
ビルドに成功したら、パスを通します。OpenSSLのときと同様に.bashrc
に以下の一行を追加します。
+ PATH="/usr/local/nginx/sbin:$PATH"
.bashrc
を反映させます。
$ source ~/.bashrc
パスを通したら、以下のコマンドを実行して、NginxがソースからビルドしたOpenSSLを使用しているか確認します。
$ nginx -V
nginx version: nginx/x.xx.x
built by gcc x.x.x xxxxxxxx (Red Hat x.x.x) (GCC)
built with OpenSSL x.x.x xx xxx xxxx
TLS SNI support enabled
configure arguments: ...
built with OpenSSL
の箇所のバージョンがソースからビルドしたOpenSSLのバージョンになっていれば成功です!
再起動
せっかくアップデートしても、再起動しなければ意味がありません。nginx
コマンドには再起動するコマンドがあるので問題ないですが、openssl
コマンドで再起動する方法はわからないので、ぼくはサーバ自体を再起動しました。
サーバを再起動したら、Nginxを起動します。
$ sudo nginx
これで、Nginxでも最新バージョンのOpenSSLを使用することができるようになりました!
Discussion