nginx のモジュール追加リビルド (CentOS 7 EPEL 版)

nginx 公式や epel パッケージの nginx バイナリでは使いたいモジュールがコンパイルされていない。特に nginx-dav-ext-module(WebDAV で OPTIONS メソッドが利用可能になる)、headers-more-nginx-module(HTTPヘッダを追加したり削除したり)、nginx-ct(証明書の透明性対応ができる)を使いたいので、ソースからビルドすることにする。

前提として、使用 OS は CentOS 7 である。

nginx 公式の RPM パッケージもあるが、この記事では epel リポジトリの nginx RPM をベースに、必要なモジュールの記述を追加して SRPM からリビルドしてみる。

1. コンパイルに必要なパッケージをインストール

$ sudo yum install gperftools-devel openssl-devel pcre-devel zlib-devel GeoIP-devel gd-devel perl-devel perl-ExtUtils-Embed libxslt-devel expat-devel git

2. epel リポジトリを追加

epel リポジトリを追加する。追加済みであれば作業の必要なし。
$ sudo yum install epel-release

3. SRPM の入手

SRPM をダウンロード・インストールする。
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --enable epel-testing
$ yumdownloader --source nginx
$ rpm -ivh nginx-1.16.1-1.el7.src.rpm

今後 yum update で勝手にアップデートされないように、epel レポジトリを無効化しておく。
$ sudo yum-config-manager --disable epel\*

4. カスタマイズ

SRPM の spec ファイルを編集する。
$ vi rpmbuild/SPECS/nginx.spec

以下、nginx.spec に青字の部分を追加する。追加する3つのモジュールのうち、nginx-ct は元々 nginx に含まれていて動的モジュール化されている mod-mail と mod-stream に依存するため、これも動的モジュール化する(そうしないとビルドエラーになる)。

(58行目から)
BuildRequires: openssl-devel
BuildRequires: pcre-devel
BuildRequires: zlib-devel
BuildRequires: expat-devel
BuildRequires: git

Requires: nginx-filesystem = %{epoch}:%{version}-%{release}
%if 0%{?el7}

(78行目から)
Requires: openssl
Requires: pcre
Requires: expat
Requires(pre): nginx-filesystem
%if 0%{?with_mailcap_mimetypes}
Requires: nginx-mimetypes

(106行目から)
Requires: nginx-mod-http-xslt-filter = %{epoch}:%{version}-%{release}
Requires: nginx-mod-mail = %{epoch}:%{version}-%{release}
Requires: nginx-mod-stream = %{epoch}:%{version}-%{release}
Requires: nginx-mod-ct = %{epoch}:%{version}-%{release}

%description all-modules
Meta package that installs all available nginx modules.

(176行目から)
%description mod-stream
%{summary}.

%package mod-ct
Summary: Nginx ct modules
Requires: nginx

%description mod-ct
%{summary}.


%prep
%setup -q
git clone https://github.com/arut/nginx-dav-ext-module.git
git clone https://github.com/openresty/headers-more-nginx-module.git
git clone https://github.com/grahamedgecombe/nginx-ct.git
%patch0 -p0
%patch2 -p1
cp %{SOURCE200} %{SOURCE210} %{SOURCE10} %{SOURCE12} .

(246行目から)
--with-pcre-jit \
--with-stream=dynamic \
--with-stream_ssl_module \
--add-module=./nginx-dav-ext-module \
--add-module=./headers-more-nginx-module \
--add-dynamic-module=./nginx-ct \
%if 0%{?with_gperftools}
--with-google_perftools_module \
%endif

(343行目から)
> %{buildroot}%{_datadir}/nginx/modules/mod-mail.conf
echo 'load_module "%{_libdir}/nginx/modules/ngx_stream_module.so";' \
> %{buildroot}%{_datadir}/nginx/modules/mod-stream.conf
echo 'load_module "%{_libdir}/nginx/modules/ngx_ssl_ct_module.so";' \
> %{buildroot}%{_datadir}/nginx/modules/mod-ct.conf
echo 'load_module "%{_libdir}/nginx/modules/ngx_http_ssl_ct_module.so";' \
> %{buildroot}%{_datadir}/nginx/modules/mod-http-ct.conf
echo 'load_module "%{_libdir}/nginx/modules/ngx_mail_ssl_ct_module.so";' \
> %{buildroot}%{_datadir}/nginx/modules/mod-mail_ct.conf
echo 'load_module "%{_libdir}/nginx/modules/ngx_stream_ssl_ct_module.so";' \
> %{buildroot}%{_datadir}/nginx/modules/mod-stream_ct.conf

%pre filesystem
getent group %{nginx_user} > /dev/null || groupadd -r %{nginx_user}

(386行目から)
/usr/bin/systemctl reload nginx.service >/dev/null 2>&1 || :
fi

%post mod-ct
if [ $1 -eq 1 ]; then
/usr/bin/systemctl reload nginx.service >/dev/null 2>&1 || :
fi

%preun
%systemd_preun nginx.service

(475行目から)
%{_datadir}/nginx/modules/mod-stream.conf
%{_libdir}/nginx/modules/ngx_stream_module.so

%files mod-ct
%{_datadir}/nginx/modules/mod-ct.conf
%{_datadir}/nginx/modules/mod-http-ct.conf
%{_datadir}/nginx/modules/mod-mail_ct.conf
%{_datadir}/nginx/modules/mod-stream_ct.conf
%{_libdir}/nginx/modules/ngx_http_ssl_ct_module.so
%{_libdir}/nginx/modules/ngx_mail_ssl_ct_module.so
%{_libdir}/nginx/modules/ngx_ssl_ct_module.so
%{_libdir}/nginx/modules/ngx_stream_ssl_ct_module.so


%changelog
* Sun Sep 15 2019 Warren Togami <warren@blockstream.com>
(以下略)

5. ビルド、インストール

ビルドを実行する。
$ rpmbuild --with geoip -ba rpmbuild/SPECS/nginx.spec

RPM が出来上がったらインストールする。すでに EPEL や nginx 公式 RPM をインストールしてしまっている場合は、先に削除しておくこと。

既存パッケージの削除:
$ sudo yum erase `rpm -qa | grep nginx`

カスタマイズした RPM のインストール:
$ sudo yum localinstall rpmbuild/RPMS/x86_64/nginx-1.*.rpm rpmbuild/RPMS/x86_64/nginx-mod-*.rpm rpmbuild/RPMS/noarch/nginx-*.rpm

6. 起動

デーモンを起動する。
$ sudo systemctl enable nginx
$ sudo systemctl start nginx