CentOS7.3のApache 2.4をRPMでアップデートする方法(1)

#はじめに
CentOS7.3のApacheは標準で2.4.6が入っています。
しかし、バージョンが古いため、新しいバージョンの機能を使いたくてアップデートしたいこともあると思います。

私の場合は、バージョンアップに加えて、開発要件としてApacheのセキュリティモジュールをmod_sslの代わりにmod_nssを使う(ためにmod_sslを抜く)必要もありました。

この記事ではFedraCore25(以下FC25)のSRPMをリビルドしてRPMファイルを作成し、ApacheをRPMパッケージとしてバージョンアップさせる方法をまとめました。

# アップデートの進め方
自分だけでなく、同僚の開発環境もそろえるために、一度RPMファイルを作成後にアップデートという手順を踏んでいます。

1. RPMビルド環境の構築
2. アップデート先のSRPMファイルの取得と展開
3. SPECファイルの編集
4. rpmbuildでSRPMからRPMファイルを作成する
5. RPMファイルでアップデートする

#実行環境
- OS：CentOS 7.3(64bit)
- Apache：v2.4.6(OS標準)　→　v2.4.23(アップデート先)

# 1. RPMビルド環境の構築
今回はrpmbuildコマンドを使ってパッケージを作成するため、まずrpmbuild環境を構築します。
環境構築が必要な方は次の記事が参考になると思いますので、参照して構築してください。
[rpmbuild環境の構築](https://qiita.com/IK12_info/items/bcf695460363bae87eb9)

# 2. アップデート先のSRPMファイルの取得と展開
FedoraProjectからSRPMファイル(httpd-2.4.23-4.fc25.src.rpm)をダウンロードして展開します。

```console
 $ wget https://dl.fedoraproject.org/pub/fedora/linux/releases/25/Everything/source/tree/Packages/h/httpd-2.4.23-4.fc25.src.rpm
 $ rpm -ivh httpd-2.4.23-4.fc25.src.rpm
```

RPMビルド環境の構築のところで作成した各ディレクトリに展開されます。

# 3. SPECファイルの編集

~/rpmbuild/SPECSにあるhttpd.specを編集します。

FC25オリジナルとの違い

- Release欄を変更し、別リリース扱いにする。
- TLS通信はmod_sslではなくmod_nssを使うため、mod_sslおよび関連モジュールはインストールしない。
- system-logos-httpdはBuildRequiredから除外する(centos-logosと競合するため)

実装例です。(オリジナルとの差分のみ)

```diff:httpd.spec
--- httpd.spec.org	2016-07-19 00:33:45.000000000 +0900
+++ httpd.spec	2017-07-14 10:38:47.825864600 +0900
@@ -8,7 +8,7 @@
 Summary: Apache HTTP Server
 Name: httpd
 Version: 2.4.23
-Release: 4%{?dist}
+Release: 4.1.sample%{?dist}
 URL: http://httpd.apache.org/
 Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
 Source1: index.html
@@ -35,7 +35,7 @@
 Source23: manual.conf
 Source24: 00-systemd.conf
 Source25: 01-session.conf
-Source26: 10-listen443.conf
+#Source26: 10-listen443.conf
 Source27: httpd.socket
 Source28: 00-optional.conf
 # Documentation
@@ -75,7 +75,7 @@
 BuildRequires: zlib-devel, libselinux-devel, lua-devel
 BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0
 BuildRequires: systemd-devel, libnghttp2-devel
-Requires: /etc/mime.types, system-logos-httpd
+Requires: /etc/mime.types 
 Obsoletes: httpd-suexec
 Provides: webserver
 Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release}
@@ -139,22 +139,22 @@
 The httpd-tools package contains tools which can be used with 
 the Apache HTTP Server.
 
-%package -n mod_ssl
-Group: System Environment/Daemons
-Summary: SSL/TLS module for the Apache HTTP Server
-Epoch: 1
-BuildRequires: openssl-devel
-Requires(post): openssl, /bin/cat, hostname
-Requires(pre): httpd-filesystem
-Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
-Obsoletes: stronghold-mod_ssl
-# Require an OpenSSL which supports PROFILE=SYSTEM
-Conflicts: openssl-libs < 1:1.0.1h-4
-
-%description -n mod_ssl
-The mod_ssl module provides strong cryptography for the Apache Web
-server via the Secure Sockets Layer (SSL) and Transport Layer
-Security (TLS) protocols.
+#%package -n mod_ssl
+#Group: System Environment/Daemons
+#Summary: SSL/TLS module for the Apache HTTP Server
+#Epoch: 1
+#BuildRequires: openssl-devel
+#Requires(post): openssl, /bin/cat, hostname
+#Requires(pre): httpd-filesystem
+#Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
+#Obsoletes: stronghold-mod_ssl
+## Require an OpenSSL which supports PROFILE=SYSTEM
+#Conflicts: openssl-libs < 1:1.0.1h-4
+#
+#%description -n mod_ssl
+#The mod_ssl module provides strong cryptography for the Apache Web
+#server via the Secure Sockets Layer (SSL) and Transport Layer
+#Security (TLS) protocols.
 
 %package -n mod_proxy_html
 Group: System Environment/Daemons
@@ -274,7 +274,6 @@
         --enable-pie \
         --with-pcre \
         --enable-mods-shared=all \
-	--enable-ssl --with-ssl --disable-distcache \
 	--enable-proxy --enable-proxy-fdpass \
         --enable-cache \
         --enable-disk-cache \
@@ -305,7 +304,7 @@
 install -m 644 $RPM_SOURCE_DIR/README.confmod \
     $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/README
 for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \
-         00-proxy.conf 00-ssl.conf 01-ldap.conf 00-proxyhtml.conf \
+         00-proxy.conf 01-ldap.conf 00-proxyhtml.conf \
          01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf; do
   install -m 644 -p $RPM_SOURCE_DIR/$f \
         $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f
@@ -317,10 +316,11 @@
 mkdir $RPM_BUILD_ROOT%{_unitdir}/httpd.service.d
 mkdir $RPM_BUILD_ROOT%{_unitdir}/httpd.socket.d
 
-install -m 644 -p $RPM_SOURCE_DIR/10-listen443.conf \
-      $RPM_BUILD_ROOT%{_unitdir}/httpd.socket.d/10-listen443.conf
+#install -m 644 -p $RPM_SOURCE_DIR/10-listen443.conf \
+#      $RPM_BUILD_ROOT%{_unitdir}/httpd.socket.d/10-listen443.conf
 
-for f in welcome.conf ssl.conf manual.conf userdir.conf; do
+#for f in welcome.conf ssl.conf manual.conf userdir.conf; do
+for f in welcome.conf manual.conf userdir.conf; do
   install -m 644 -p $RPM_SOURCE_DIR/$f \
         $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/$f
 done
@@ -332,7 +332,8 @@
 done
 
 # Extra config trimmed:
-rm -v docs/conf/extra/httpd-{ssl,userdir}.conf
+#rm -v docs/conf/extra/httpd-{ssl,userdir}.conf
+rm -v docs/conf/extra/httpd-userdir.conf
 
 rm $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/*.conf
 install -m 644 -p $RPM_SOURCE_DIR/httpd.conf \
@@ -413,10 +414,10 @@
 ln -s /run/httpd $RPM_BUILD_ROOT/etc/httpd/run
 ln -s ../..%{_libdir}/httpd/modules $RPM_BUILD_ROOT/etc/httpd/modules
 
-# install http-ssl-pass-dialog
-mkdir -p $RPM_BUILD_ROOT%{_libexecdir}
-install -m755 $RPM_SOURCE_DIR/httpd-ssl-pass-dialog \
-	$RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-pass-dialog
+## install http-ssl-pass-dialog
+#mkdir -p $RPM_BUILD_ROOT%{_libexecdir}
+#install -m755 $RPM_SOURCE_DIR/httpd-ssl-pass-dialog \
+#	$RPM_BUILD_ROOT%{_libexecdir}/httpd-ssl-pass-dialog
 
 # Install action scripts
 mkdir -p $RPM_BUILD_ROOT%{_libexecdir}/initscripts/legacy-actions/httpd
@@ -493,35 +494,35 @@
 test -f /etc/sysconfig/httpd-disable-posttrans || \
   /bin/systemctl try-restart httpd.service htcacheclean.service >/dev/null 2>&1 || :
 
-%define sslcert %{_sysconfdir}/pki/tls/certs/localhost.crt
-%define sslkey %{_sysconfdir}/pki/tls/private/localhost.key
-
-%post -n mod_ssl
-umask 077
-
-if [ -f %{sslkey} -o -f %{sslcert} ]; then
-   exit 0
-fi
-
-%{_bindir}/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 2048 > %{sslkey} 2> /dev/null
-
-FQDN=`hostname`
-# A >59 char FQDN means "root@FQDN" exceeds 64-char max length for emailAddress
-if [ "x${FQDN}" = "x" -o ${#FQDN} -gt 59 ]; then
-   FQDN=localhost.localdomain
-fi
-
-cat << EOF | %{_bindir}/openssl req -new -key %{sslkey} \
-         -x509 -sha256 -days 365 -set_serial $RANDOM -extensions v3_req \
-         -out %{sslcert} 2>/dev/null
---
-SomeState
-SomeCity
-SomeOrganization
-SomeOrganizationalUnit
-${FQDN}
-root@${FQDN}
-EOF
+#%define sslcert %{_sysconfdir}/pki/tls/certs/localhost.crt
+#%define sslkey %{_sysconfdir}/pki/tls/private/localhost.key
+#
+#%post -n mod_ssl
+#umask 077
+#
+#if [ -f %{sslkey} -o -f %{sslcert} ]; then
+#   exit 0
+#fi
+#
+#%{_bindir}/openssl genrsa -rand /proc/apm:/proc/cpuinfo:/proc/dma:/proc/filesystems:/proc/interrupts:/proc/ioports:/proc/pci:/proc/rtc:/proc/uptime 2048 > %{sslkey} 2> /dev/null
+#
+#FQDN=`hostname`
+## A >59 char FQDN means "root@FQDN" exceeds 64-char max length for emailAddress
+#if [ "x${FQDN}" = "x" -o ${#FQDN} -gt 59 ]; then
+#   FQDN=localhost.localdomain
+#fi
+#
+#cat << EOF | %{_bindir}/openssl req -new -key %{sslkey} \
+#         -x509 -sha256 -days 365 -set_serial $RANDOM -extensions v3_req \
+#         -out %{sslcert} 2>/dev/null
+#--
+#SomeState
+#SomeCity
+#SomeOrganization
+#SomeOrganizationalUnit
+#${FQDN}
+#root@${FQDN}
+#EOF
 
 %check
 # Check the built modules are all PIC
@@ -569,13 +570,13 @@
 %config(noreplace) %{_sysconfdir}/logrotate.d/httpd
 
 %config(noreplace) %{_sysconfdir}/httpd/conf.d/*.conf
-%exclude %{_sysconfdir}/httpd/conf.d/ssl.conf
+#%exclude %{_sysconfdir}/httpd/conf.d/ssl.conf
 %exclude %{_sysconfdir}/httpd/conf.d/manual.conf
 
 %dir %{_sysconfdir}/httpd/conf.modules.d
 %{_sysconfdir}/httpd/conf.modules.d/README
 %config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/*.conf
-%exclude %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
+#%exclude %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
 %exclude %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf
 %exclude %{_sysconfdir}/httpd/conf.modules.d/01-ldap.conf
 %exclude %{_sysconfdir}/httpd/conf.modules.d/01-session.conf
@@ -596,7 +597,7 @@
 %dir %{_libdir}/httpd/modules
 %{_libdir}/httpd/modules/mod*.so
 %exclude %{_libdir}/httpd/modules/mod_auth_form.so
-%exclude %{_libdir}/httpd/modules/mod_ssl.so
+#%exclude %{_libdir}/httpd/modules/mod_ssl.so
 %exclude %{_libdir}/httpd/modules/mod_*ldap.so
 %exclude %{_libdir}/httpd/modules/mod_proxy_html.so
 %exclude %{_libdir}/httpd/modules/mod_xml2enc.so
@@ -648,14 +649,14 @@
 %{contentdir}/manual
 %config(noreplace) %{_sysconfdir}/httpd/conf.d/manual.conf
 
-%files -n mod_ssl
-%defattr(-,root,root)
-%{_libdir}/httpd/modules/mod_ssl.so
-%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
-%config(noreplace) %{_sysconfdir}/httpd/conf.d/ssl.conf
-%attr(0700,apache,root) %dir %{_localstatedir}/cache/httpd/ssl
-%{_libexecdir}/httpd-ssl-pass-dialog
-%{_unitdir}/httpd.socket.d/10-listen443.conf
+#%files -n mod_ssl
+#%defattr(-,root,root)
+#%{_libdir}/httpd/modules/mod_ssl.so
+#%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf
+#%config(noreplace) %{_sysconfdir}/httpd/conf.d/ssl.conf
+#%attr(0700,apache,root) %dir %{_localstatedir}/cache/httpd/ssl
+#%{_libexecdir}/httpd-ssl-pass-dialog
+#%{_unitdir}/httpd.socket.d/10-listen443.conf
 
 %files -n mod_proxy_html
 %defattr(-,root,root)
@@ -685,6 +686,12 @@
 %{_rpmconfigdir}/macros.d/macros.httpd
 
 %changelog
 * Mon Jul 18 2016 Joe Orton <jorton@redhat.com> - 2.4.23-4
 - add security fix for CVE-2016-5387
```

# 4. rpmbuildでSRPMからRPMファイルを作成する
rpmbuildでオプションを指定して実行します。

- -bb：RPMファイルのみ作成する
- --clean：パッケージ作成後にビルドツリーを削除する

```shell-session
$ rpmbuild -bb --clean httpd.spec
エラー: ビルド依存性の失敗:
	perl-generators は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	xmlto は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	zlib-devel は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	libselinux-devel は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	lua-devel は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	apr-devel >= 1.5.0 は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	apr-util-devel >= 1.5.0 は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	pcre-devel >= 5.0 は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	systemd-devel は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	libnghttp2-devel は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
	libxml2-devel は httpd-2.4.23-4.1.sample.el7.centos.x86_64 に必要とされています
```

この時点ではビルド依存性の失敗でエラーになります。


## 依存性解消の対応方針
### yumに存在したもの(私の環境で)
- xmlto
- zlib-devel
- libselinux-devel
- lua-devel
- apr-util-devel
- pcre-devel
- systemd-devel
- libxml2-devel

私の開発時の環境で上記のものはyumのリポジトリに存在しました。(それぞれ異なると思います。)
これらはyum installでインストールします。

```console
$ sudo yum install モジュール名
```

### FedoraProject(epelリポジトリ)から持ってきたもの
- perl-generators
- libnghttp2-devel

これらはyumのリポジトリに存在しなかったので、FedoraProjectのものをインストールしました。

https://dl.fedoraproject.org/pub/epel/7/x86_64/
上記のサイトからダウンロードするか、epelリポジトリをyumのリポジトリへ追加してyum installします。

あとは、apr-develの依存性を解消する必要があります。

# 残項目
- 依存性の解消の続き(apr-develのアップデート)
- (apache2.4本体を)RPMファイルでアップデートする

少し長くなりそうなので続きは別の記事にしたいと思います。
続き：[CentOS7.3のApache 2.4をRPMでアップデートする方法(2)](https://qiita.com/tomluck/items/1cbe7a9d058730a66796)