Apacheでメンテナンスページを設定する方法

## はじめに
EC2のメンテナンス時などに、作業者など特定のユーザーには通常のページを表示させ、
それ以外のリクエストにはメンテナンスページを表示させる設定をする機会がありましたので、自分の備忘録を兼ねて記事にします。
送信元IPを判断することで表示させるページの制御を行いますが、今回は以下の構成のように、EC2の前段にALBがいて、そのままでは送信元IPはALBのIPが表示される状況を想定します。

## 構成
![ALB-EC2.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/e2d3dd57-30fd-47c2-b7dc-868036b0cd16.png)

## 前提
・AWS等の各リソースは作成済みであること
・WEBページにはインターネット経由でアクセス確認を行う
・許可したいアクセスの送信元のアドレスを確認(本記事では☓☓☓.☓☓☓.☓☓☓.☓☓☓とします)
・メンテナンスページを用意していること
今回は以下のようなページを用いて稼働確認しました。
```php:maintenance.html
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>メンテナンス中</title>
</head>
<body>
    <p>メンテナンス中です</p>
</body>
</html>
```
## やること
DocumentRoot直下にmaintenance.htmlのページを配置します。
 httpd.conf や VirtualHost の設定を確認して、DocumentRootを確認してください。

 
次に.htaccessファイルにリダイレクト設定を行います。
.htaccessファイルに以下の設定を記述します。

```php:.htaccess
    # --- 503 Error Handling Configuration ---
     ErrorDocument 503 /maintenance.html
     RewriteEngine On
     RewriteCond %{REQUEST_URI} !/maintenance.html
     RewriteCond %{REQUEST_FILENAME} !^(.*)\.(jpg|png|css)$
     RewriteCond %{HTTP:X-Forwarded-For} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
     RewriteRule ^.*$ - [R=503,L]
```
※☓☓☓の部分は許可したいアクセスの送信元アドレスに置き換えてください。
具体的な意味は以下になります。
```php:.htaccess
ErrorDocument 503 /maintenance.html
```
→ HTTP 503エラー（サービス利用不可）が発生した場合、/maintenance.html を表示します。
```php:.htaccess
RewriteEngine On
```
→ Apacheのリライトモジュール（mod_rewrite） を有効にして、メンテナンスページへのリダイレクトを行えるようにします。
```php:.htaccess
RewriteCond %{REQUEST_URI} !/maintenance.html
```
→ /maintenance.html へのリクエストは503エラーの対象外（アクセス許可）とします。
これがないと、503エラーのページ自体も503になってしまい、無限ループになる可能性があります。
```php:.htaccess
RewriteCond %{REQUEST_FILENAME} !^(.*)\.(jpg|png|css)$
```
→ .jpg, .png, .css のリクエストは503エラーにしないようにします。
メンテナンス中でも画像やCSSを読み込ませるための設定になります。
※今回のメンテナンスページでは画像やCSSは使っていないので、この設定は削除しても問題ありません。
```php:.htaccess
RewriteCond %{HTTP:X-Forwarded-For} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
```
→ このIPアドレス（例：☓☓☓.☓☓☓.☓☓☓.☓☓☓）以外からのアクセスは503エラーにします(メンテナンスページを表示させます)。
また許可したいIPアドレスが複数ある場合は、以下のように複数行設定することも可能です。
```php:.htaccess
RewriteCond %{HTTP:X-Forwarded-For} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
RewriteCond %{HTTP:X-Forwarded-For} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
```
なお今回はロードバランサー（ALBなど）を経由している環境のため「X-Forwarded-For」を使っていますが、ロードバランサーがなくEC2単体での運用であれば 
```php:.htaccess
RewriteCond %{REMOTE_ADDR} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
```
を使う必要があります。
```php:.htaccess
RewriteRule ^.*$ - [R=503,L]
```
→ 503エラーを強制適用（HTTPステータス503を返す）
→ [L] は このルールが適用されたら、以降のルールを評価せず終了する という意味になります。

以上の設定は、メンテナンスページを503エラーとして適用しつつ、
特定のIPアドレス（☓☓☓.☓☓☓.☓☓☓.☓☓☓）のユーザーは通常アクセスを可能とさせ、それ以外の全リクエストは503エラーにするという設定になります。

## 確認
.htaccessファイルに上記の設定後、以下の設定を「#」で無効化して、全てのリクエストでメンテナンスページが表示されることを確認します。
```php:.htaccess
#RewriteCond %{HTTP:X-Forwarded-For} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
```
![スクリーンショット 2025-01-30 103028メンテナンス表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/175bc44c-1eb3-4958-8f86-e335aa8dbce5.png)

想定通り、メンテナンス中ですのコメントが表示されることが確認できればメンテナンスページの設定は大丈夫です。

その後、設定の「#」を外して、許可しているアドレスからアクセスを行い、通常のページが表示されることを確認します。
```php:.htaccess
 RewriteCond %{HTTP:X-Forwarded-For} !^☓☓☓\.☓☓☓\.☓☓☓\.☓☓☓$
```
通常のページが表示されれば設定は完了です。
可能であれば、許可していないアドレスからもアクセスを行い、メンテナンスページが表示されることを確認してください。
## まとめ
今回、Apacheの.htaccessを利用してメンテナンスページを表示する設定を行いました。作業を通じて、Apacheのエラーページ設定やリダイレクト処理の仕組みを改めて理解することができました。
また、特定のIPアドレスを除外することで、作業者のみ通常アクセスが可能になる仕組みも、運用面で非常に便利だと感じました。

今後も、メンテナンス時の表示方法やリダイレクトの挙動について理解し、より柔軟な設定ができるよう知識を深めていきたいと思います。