Nginxに最新のOpenSSLを組み込んでソースインストールする方法

2022年6月17日

前提

書くこと/書かないこと

最新のOpenSSLを組み込んだnginxをソースコードからインストールする方法を書きます。
前にApacheで同じような記事を書きましたがそのnginx版です。

環境

AlmaLinux release 8.6 (Sky Tiger) ※CentOS8代替OS
OpenSSL 3.0.3 3 May 2022 (Library: OpenSSL 3.0.3 3 May 2022)

さくっと

内容的にさくっとまとめるのが難しいので後回しにします。

こってりと

はじめに

Nginxを標準リポジトリからインストールすると通常は最新版でなく、OpenSSLも古いため脆弱性が残る状態だったりします。

OpenSSL3の最新版をソースコードからインストールする方法は前回書いたので、今回はこの続きとして、このOpenSSLを組み込んだNginxのインストールについて書きます。

事前準備

必要なライブラリを先にインストールしておきます。

dnf install pcre-devel gd-devel

Nginxのインストール

ソースコードの入手

nginxのサイトから最新版を入手します。


https://nginx.org/en/download.html

現時点ではmainlineは1.21.6、stableが1.22.0は最新です。
今回は安定版であるstable版をインストールしたいので、nginx-1.22.0を右クリックしてリンクアドレスをコピーし、サーバにダウンロードします。

# cd /usr/local/src/
# wget https://nginx.org/download/nginx-1.22.0.tar.gz
--2022-06-11 10:58:34--  https://nginx.org/download/nginx-1.22.0.tar.gz
nginx.org (nginx.org) をDNSに問いあわせています... 52.58.199.22, 3.125.197.172, 2a05:d014:edb:5704::6, ...
nginx.org (nginx.org)|52.58.199.22|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 1073322 (1.0M) [application/octet-stream]
`nginx-1.22.0.tar.gz' に保存中

nginx-1.22.0.tar.gz 100%[===================>]   1.02M   840KB/s 時間 1.2s

2022-06-11 10:58:36 (840 KB/s) - `nginx-1.22.0.tar.gz' へ保存完了 [1073322/1073322]

解凍 ~ コンフィギュレーション

tar.gzを展開してconfigureします。

# tar zxvf nginx-1.22.0.tar.gz
# cd nginx-1.22.0.tar.gz/

ここで、サービス開始後に外部からWebサーバとしてnginxを使っていることやそのバージョンなどを知られないように、情報を隠すための変更を行います。テキストエディタでsrc/http/ngx_http_header_filter_module.cを開き、49行目~51行目付近にある"nginx", NGINX_VER, NGINX_VER_BUILDを書き換えて保存します。

★一部抜粋
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
↓
static u_char ngx_http_server_string[] = "Server: secret" CRLF;
static u_char ngx_http_server_full_string[] = "Server: secret" CRLF;
static u_char ngx_http_server_build_string[] = "Server: secret" CRLF;

続いてconfigureです。configureのオプションは目的によって変える必要があります。今回はOpenSSLを最新化する以外に、HTTP/2、gzip圧縮、realipを使います。

./configure --prefix=/usr/local/nginx \
--with-http_ssl_module --with-openssl=/usr/local/openssl \
--with-http_v2_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gzip_static_module

ビルド ~ インストール

次はビルドです。ここで暫く嵌りました。

# make
make -f objs/Makefile
make[1]: ディレクトリ '/usr/local/src/nginx-1.22.0' に入ります
cd /usr/local/openssl/ \
&& if [ -f Makefile ]; then make clean; fi \
&& ./config --prefix=/usr/local/openssl//.openssl no-shared no-threads  \
&& make \
&& make install_sw LIBDIR=lib
/bin/sh: 行 2: ./config: そのようなファイルやディレクトリはありません
make[1]: *** [objs/Makefile:1332: /usr/local/openssl//.openssl/include/openssl/ssl.h] エラー 127
make[1]: ディレクトリ '/usr/local/src/nginx-1.22.0' から出ます
make: *** [Makefile:10: build] エラー 2

“/usr/local/openssl//.openssl"の部分がおかしそうです。実際にディレクトリを見ても.opensslディレクトリはありませんでした。

 #ls -al /usr/local/openssl/
合計 0
drwxr-xr-x   7 root root  69  6月 11 14:54 .
drwxr-xr-x. 13 root root 146  6月 11 14:50 ..
drwxr-xr-x   2 root root  37  6月 11 14:50 bin
drwxr-xr-x   3 root root  21  6月 11 14:50 include
drwxr-xr-x   5 root root 173  6月 11 14:50 lib64
drwxr-xr-x   4 root root  28  6月 11 14:55 share
drwxr-xr-x   5 root root 140  6月 11 14:50 ssl

方々調べたところ、中国語のページに同じ事象のことが書かれており、解決策まで書かれていました。

https://www.cnblogs.com/kevingrace/p/8058535.html

“auto/lib/openssl"を見てみると、下記の箇所で確かに.opensslのパスが指定されるケースが記述されていました。
$CCが"cl"でも"bcc32″でもない場合に.opensslが付くようです。
$CCはコンパイラを指し、今回の環境ではgccを使っているので*)の方が適用される状況です。

    case "$CC" in

        cl | bcc32)
            have=NGX_OPENSSL . auto/have
            have=NGX_SSL . auto/have

            CFLAGS="$CFLAGS -DNO_SYS_TYPES_H"

            CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
            CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"

            if [ -f $OPENSSL/ms/do_ms.bat ]; then
                # before OpenSSL 1.1.0
                CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/ssleay32.lib"
                CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libeay32.lib"
            else
"auto/lib/openssl/conf" 142L, 4127C

            # libeay32.lib requires gdi32.lib
            CORE_LIBS="$CORE_LIBS gdi32.lib"
            # OpenSSL 1.0.0 requires crypt32.lib
            CORE_LIBS="$CORE_LIBS crypt32.lib"
        ;;

        *)
            have=NGX_OPENSSL . auto/have
            have=NGX_SSL . auto/have

            CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
            CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
            CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
            CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
            CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
            CORE_LIBS="$CORE_LIBS $NGX_LIBPTHREAD"

            if [ "$NGX_PLATFORM" = win32 ]; then
                CORE_LIBS="$CORE_LIBS -lgdi32 -lcrypt32 -lws2_32"
            fi
        ;;
    esac

対象サーバの構成に合うように下記の変更をして保存します。
先人に倣い/.opensslの階層の削除とlib→lib64の修正を行います。

★一部抜粋
            CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
            CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
            CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
            CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
↓
            CORE_INCS="$CORE_INCS $OPENSSL/include"
            CORE_DEPS="$CORE_DEPS $OPENSSL/include/openssl/ssl.h"
            CORE_LIBS="$CORE_LIBS $OPENSSL/lib64/libssl.a"
            CORE_LIBS="$CORE_LIBS $OPENSSL/lib64/libcrypto.a"

configure→makeすると、エラーが解消されたので、続けてmake installまで行います。

# ./configure --prefix=/usr/local/nginx \
--with-http_ssl_module --with-openssl=/usr/local/openssl \
--with-http_v2_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gzip_static_module
# make
# make install

インストール結果の確認

エラーなくinstallが終わったのでバージョンを確認します。

# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.22.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-10) (GCC)
built with OpenSSL 3.0.3 3 May 2022
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/usr/local/openssl/ --with-http_v2_module --with-http_realip_module --with-http_image_filter_module --with-http_gzip_static_module

OKですね。
OpenSSLもOpenSSL3がインストールされていることが確認できました。

起動確認

次のコマンドで起動します。

/usr/local/nginx/sbin/nginx

localhostにアクセスすると、無事にnginxが表示されました。

これでOKです。