Apacheで403を404に偽装してページの存在を隠す

Web

アクセス権限がなく403エラーが発生した際、サーバーのレスポンスを404エラーに偽装する方法を解説します。
本記事ではApache2.4準拠で説明しますが、旧バージョンも手順はほぼ同じです。

403エラーと404エラーについて

まず、403エラーが発生すると次のような内容が表示されます。

403 Forbidden

アクセス権がありません。

また、404エラーが発生すると次のような内容が表示されます。

404 Not Found

リクエストしたページは存在しません。

全て英文のケースもありますが、画面に書かれているとおりの理由です。
「404」は単純にアクセスした対象が存在しない場合に発生します。 「403」は原因が複数存在し、事例として多いのは次のとおりです。

  • サーバー設定で対象ファイルにアクセス制限を設けている (正常)
  • 対象ファイルのパーミッション設定をミスしている (不具合)
  • 対象ファイルのオーナー/グループ設定をミスしている (不具合)

403エラーを404エラーに偽装する理由

403エラーは前項で記載したように、アクセス制限を設けている際に表示されます。Webアクセス可能な管理画面に設定されていることが多いです。
ただし、403エラーをそのまま返してしまうと……

「このアドレス配下に管理画面が存在するのか」

といったように不正アクセスを試みる攻撃者に気付かれるため、セキュリティ面で対策をするのが一般的です。
実例として、403エラーとなるアクセスが404エラーになるケースを挙げます。

  • SNSの鍵アカに対して権限のない人がプロフィール画面を見ようとした時
  • GitHubで権限のない人がリソースを取得しようとした時
  • Amazon S3で権限のない人がリソースを取得しようとした時

confファイルで設定する場合

バーチャルホスト毎に設定したいため、ドメインのconfファイルを編集します。

/etc/apache2/sites-available/your-domain.tld.conf<VirtualHost *:8080>
    ServerName your-domain.tld
    DocumentRoot /var/www/your-domain.tld/public
    DirectoryIndex index.php index.html index.htm
    ErrorDocument 403 /missing.html
    RewriteEngine On
    RewriteRule missing.html - [R=404,L]
</VirtualHost>

ドキュメントルートにmissing.htmlを作成する必要はありません。 変更したら構文チェックを行います。

sudo apache2ctl -t

最後にApacheを再起動して設定を反映しましょう。

sudo systemctl restart apache2

.htaccessで設定する場合

やることはconfファイルの場合とほぼ同じです。
ドキュメントルートより1階層上で設定するのがよいでしょう。

/var/www/your-domain.tld/.htaccessErrorDocument 403 /missing.html
RewriteEngine On
RewriteRule missing.html - [R=404,L]

.htaccessを弄る場合、500エラー(Internal Server Error)が起きる可能性があります。事前にローカル環境で動作確認したうえで反映作業を行いましょう。

WordPress環境での活用

以前投稿したサーバー構築記事では省いていた内容となります。
固定IPが利用できる環境の場合、ログイン画面と管理画面のURLに対してアクセス制限する対応を載せていますが、この際に表示されるApache標準の403ページをWordPressの404ページに置き換える対応を行います。

まず、ドメインのconfファイルを編集します。

/etc/apache2/sites-available/your-domain.tld.conf<VirtualHost *:8080>
    ServerName your-domain.tld
    DocumentRoot /var/www/your-domain.tld/public
    DirectoryIndex index.php index.html index.htm
    ErrorDocument 403 /404.php
    <Directory "/var/www/your-domain.tld/public">
        AllowOverride All
        <Files wp-login.php>
            Require ip xxx.xxx.xxx.xxx
        </Files>
    </Directory>
    <Directory "/var/www/your-domain.tld/public/wp-admin">
        Require ip xxx.xxx.xxx.xxx
        <FilesMatch "(admin-ajax.php)$">
            Require all granted
        </FilesMatch>
    </Directory>
</VirtualHost>

次に403エラー発生時に処理を行う404.phpをドキュメントルートに作成します。 $urlはWordPressの404ページを取得できるものに各自修正してください。

./404.php<?php
$url = 'https://your-domain.tld/404-not-found';
$context = stream_context_create([
    'http' => ['ignore_errors' => true]
]);

header('HTTP/1.0 404 Not Found');
echo file_get_contents($url, false, $context);

準備が整ったらApacheを再起動します。

sudo systemctl restart apache2

これで対応完了となります。

以上です。

タイトルとURLをコピーしました