[AWS]最新版のApache2.4のインストール【AlmaLinux 10】
標準のApacheは2.4.63で、現在では最新版より古くなっています。
そこでデフォルトリポジトリのappstreamではなく、サードパーティーのCodeIT(el10)を利用して、最新版をインストールします。
※現行の最新バージョン:2.4.66
1. 準備作業
(1) /etc/mime.types
「/etc/mime.types」が必要なのでインストールします。
なお、この「/etc/mime.types」は「mailcap」パッケージに含まれます。
(2) openssl
「openssl」をインストールします。
# dnf install openssl
# dnf install openssl-devel
(3) libev
# dnf --enablerepo=epel install libev
# dnf --enablerepo=epel install libev-devel
(4) libnghttp2
※ALBを使用する場合には「nghttp2」、「libnghttp2」、「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
※ALBを使用する場合には「sscg」はインストールしません。
(10) perl
2. Apache 2.4のインストール
# 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_ldap
# dnf --enablerepo=CodeIT install mod_session
# dnf --enablerepo=CodeIT install mod_md
※ALBを使用する場合には「mod_ssl」はインストールしません。
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」は必ず削除して下さい。
※ALB経由の場合にはALBのIPアドレスが記録されてしまうので、「X-Forwarded-For」ヘッダを追記します。
これによりきちんとアクセス元のIPアドレスが記録されます。
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
1日ごとにログを分けます。
また、死活監視用ファイル「_health.html」および画像ファイルを記録させない設定にします。
なお、ALBを使用している場合には、ELB-HealthCheckerのログが大量に書き込まれるので、これを抑止します。
ErrorLog "|/usr/sbin/rotatelogs logs/www-example.jp-error_log-%Y%m%d.log 86400 540"
SetEnvIf User-Agent "ELB-HealthChecker.*" nolog
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
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>
RemoteIPHeader X-Forwarded-For
ServerName www.example.jp
ServerAlias ec2-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 User-Agent "ELB-HealthChecker.*" nolog
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
</VirtualHost>
※アクセス元のIPアドレスを取得するため「RemoteIPHeader X-Forwarded-For」を追記します。
(2) /etc/httpd/conf.d/autoindex.conf
Index機能は無効にしているので、このファイルをリネームします。
# cd /etc/httpd/conf.d
# mv autoindex.conf{,.bak}
(3) /etc/httpd/conf.d/ssl.conf
※ALBを使用する場合はこのファイルは使用しません。ファイルが存在した場合はリネームして下さい。
# cd /etc/httpd/conf.d
# mv ssl.conf{,.bak}
(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
※ALBを使用する場合はこのファイルは使用しません。ファイルが存在した場合はリネームして下さい。
# cd /etc/httpd/conf.modules.d
# mv 10-h2.conf{,.bak}
(14) /etc/httpd/conf.modules.d/10-proxy_h2.conf
※ALBを使用する場合はこのファイルは使用しません。ファイルが存在した場合はリネームして下さい。
# cd /etc/httpd/conf.modules.d
# mv 10-proxy_h2.conf{,.bak}
(15) /etc/httpd/conf.d/manual.conf
脆弱性として指摘される場合もあるので、ファイルが存在した場合は無効にしておきます。
# cd /etc/httpd/conf.d
# mv manual.conf{,.bak}
(16) logrotateの無効化
logrotateでApacheのログは自動的に整理されますが、ログを日ごとに管理している場合に自動的に整理されると不都合を生じますので、この機能を解除します。
※デフォルトの場合はこのまま有効化しておいて下さい。
vi /etc/logrotate.d/httpd
ファイルの内容をコメントアウトします。
#/var/log/httpd/*log {
# missingok
# notifempty
# sharedscripts
# postrotate
# /sbin/service httpd reload > /dev/null 2>/dev/null || true
# endscript
#}
(17) 設定ファイルのエラーチェック
設定ファイルにエラーがないかどうかチェックします。
※「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ログをS3バケットに退避させるスクリプトです。
| バックアップデバイス |
S3 |
| バケット名 |
example-jp-s3-backup |
| バックアップディレクトリ |
/apache_log/yyyymm |
| バックアップログ |
/var/log/backup/apache_log_backup.log |
※「バックアップディレクトリ」は「example-jp-s3-backup/apache_log」配下に年月ディレクトリを作成して保存
#!/usr/bin/env bash
set -euo pipefail
############################################################
# 設定
############################################################
LOG_DIR="/var/log/httpd"
# S3設定
S3_BUCKET="example-jp-s3-backup"
# Apacheログバックアップ保存先プレフィックス
S3_PREFIX="apache_log"
# ログ出力
BACKUP_LOG_FILE_BASE="/var/log/backup"
BACKUP_LOG_FILE="${BACKUP_LOG_FILE_BASE}/backup_apache_log.log"
# コマンド定義
DATE_CMD="/bin/date"
RM_CMD="/bin/rm"
MKDIR_CMD="/bin/mkdir"
TOUCH_CMD="/bin/touch"
CHMOD_CMD="/bin/chmod"
PRINTF_CMD="/usr/bin/printf"
BASENAME_CMD="/usr/bin/basename"
AWS_CMD="/usr/local/bin/aws"
############################################################
# ログ出力関数
############################################################
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}"
}
############################################################
# S3オブジェクト存在確認
# 存在する: 0
# 存在しない: 1
############################################################
s3_object_exists() {
local bucket="$1"
local key="$2"
if "${AWS_CMD}" s3api head-object --bucket "${bucket}" --key "${key}" >/dev/null 2>&1; then
return 0
else
return 1
fi
}
############################################################
# ログファイル作成
############################################################
"${MKDIR_CMD}" -p "${BACKUP_LOG_FILE_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 [[ ! -x "${AWS_CMD}" ]]; then
log "ERROR: AWS CLI が見つかりません: ${AWS_CMD}"
exit 1
fi
# バケット存在確認
if ! "${AWS_CMD}" s3api head-bucket --bucket "${S3_BUCKET}" >/dev/null 2>&1; then
log "ERROR: S3バケットにアクセスできません: ${S3_BUCKET}"
exit 1
fi
############################################################
# 当日日付
# ファイル名内の 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 "バックアップ先: s3://${S3_BUCKET}/${S3_PREFIX}/"
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
s3_key="${S3_PREFIX}/${file_ym}/${filename}"
s3_uri="s3://${S3_BUCKET}/${s3_key}"
# 退避先に同名オブジェクトがある場合はリネームして残す
if s3_object_exists "${S3_BUCKET}" "${s3_key}"; then
backup_suffix="$("${DATE_CMD}" '+%Y%m%d%H%M%S')"
renamed_key="${s3_key}.bak.${backup_suffix}"
renamed_uri="s3://${S3_BUCKET}/${renamed_key}"
n=1
while s3_object_exists "${S3_BUCKET}" "${renamed_key}"; do
renamed_key="${s3_key}.bak.${backup_suffix}.${n}"
renamed_uri="s3://${S3_BUCKET}/${renamed_key}"
((n+=1))
done
if "${AWS_CMD}" s3 mv "${s3_uri}" "${renamed_uri}" >/dev/null; then
log "RENAME: 既存バックアップを退避しました: ${s3_uri} -> ${renamed_uri}"
else
log "ERROR: 既存バックアップの退避に失敗しました: ${s3_uri} -> ${renamed_uri}"
((error_count+=1))
continue
fi
fi
# S3へアップロード
if "${AWS_CMD}" s3 cp "${filepath}" "${s3_uri}" >/dev/null; then
log "COPIED: ${filepath} -> ${s3_uri}"
# アップロード成功後に元ファイル削除
"${RM_CMD}" -f "${filepath}"
log "REMOVED: 元ファイルを削除しました: ${filepath}"
((copied_count+=1))
else
log "ERROR: S3アップロードに失敗しました: ${filepath} -> ${s3_uri}"
((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月20日 13:49