Ubuntu 24.04 Apache2 設定手順

1分で読めるサマリー

この手順で達成できること:Ubuntu 24.04 上に、HTTPS 対応の安全な Web サーバーを構築できる。SSL 証明書は無料で取得でき、自動更新されるため運用負荷が低い。

前提条件

主要な手順

  1. Apache2 をインストールし、基本設定を実施(手順 1〜5)
  2. Let's Encrypt で無料の SSL 証明書を取得(手順 6〜7)
  3. HTTPS を有効化し、HTTP からのリダイレクトを設定(手順 8〜10)
  4. 証明書の自動更新を確認(手順 11)
  5. 動作確認(手順 12)
  6. オプション:高速化設定(Gzip 圧縮、KeepAlive、ブラウザキャッシュ)(手順 13〜15)
  7. オプション:不正アクセス自動遮断(fail2ban)(手順 16〜18)

重要な注意事項

費用:すべて無料(Let's Encrypt の SSL 証明書は無料で取得でき、更新も無料)

本手順の設定値(例)

目次

セキュリティに関する注意事項

本手順には基本的なセキュリティ設定を含むが、以下の点に留意する必要がある。

事前に決定しておく事項

本手順を実施する前に、以下の項目を決定しておく。

項目本手順での設定値説明
ドメイン名www.example.jpWeb サイトの URL に使用するドメイン
ドキュメントルート/wwwWeb コンテンツを配置するディレクトリ
アクセスログのパス/var/log/apache2/www.example.jp-access.logアクセス記録の保存先
エラーログのパス/var/log/apache2/www.example.jp-error.logエラー記録の保存先
ログ形式commonIP、日時、リクエスト、ステータスを記録

注意:上記の値は自身の環境に合わせて読み替える。本手順中の www.example.jp は、すべて自身のドメイン名に置き換える。

前提条件

本手順を実施する前に、以下の条件を満たしていることを確認する。

補足:ファイアウォール設定は本手順の範囲外である。使用しているファイアウォールソフトウェア(ufw、iptables 等)のマニュアルを参照し、事前に設定を完了させる。

用語説明

用語説明
ドキュメントルートWeb サーバーが公開するファイルを配置するディレクトリ
仮想ホスト1台のサーバーで複数のドメインを運用するための設定単位
SSL/TLS通信を暗号化するプロトコル。HTTPS はこれを使用する
Let's Encrypt無料で SSL 証明書を発行する認証局。証明書の有効期間は 90 日間
webroot 方式既存の Web サーバーを利用して Let's Encrypt の認証を実施する方式。サーバーを停止せずに証明書を取得できる
common 形式Apache のログ形式の一つ。IP アドレス、日時、リクエスト内容、ステータスコード、転送バイト数を記録する
HSTSHTTP Strict Transport Security の略。ブラウザに HTTPS 接続を強制する仕組み
暗号スイートSSL/TLS 通信で使用する暗号化アルゴリズムの組み合わせ。安全性と互換性のバランスを考慮して選択する

設定手順の流れ

本手順は以下の順序で進める。

段階作業内容HTTP(80番)HTTPS(443番)
手順 1〜5Apache 導入と HTTP 設定通常公開未設定
手順 6HTTP 動作確認通常公開未設定
手順 7証明書取得認証に使用未設定
手順 8〜10HTTPS 設定とリダイレクトリダイレクト公開
手順 11〜12自動更新確認と動作確認リダイレクト公開
手順 13〜15高速化設定(オプション)リダイレクト公開
手順 16〜18不正アクセス対策(オプション)リダイレクト公開
手順 19総合的な動作確認リダイレクト公開

この順序で作業する理由:Let's Encrypt は HTTP(80番ポート)経由で認証を実施する。証明書取得前は HTTP で通常公開し、証明書取得後に HTTPS を有効化してリダイレクトを設定する必要がある。

1. Apache2 のインストール

目的:Web サーバーソフトウェアをシステムに導入する。

sudo apt update
sudo apt install -y apache2

確認

sudo systemctl status apache2

「active (running)」と表示されれば成功。インストール後、Apache は自動的に起動し、OS 起動時にも自動起動する。

2. Apache セキュリティ基本設定

目的:バージョン情報を非表示にし、攻撃者による脆弱性特定を困難にする。

設定ファイルを開く。

sudo nano /etc/apache2/conf-available/security.conf

以下の項目を変更する。

# 変更前:ServerTokens OS
# 変更後:
ServerTokens Prod

# 変更前:ServerSignature On
# 変更後:
ServerSignature Off

設定を有効化する。

sudo a2enconf security
sudo systemctl reload apache2

設定項目の説明

3. ドキュメントルートの作成

目的:Web コンテンツを配置する専用ディレクトリを作成し、適切な権限を設定する。

sudo mkdir -p /www
sudo chown -R www-data:www-data /www
sudo chmod -R 755 /www

権限設定の理由:Apache は www-data という権限の低いユーザーとして動作する。パーミッション 755 は、所有者が読み書き実行可能、その他は読み取りと実行のみ可能な設定である。

確認

ls -ld /www

「drwxr-xr-x」と表示され、所有者が「www-data」であれば成功。

4. HTTP 用仮想ホスト設定の作成

目的:HTTP(80番ポート)でアクセス可能な Web サイトの基本設定を作成する。この設定は証明書取得に必要である。

重要:この段階ではリダイレクト設定を含めない。Let's Encrypt の証明書取得には HTTP(80番ポート)でのアクセスが必要である。リダイレクト設定は手順 9 で実施する。

sudo nano /etc/apache2/sites-available/www.example.jp.conf

以下を記述する。

<VirtualHost *:80>
    ServerName www.example.jp
    DocumentRoot /www

    <Directory /www>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    # .well-knownディレクトリへのアクセスを原則禁止
    <Directory "/www/.well-known">
        Require all denied
    </Directory>

    # ACME認証用ディレクトリのみ許可
    <Directory "/www/.well-known/acme-challenge">
        Require all granted
    </Directory>

</VirtualHost>

設定項目の説明

5. HTTP サイトの有効化

目的:作成した設定を有効化し、デフォルト設定を無効化する。

sudo a2dissite 000-default.conf
sudo a2ensite www.example.jp.conf
sudo systemctl reload apache2

デフォルトサイトを無効化する理由:デフォルト設定は、ドメイン名を指定しないアクセスに応答するため、意図しない情報漏洩のリスクがある。

確認

apache2ctl -S

「www.example.jp.conf」が表示され、「000-default.conf」が表示されなければ成功。

6. HTTP アクセスの確認

目的:証明書取得の前に、HTTP でアクセスできることを確認する。これにより、DNS 設定とファイアウォール設定の正常性を検証できる。

# テスト用ファイルの作成
echo "test" | sudo tee /www/index.html

# アクセス確認
curl -I http://www.example.jp

成功の判定HTTP/1.1 200 OK が表示されれば成功。

失敗した場合の確認事項

7. Let's Encrypt 証明書の取得

目的:webroot 方式により、HTTPS 通信に必要な SSL 証明書を取得する。

DNSによる認証の場合は、 sudo certbot certonly --manual --preferred-challenges dns -d www.example.jp を実行

sudo apt install -y certbot
sudo mkdir -p /www/.well-known/acme-challenge
sudo chown www-data:www-data /www/.well-known/acme-challenge
sudo certbot certonly --webroot -w /www -d www.example.jp

webroot 方式の仕組み:certbot は /www/.well-known/acme-challenge/ に認証用ファイルを配置する。Let's Encrypt のサーバーは HTTP 経由でこのファイルにアクセスし、ドメインの所有権を確認する。Web サーバーを停止する必要はない。

成功の判定:以下のディレクトリに証明書ファイルが作成される。

/etc/letsencrypt/live/www.example.jp/

確認

sudo ls -l /etc/letsencrypt/live/www.example.jp/

「fullchain.pem」と「privkey.pem」が存在すれば成功。

失敗した場合の確認事項

8. HTTPS 用仮想ホスト設定の作成

目的:HTTPS(443番ポート)での安全な通信を有効化し、セキュリティヘッダーとログ記録を設定する。

重要:セキュリティヘッダーの設定には headers モジュールが必要である。このモジュールは手順 10 で有効化する。

sudo nano /etc/apache2/sites-available/www.example.jp-ssl.conf

以下を記述する。

<VirtualHost *:443>
    ServerName www.example.jp
    DocumentRoot /www

    # SSL 設定
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/www.example.jp/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/www.example.jp/privkey.pem

    # SSL プロトコル設定(古い脆弱なプロトコルを無効化)
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

    # 暗号スイート設定
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    SSLHonorCipherOrder off

    # セキュリティヘッダー
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"

    # ドキュメントルート設定
    <Directory /www>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    # .well-knownディレクトリへのアクセスを原則禁止
    <Directory "/www/.well-known">
        Require all denied
    </Directory>

    # ACME認証用ディレクトリのみ許可
    <Directory "/www/.well-known/acme-challenge">
        Require all granted
    </Directory>

    # ログ設定
    ErrorLog ${APACHE_LOG_DIR}/www.example.jp-error.log
    CustomLog ${APACHE_LOG_DIR}/www.example.jp-access.log common
</VirtualHost>

セキュリティ設定の説明

設定項目目的詳細
SSLProtocol安全なプロトコルのみ使用SSLv3、TLSv1、TLSv1.1 を無効化し、TLSv1.2 以上のみ許可
SSLCipherSuite安全な暗号化方式のみ使用ECDHE と GCM を使用した暗号スイートを選択
SSLHonorCipherOrder暗号スイート選択の制御off に設定し、クライアントの優先順位を尊重
Strict-Transport-SecurityHTTPS 接続を強制ブラウザに HTTPS 接続を強制(HSTS)。max-age=31536000 は1年間有効
X-Frame-Optionsクリックジャッキング攻撃を防止他のサイトから iframe で埋め込まれることを防止
X-Content-Type-OptionsMIME タイプスニッフィングを防止ブラウザが独自にファイル種別を判定することを防止
Referrer-Policyリファラー情報の送信を制御同一サイト内ではフルパスを送信、外部サイトへはオリジンのみ送信

ログ形式 common の出力例

192.168.1.100 - - [20/Jan/2026:12:34:56 +0900] "GET /index.html HTTP/1.1" 200 1234

この形式は、IP アドレス、日時、リクエスト内容、ステータスコード、転送バイト数を記録する。

9. HTTP 設定をリダイレクトに変更

目的:HTTP アクセスを HTTPS へ自動転送し、すべての通信を暗号化する。

HTTPS の準備が整ったため、手順 4 で作成した HTTP 設定ファイルを書き換え、HTTPS へリダイレクトするよう変更する。

sudo nano /etc/apache2/sites-available/www.example.jp.conf

内容を以下に変更する。

<VirtualHost *:80>
    ServerName www.example.jp
    Redirect permanent / https://www.example.jp/
</VirtualHost>

Redirect permanent の意味:HTTP ステータスコード 301(恒久的な移動)を返す。ブラウザと検索エンジンは、このサイトが HTTPS に完全移行したことを認識する。

10. 必要なモジュールの有効化と設定の反映

目的:SSL 通信とセキュリティヘッダーに必要なモジュールを有効化し、HTTPS 設定を反映する。

sudo a2enmod ssl
sudo a2enmod headers
sudo a2ensite www.example.jp-ssl.conf
sudo systemctl reload apache2

各モジュールの役割

確認

apache2ctl -M | grep -E 'ssl|headers'

「ssl_module」と「headers_module」が表示されれば成功。

11. 証明書自動更新の確認

目的:証明書の自動更新が正常に動作することを検証する。

sudo certbot renew --dry-run

--dry-run オプションの意味:テスト実行であり、実際の更新は実施されない。エラーが出なければ自動更新が正しく機能する。

確認

sudo systemctl list-timers | grep certbot

「certbot.timer」が表示され、次回実行時刻が表示されれば成功。

証明書自動更新の仕組み

certbot のインストール時に systemd タイマーが設定され、定期的に更新確認が実行される。証明書の有効期限が 30 日以内になると、自動的に更新が試行される。

自動更新が失敗する主な原因

定期的な手動確認を推奨する(運用上の注意事項を参照)。

12. 動作確認

目的:すべての設定が正しく機能していることを確認する。

12.1 基本動作の確認

# HTTP から HTTPS へのリダイレクトを確認
curl -I http://www.example.jp

# HTTPS でのアクセスを確認
curl -I https://www.example.jp

成功の判定

12.2 セキュリティヘッダーの確認

curl -I https://www.example.jp

以下のヘッダーが含まれていることを確認する。

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin

ヘッダーが表示されない場合:headers モジュールが有効化されているか確認する(手順 10 を再実行)。

12.3 サーバー情報の非表示確認

curl -I https://www.example.jp

レスポンスヘッダーの Server:Apache のみとなり、バージョン番号が表示されていないことを確認する。

バージョン番号が表示される場合:手順 2 の設定が正しく反映されているか確認する。

高速化設定(オプション)

本セクションでは、Web サーバーのレスポンス速度を向上させる設定を実施する。

13. Deflate 圧縮の有効化

目的:テキストベースのファイル(HTML、CSS、JavaScript 等)を圧縮して転送し、転送量を削減する。

期待される効果:転送量を 60〜80% 削減できる。

sudo a2enmod deflate
sudo systemctl restart apache2

圧縮対象の設定

sudo cat /etc/apache2/mods-available/deflate.conf

以下の内容であることを確認する(デフォルトで設定済み)。

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
    AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/ecmascript
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/wasm
    AddOutputFilterByType DEFLATE application/xml
</IfModule>

確認

curl -H "Accept-Encoding: gzip" -I https://www.example.jp

「Content-Encoding: gzip」が表示されれば成功。

注意:画像ファイル(JPEG、PNG、GIF)や動画ファイルは既に圧縮されているため、対象に含めない。

14. KeepAlive の最適化

目的:HTTP コネクションを再利用し、接続確立のオーバーヘッドを削減する。

期待される効果:複数のファイルを読み込むページで、読み込み時間を 30〜50% 削減できる。

sudo nano /etc/apache2/apache2.conf

以下の項目を確認する。

# KeepAlive を有効化
KeepAlive On

# 1つのコネクションで処理できるリクエスト数
MaxKeepAliveRequests 100

# KeepAlive タイムアウト(秒)
KeepAliveTimeout 5

設定項目の説明

設定変更を行った場合は、次のコマンドにより反映する。

sudo systemctl restart apache2

確認

curl -v -I https://www.kkaneko.jp 2>&1 | grep -i "connection"