OpenSSLをソースからビルドしてNginxで使用する

  • 0
    いいね
  • 0
    コメント

    はじめに

    今まではパッケージマネージャのアップデートで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
    
    ~/.bashrc
    + 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
    
    ~/.bashrc
    + 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ファイルを参照してください。通常はsharedzlibで問題ないかと思います。

    ビルドには時間がかかりますが、エラーが出なければ成功です。

    確認

    インストールされていることを確認するには以下のコマンドを実行します。

    $ /usr/local/ssl/bin/openssl version
    OpenSSL x.x.x  xx xxx xxxx
    

    自分がインストールしたバージョンが表示されていればOKです。

    パスを通す

    しかし、元々プリインストールされているOpenSSLがある場合は、opensslコマンドがそちらを参照してしまうので、今回ソースからビルドしたほうのOpenSSLを使用するためには、パスを通す必要があります。.bashrcに以下の一行を追加します。

    ~/.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に以下の一行を追加します。

    ~/.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を使用することができるようになりました!

    参考