アットウィキロゴ

最新版のApache2.4のインストール【AlmaLinux 10】

標準のApacheは2.4.63で、現在では最新版より古くなっています。
そこでデフォルトリポジトリのappstreamではなく、サードパーティーのCodeIT(el10)を利用して、最新版をインストールします。
※現行の最新バージョン:2.4.67

1. 準備作業

(1) /etc/mime.types
「/etc/mime.types」が必要なのでインストールします。
なお、この「/etc/mime.types」は「mailcap」パッケージに含まれます。
# dnf install mailcap

(2) openssl
「openssl」をインストールします。
# dnf install openssl
# dnf install openssl-devel

(3) libev
「epel」リポジトリをインストールする方法は、dnfのリポジトリの追加登録方法【AlmaLinux 10】を参照して下さい。

# dnf --enablerepo=epel install libev
# dnf --enablerepo=epel install libev-devel

(4) libnghttp2
AlmaLinux8までは「powertools」リポジトリにありましたが、AlmaLinux9からは「crb」という名前に変更されています。
# dnf --enablerepo=crb install nghttp2
# dnf --enablerepo=crb install libnghttp2
# dnf --enablerepo=crb install libnghttp2-devel

(5) openldap-devel
# dnf install openldap-devel

(6) expat-devel
# dnf install expat-devel

(7) almalinux-logos
# dnf install almalinux-logos
もしくは
# dnf install system-logos

(8) libdb-devel
# dnf install libdb-devel

(9) sscg
mod_sslをインストールするために「sscg」をインストールします。
# dnf install sscg

(10) perl
# dnf install perl

2. Apache 2.4のインストール

CodeITリポジトリを利用するので、「dnfのリポジトリの追加登録方法【AlmaLinux 10】」を参照して、先に「CodeIT」リポジトリをインストールしておいて下さい。
# dnf install apr-devel
# dnf install apr-util-devel
# dnf install apr-util-ldap
# dnf install almalinux-logos-httpd

# dnf --enablerepo=CodeIT module enable httpd:codeit
# dnf --enablerepo=CodeIT install httpd
# dnf --enablerepo=CodeIT install httpd-devel
# dnf --enablerepo=CodeIT install mod_ssl
※その他のモジュールは必要に応じて選択してインストールして下さい。
# dnf --enablerepo=CodeIT install mod_ldap
# dnf --enablerepo=CodeIT install mod_session
# dnf --enablerepo=CodeIT install mod_md

3. 各ファイルの設定

ここでは一例を挙げます。サーバの環境や使用目的などによって任意に変更して下さい。
(1) /etc/httpd/conf/httpd.conf
ServerAdmin webmaster@example.jp
ServerName www.example.jp:80
<Directory "/var/www/html">
    Options FollowSymLinks IncludesNOEXEC
    AllowOverride All
    Require all granted
</Directory>
※Optionsの「Indexes」は必ず削除して下さい。

1日ごとにログを分けます。
また、死活監視用ファイル「_health.html」および画像ファイルを記録させないように設定。
ErrorLog "|/usr/sbin/rotatelogs logs/www-example.jp-error_log-%Y%m%d.log 86400 540"
 
SetEnvIf Request_URI "_health\.html|\.(gif|jpg|png|ico)$" nolog
CustomLog "|/usr/sbin/rotatelogs logs/www-example.jp-access_log-%Y%m%d.log 86400 540" combined env=!nolog

CGIを使用しない場合はコメントアウト。
<IfModule alias_module>
#    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
 
#<Directory "/var/www/cgi-bin">
#    AllowOverride None
#    Options None
#    Require all granted
#</Directory>
SSIを使用する場合に、その拡張子を指定します。
AddType text/html .html
AddOutputFilter INCLUDES .html

デフォルトの文字エンコードをOffにします。
#AddDefaultCharset UTF-8
AddDefaultCharset Off

■サイト共通・セキュリティ設定
サイト全体の共通およびセキュリティ設定ファイルを作成します。
# vi /etc/httpd/conf.d/_00-site-global.conf
KeepAlive On
KeepAliveTimeout 120
Timeout 120
ServerTokens Prod
ExtendedStatus Off
ServerSignature Off
UseCanonicalName Off
TraceEnable Off
 
<IfModule mod_headers.c>
    Header set X-XSS-Protection "1;mode=block"
    Header set X-Content-Type-Options nosniff
    Header always unset X-Powered-By
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule> 

■サイトごとの設定(VirtualHostで記述)
# vi /etc/httpd/conf.d/_01-www.example.jp.conf
<VirtualHost *:80>
    <IfModule http2_module>
        LogLevel http2:info
        ProtocolsHonorOrder On
        Protocols h2c http/1.1
        H2Direct on
    </IfModule>
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
    </IfModule>
 
  ServerName www.example.jp
 
  DocumentRoot "/var/www/html"
  <Directory "/var/www/html">
    Options FollowSymLinks IncludesNOEXEC
    AllowOverride All
    Require all granted
  </Directory>
 
  <Location "/">
    <LimitExcept GET POST HEAD>
        Require all denied
    </LimitExcept>
  </Location>
 
  TraceEnable Off
  ProxyErrorOverride on
 
  ErrorLog "|/usr/sbin/rotatelogs logs/www.example.jp-error_log-%Y%m%d.log 86400 540"
 
  SetEnvIf Request_URI "_health\.html|health\.html|\.(gif|jpg|png|ico)$" nolog
  CustomLog "|/usr/sbin/rotatelogs logs/www.example.jp-access_log-%Y%m%d.log 86400 540" combined env=!nolog
</VirtualHost> 
※複数のサイトがある場合はサイトごとに作成します。
(2) /etc/httpd/conf.d/autoindex.conf
Index機能は無効にしているので、このファイルをリネームします。
# cd /etc/httpd/conf.d
# mv autoindex.conf{,.bak} 

(3) /etc/httpd/conf.d/ssl.conf
GlobalSign SSLサーバ証明書のインストールを参照して設定して下さい。

■共通項目の抽出
先頭の共通箇所のみ残し他はサイトごとの設定にファイルを分けます。

ここでは、53行目の「SSL Viertual Host Context」の項目の前までを抽出します。
# cd /etc/conf.d
# mv ssl.conf{,.default}
# head -n 53 ssl.conf.default > ssl.conf

■サイトごとの設定
54行目以降のサイトごとの設定を抽出します。
# tail -n +54 ssl.conf.default > z_www.example.jp.ssl.conf
※ssl.confの後に読み込ませるために「z_」を付けています。

なお、1台のサーバに複数の証明書をインストールするSNI(Server Name Indication)に対応するため、以下のように変更します。
#<VirtualHost _default_:443>
<VirtualHost *:443>

DocumentRoot "/var/www/html"
ServerName www.example.jp:443

ログは通常のCustomLogを使用。
#ErrorLog logs/ssl_error_log
#TransferLog logs/ssl_access_log
ErrorLog "|/usr/sbin/rotatelogs logs/www-example.jp-error_log-%Y%m%d.log 86400 540"
SetEnvIf Request_URI "_health\.html|\.(gif|jpg|png|ico)$" nolog
CustomLog "|/usr/sbin/rotatelogs logs/www-example.jp-access_log-%Y%m%d.log 86400 540" combined env=!nolog

■その他の設定変更
TLSv1.2、TLSv1.3のみ許可します。
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLProxyProtocol -all +TLSv1.2 +TLSv1.3

SSLCipherSuiteは「PROFILE=SYSTEM」にします。
#SSLCipherSuite "EECDH+AES128:EECDH+AES256:+SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RSA+3DES:!DSS"
#SSLProxyCipherSuite "EECDH+AES128:EECDH+AES256:+SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RSA+3DES:!DSS"
SSLCipherSuite PROFILE=SYSTEM
SSLProxyCipherSuite PROFILE=SYSTEM

SSLCipherSuiteは、上記のようになっています。
これは暗号化スイートの設定作業を簡単にするため「crypto-policies」という仕組みが導入されたことによるもので、以下のライブラリをサポートしています。
  • GnuTLS library
  • OpenSSL library
  • NSS library
  • OpenJDK
  • Libkrb5
  • BIND
  • OpenSSH
  • Libreswan
ちなみにOpenSSLのデフォルト設定は「/etc/crypto-policies/back-ends/openssl.config」に記述されています。
@SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
実際にどのようなCipher Suiteが使われるかは、以下のコマンドで確認します。
# openssl ciphers -v 'PROFILE=SYSTEM'
なお、「crypto-policies」は、「LEGACY」、「DEFAULT」、「FUTURE」、「FIPS」の中から選択できます。
現在のモードは、以下のコマンドで確認するか、/etc/crypto-policies/state/current」に記載されています。
# update-crypto-policies --show
DEFAULT
この設定を変更するには「/etc/crypto-policies/config」を編集後、「update-crypto-policies」を実行します。
# vi /etc/crypto-policies/config
# update-crypto-policies
Setting system policy to FUTURE
※不用意にこの設定を変更するとSSHのログインができなくなる場合がありますので、注意して下さい。


■証明書ファイルの指定
SSLサーバ証明書+中間CA証明書を合わせたファイル名を指定します。※実際のファイル名を指定して下さい。
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/httpd/certs/latest/www.example.jp.full_cert.pem
パスフレーズを削除したサービス起動用の秘密鍵ファイル名を指定します。※実際のファイル名を指定して下さい。
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/httpd/certs/latest/www.example.jp.privkey_nopwd.pem

■設定追加
<Directory "/var/www/html">
    Options FollowSymLinks IncludesNOEXEC
    AllowOverride All
    Require all granted
</Directory>

「ssl_request_log」は出力しないようにコメントアウトします。
#CustomLog logs/ssl_request_log \
#          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

セキュリティ向上のため、DH(Diffie-Hellman)ファイルの指定を行います。
SSLOpenSSLConfCmd DHParameters /etc/httpd/certs/dhparams.pem
※上記設定のため、「z_www.example.jp.ssl.conf」編集後、DH(Diffie-Hellman)を生成します。(結構時間がかかります。)
# mkdir -p /etc/httpd/certs
# openssl dhparam -out /etc/httpd/certs/dhparams.pem 4096

(4) /etc/httpd/conf.d/userdir.conf
ユーザディレクトリ機能は使用しないのでリネームします。
※使用する場合には有効にして下さい。
# cd /etc/httpd/conf.d
# mv userdir.conf{,.bak} 

(5) /etc/httpd/conf.modules.d/00-dav.conf
WebDAV機能は使用しないのでリネームします。
※使用する場合には有効にして下さい。
# cd /etc/httpd/conf.modules.d
# mv 00-dav.conf{,.bak} 

(6) /etc/httpd/conf.modules.d/00-lua.conf
mod_luaは組み込み系スクリプト言語です。この機能も使用しないのでリネームします。
# cd /etc/httpd/conf.modules.d
# mv 00-lua.conf{,.bak} 

(7) /etc/httpd/conf.modules.d/00-mpm.conf
デフォルトの「event」のままでOKです。
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
LoadModule mpm_event_module modules/mod_mpm_event.so

(8) /etc/httpd/conf.modules.d/00-optional.conf
初期値ではすべて無効化されています。
必要なモジュールがありましたら、有効化して下さい。
#
# This file lists modules included with the Apache HTTP Server
# which are not enabled by default.
#

#LoadModule asis_module modules/mod_asis.so
#LoadModule buffer_module modules/mod_buffer.so
#LoadModule heartbeat_module modules/mod_heartbeat.so
#LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule dialup_module modules/mod_dialup.so
#LoadModule charset_lite_module modules/mod_charset_lite.so
#LoadModule log_debug_module modules/mod_log_debug.so
#LoadModule log_forensic_module modules/mod_log_forensic.so
#LoadModule ratelimit_module modules/mod_ratelimit.so
#LoadModule reflector_module modules/mod_reflector.so
#LoadModule sed_module modules/mod_sed.so
#LoadModule speling_module modules/mod_speling.so

(9) /etc/httpd/conf.modules.d/00-proxy.conf
このままでOKです。

(10) /etc/httpd/conf.modules.d/00-ssl.conf
このままでOKです。
LoadModule ssl_module modules/mod_ssl.so

(11) /etc/httpd/conf.modules.d/00-systemd.conf
このままでOKです。
# This file configures systemd module:
LoadModule systemd_module modules/mod_systemd.so

(12) /etc/httpd/conf.modules.d/01-cgi.conf
CGI機能は使用しないのでリネームします。
※使用する場合には有効にして下さい。
# cd /etc/httpd/conf.modules.d
# mv 01-cgi.conf{,.bak} 

(13) /etc/httpd/conf.modules.d/10-h2.conf
HTTP/2対応とするので必須です。既に有効化されていますので、このままでOKです。
LoadModule http2_module modules/mod_http2.so

(14) /etc/httpd/conf.modules.d/10-proxy_h2.conf
このままでOKです。
LoadModule proxy_http2_module modules/mod_proxy_http2.so

(15) /etc/httpd/conf.d/manual.conf
脆弱性として指摘される場合もあるので、これは無効にしておきます。
# cd /etc/httpd/conf.d
# mv /etc/httpd/conf.d/manual.conf{,.bak} 

(16) 設定ファイルのエラーチェック
設定ファイルにエラーがないかどうかチェックします。
# apachectl configtest
※「Syntax OK」と表示されたらOKです。

4. サービスの起動

httpdサービスの起動と自動起動設定を行います。
■ サービスの起動
# systemctl start httpd.service
■ サービスの自動起動
# systemctl enable httpd.service
その他のコマンド。
■ サービスの停止
# systemctl stop httpd.service
■ サービスの自動起動解除
# systemctl disable httpd.service
■ サービスが自動起動かどうかチェック
# systemctl is-enabled httpd.service

5. gzip圧縮の設定

アクセス速度アップのために、通信速度を短縮する「gzip圧縮」を導入します。
「/etc/httpd/conf.d」フォルダに「gzip.conf」というファイルを作成します。
※ファイル名は任意です。
# vi /etc/httpd/conf.d/gzip.conf
以下の内容を記入します。
<IfModule mod_deflate.c>
    #
    # gzip圧縮を有効にする対象
    # 主にテキスト系のみを対象にする
    #
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE font/woff
    AddOutputFilterByType DEFLATE font/woff2
 
    #
    # 既に圧縮済み、または圧縮効果が薄い拡張子は除外
    #
    SetEnvIfNoCase Request_URI \
        "\.(?:gif|jpe?g|png|webp|avif|ico|mp3|aac|ogg|m4a|mp4|mpeg|mov|avi|webm|wmv|zip|gz|tgz|bz2|xz|7z|rar|pdf|exe|iso)$" \
        no-gzip dont-vary
 
    #
    # プロキシ経由時の不整合回避で使われることがある設定
    #
    Header append Vary Accept-Encoding
</IfModule>

Apacheを再起動します。
# systemctl reload httpd.service

6. Apacheログ退避スクリプト

当日以外のApacheログをバックアップディレクトリに退避させるスクリプトです。
バックアップデバイス NFS
マウントディレクトリ /disk2
バックアップディレクトリ /disk2/__backup__/apache_log/yyyymm
バックアップログ /var/log/apache_log_backup.log
※「バックアップディレクトリ」は「/disk2/__backup__/apache_log」配下に年月ディレクトリを作成して保存
#!/usr/bin/env bash
set -euo pipefail
 
############################################################
# 設定
############################################################
LOG_DIR="/var/log/httpd"
BACKUP_BASE="/disk2/__backup__/apache_log"
BACKUP_LOG_BASE="/var/log/backup"
BACKUP_LOG_FILE="${BACKUP_LOG_BASE}/apache_log_backup.log"
 
DATE_CMD="/bin/date"
CP_CMD="/bin/cp"
RM_CMD="/bin/rm"
MV_CMD="/bin/mv"
MKDIR_CMD="/bin/mkdir"
TOUCH_CMD="/bin/touch"
CHMOD_CMD="/bin/chmod"
PRINTF_CMD="/usr/bin/printf"
BASENAME_CMD="/usr/bin/basename"
MOUNTPOINT_CMD="/usr/bin/mountpoint"
 
############################################################
# ログ出力関数
############################################################
log() {
  local msg="$1"
  local now
  now="$("${DATE_CMD}" '+%Y-%m-%d %H:%M:%S')"
  "${PRINTF_CMD}" '[%s] %s\n' "${now}" "${msg}" >> "${BACKUP_LOG_FILE}"
}
 
############################################################
# ログファイル作成
############################################################
mkdir -p ${BACKUP_LOG_BASE}
if [[ ! -e "${BACKUP_LOG_FILE}" ]]; then
  "${TOUCH_CMD}" "${BACKUP_LOG_FILE}"
  "${CHMOD_CMD}" 600 "${BACKUP_LOG_FILE}"
fi
 
############################################################
# 事前チェック
############################################################
if [[ ! -d "${LOG_DIR}" ]]; then
  log "ERROR: Apacheログディレクトリが存在しません: ${LOG_DIR}"
  exit 1
fi
 
if [[ ! -d "/disk2" ]]; then
  log "ERROR: NFSマウント先 /disk2 が存在しません"
  exit 1
fi
 
if ! "${MOUNTPOINT_CMD}" -q /disk2; then
  log "ERROR: /disk2 はマウントされていません"
  exit 1
fi
 
"${MKDIR_CMD}" -p "${BACKUP_BASE}"
 
############################################################
# 当日日付
# ファイル名内の yyyymmdd と比較する
############################################################
TODAY_YMD="$("${DATE_CMD}" '+%Y%m%d')"
TODAY_YMD_DATE="$("${DATE_CMD}" '+%Y-%m-%d')"
 
log "================================================"
log "${TODAY_YMD_DATE}"
log "================================================"
log "START: Apacheログ退避処理を開始します"
log "対象ディレクトリ: ${LOG_DIR}"
log "バックアップ先: ${BACKUP_BASE}"
log "ログ出力先: ${BACKUP_LOG_FILE}"
 
############################################################
# 対象ファイル処理
# 例:
#   www.example.jp-access_log-20260323.log
#   www.example.jp-error_log-20260323.log
############################################################
shopt -s nullglob
 
copied_count=0
skip_count=0
error_count=0
 
for filepath in "${LOG_DIR}"/*-access_log-*.log "${LOG_DIR}"/*-error_log-*.log; do
  [[ -e "${filepath}" ]] || continue
 
  filename="$("${BASENAME_CMD}" "${filepath}")"
 
  if [[ "${filename}" =~ ^.+-(access_log|error_log)-([0-9]{8})\.log$ ]]; then
    file_ymd="${BASH_REMATCH[2]}"
    file_ym="${file_ymd:0:6}"
 
    # 当日ログは退避しない
    if [[ "${file_ymd}" == "${TODAY_YMD}" ]]; then
      log "SKIP: 当日ログのため退避しません: ${filename}"
      ((skip_count+=1))
      continue
    fi
 
    dest_dir="${BACKUP_BASE}/${file_ym}"
    dest_file="${dest_dir}/${filename}"
 
    "${MKDIR_CMD}" -p "${dest_dir}"
 
    # 退避先に同名ファイルがある場合はリネームして残す
    if [[ -e "${dest_file}" ]]; then
      backup_suffix="$("${DATE_CMD}" '+%Y%m%d%H%M%S')"
      renamed_file="${dest_file}.bak.${backup_suffix}"
 
      n=1
      while [[ -e "${renamed_file}" ]]; do
        renamed_file="${dest_file}.bak.${backup_suffix}.${n}"
        ((n+=1))
      done
 
      "${MV_CMD}" "${dest_file}" "${renamed_file}"
      log "RENAME: 既存バックアップを退避しました: ${dest_file} -> ${renamed_file}"
    fi
 
    # コピー
    if "${CP_CMD}" -p "${filepath}" "${dest_file}"; then
      log "COPIED: ${filepath} -> ${dest_file}"
 
      # コピー成功後に元ファイル削除
      "${RM_CMD}" -f "${filepath}"
      log "REMOVED: 元ファイルを削除しました: ${filepath}"
 
      ((copied_count+=1))
    else
      log "ERROR: コピーに失敗しました: ${filepath} -> ${dest_file}"
      ((error_count+=1))
      continue
    fi
  else
    log "SKIP: 対象形式外のため処理しません: ${filename}"
    ((skip_count+=1))
  fi
done
 
log "END: Apacheログ退避処理が完了しました copied=${copied_count} skip=${skip_count} error=${error_count}"
exit 0
最終更新:2026年05月15日 07:52