1.

非推奨である理由(性能問題)

▶
この記事の要点
  • Apache 公式は「設定ファイルを編集できるなら .htaccess は使わない」ことを推奨している。理由は性能とセキュリティ
  • 性能の問題: AllowOverride が有効だと、リクエストのたびにパス上の全ディレクトリで .htaccess を探し、見つかれば読み込む
  • .htaccess 内の RewriteRule の正規表現もリクエストごとに処理し直される
  • 同じ設定を httpd.conf の <Directory> に書けば、起動時に 1 回読むだけで済む
  • 共有レンタルサーバーなど設定ファイルを触れない環境では、.htaccess を使うのが正しい選択

結論:設定ファイルを編集できるなら httpd.conf に書く

Apache HTTP Server の公式ドキュメント(.htaccess のチュートリアル)では、「メインのサーバー設定ファイルを編集できる場合は .htaccess の使用は避けるべき」と説明されています。理由は大きく性能とセキュリティの 2 つで、本稿では性能問題を中心に説明します。

.htaccess は「サーバー全体の設定を変更する権限がない人が、ディレクトリ単位で設定を変えるための仕組み」です。共有レンタルサーバーのように httpd.conf を編集できない環境のための手段であって、権限がある場合に積極的に使うものではありません。

なぜ遅くなるのか(仕組み)

1. リクエストごとにファイルを探す

サーバーが .htaccess の設定を許可している(AllowOverride が None 以外)と、Apache はリクエストのたびに各ディレクトリ内に .htaccess があるかどうかを探します。探す対象は、要求されたファイルのディレクトリだけではなく、上位のすべてのディレクトリです。

例えば /www/htdocs/example/index.html へのリクエストでは、次の 4 ファイルの存在確認が行われます。

/.htaccess
/www/.htaccess
/www/htdocs/.htaccess
/www/htdocs/example/.htaccess

ファイルが存在しなくても確認自体は毎回発生します。画像・CSS・JavaScript を含め、1 ページを表示するのに数十リクエストあれば、そのすべてでこの探索が行われます。

2. 見つかったファイルを毎回読み込み・解釈する

.htaccess が見つかった場合、その内容はキャッシュされず、リクエストのたびに読み込まれて設定として解釈されます。これによりファイルを保存した瞬間に設定が反映されるという利点がある一方、処理コストが毎回かかります。

3. RewriteRule の処理が重くなる

mod_rewrite の RewriteRule を .htaccess に書くと、正規表現がそのディレクトリへのリクエストごとに処理し直されます。また、ディレクトリ単位のコンテキストではパスの接頭辞を外してから照合し、書き換え後に内部的にリクエストをやり直すため、サーバー設定に書く場合より手順が多くなります。

対処法:.htaccess の内容を httpd.conf に移す

以下のように .htaccess の内容をサーバーの設定ファイルである httpd.conf(または VirtualHost の設定ファイル)の <Directory> セクションに記載することで、リクエスト毎ではなくサーバーの起動時(または再読み込み時)に一度だけ読み込まれるようになるので、パフォーマンス的に優れています。

/www/htdocs/example の .htaccess ファイルの内容

AddType text/example .exm

httpd.conf のセクション

<Directory "/www/htdocs/example">
    AddType text/example .exm
</Directory>

移行の手順は次のとおりです。

  1. 既存の .htaccess の内容を、対応するディレクトリの <Directory> ブロックへコピーする
  2. RewriteRule を移す場合は、パターンの書き方の違いに注意する(下記)
  3. そのディレクトリの AllowOverride を None にして、.htaccess の探索自体を止める
  4. apachectl configtest で文法を確認し、再読み込みする
  5. 動作確認後、不要になった .htaccess を削除する(残っていても AllowOverride None なら読まれない)
<Directory "/www/htdocs">
    AllowOverride None
    Require all granted
</Directory>

Apache 2.3.9 以降は AllowOverride の既定値が None になっています。ただし、ディストリビューションの初期設定や WordPress などの導入手順で All に変更されていることが多いので、実際の設定を確認してください。

RewriteRule を移すときの注意

.htaccess(ディレクトリ単位)ではディレクトリ部分を除いたパスに対して照合しますが、<VirtualHost> などのサーバー単位に書くと先頭のスラッシュを含む URL パスに対して照合します。そのため ^about$ のようなパターンは、場所によって ^/about$ への書き換えが必要です。<Directory> ブロック内に書く場合は .htaccess と同じ扱いになります。

どのくらい遅くなるのか

影響の大きさは、ディレクトリ階層の深さ、.htaccess の中身(特に RewriteRule の数)、ファイルシステムの速度、アクセス数によって変わるため、一概には言えません。小規模なサイトでは体感できる差にならないことも多く、だからこそ多くの環境で有効なまま運用されています。

自分の環境で影響を確かめたい場合は、同じ URL に対して設定を切り替えて負荷テストを比較します。

# AllowOverride All の状態で計測
ab -n 5000 -c 50 http://localhost/example/index.html

# 設定を httpd.conf に移し AllowOverride None にして再計測
ab -n 5000 -c 50 http://localhost/example/index.html

Linux であれば strace -f -e trace=open,openat,stat -p (httpd のプロセスID) で、リクエストごとに .htaccess を探すシステムコールが発生している様子を確認することもできます。

もう一つの理由:セキュリティ

.htaccess を許可すると、そのディレクトリに書き込める人なら誰でもサーバーの挙動を変えられます。Web アプリの脆弱性でファイルをアップロードされた場合に、.htaccess を置かれて PHP の実行設定などを変えられる危険もあります。許可が必要な場合でも AllowOverride で必要な種類(FileInfo、AuthConfig など)だけに絞るか、AllowOverrideList で使えるディレクティブを個別に指定します。

.htaccess を使ってよいケース

  • 共有レンタルサーバーで httpd.conf を編集できない
  • WordPress のパーマリンクなど、アプリが .htaccess の自動書き換えを前提にしており、その運用を優先したい
  • 開発環境で、再起動なしに設定を頻繁に試したい

Nginx には .htaccess に相当する仕組みがなく、設定はすべてサーバー設定ファイルに書きます。Apache から Nginx へ移行する際は、.htaccess の内容を設定ファイルの記法に書き換える必要があります。

関連

Post Share
子ページ

子ページはありません

同階層のページ
  1. 非推奨である理由(性能問題)
  2. Options -Indexes