端っこプログラマーの手帳

主にプログラムに関する手記です

【Apache】mod_rewrite で「403 Forbidden」

以前のエントリーで、mod_rewrite の設定は書く場所(.htaccess or httpd.conf)によって、環境変数に入ってくる値やリライト先のパスが異なるが、Directoryディレクティブ内に設定を書くことで、.htaccess と同じ記述にできることが分かった。

kzhishu.hatenablog.jp

最近、.htaccess が許可されていない環境で、リライト設定をする機会があり「待ってました!!」と、httpd.conf のDirectoryディレクティブに設定を書いた。

<VirtualHost XXX.XXX.XXX.XXX:80>
  ServerName example.com
  DocumentRoot /var/www/html

  <Directory /var/www/html>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]
  </Directory>

</VirtualHost>

これがなんとうまくいかず「403 forbidden」
エラーログには以下の内容が...

Options FollowSymLinks and SymLinksIfOwnerMatch are both off, so the RewriteRule directive is also forbidden due to its similar ability to circumvent directory restrictions : /var/www/html/

なぜだろう(-_-)...
エラー内容を調べる。

Apacheのドキュメントに「you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled」とあり、どうやら FollowSymLinks が有効でないため、RewriteRule の機能が動いていなかったようだ。

httpd.conf の全体を確認してみると、/var/www で FollowSymLinks を無効にしている箇所があり、今回は問題となっている VirtualHost は、/var/www/html のため、この設定の影響下のため同じく無効となる。これが原因だ。

<Directory /var/www>
Options -FollowSymLinks
</Directory>

以下のように書けば、エラーにはならない。ドキュメントルートは /var/www 配下だけれども、VirtualHost直下に書けば影響は及ばないようだ。

<VirtualHost XXX.XXX.XXX.XXX:80>
  ServerName example.com
  DocumentRoot /var/www/html

  RewriteEngine On
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php [QSA,L]

</VirtualHost>

「Directory /」で設定で無効になるのかも確認。(VirtualHost直下は、/ とイコールかと思った...)これでも問題なく動く。VirtualHost は、Directoryの影響外のようだ。

<Directory />
  Options -FollowSymLinks
</Directory>

まとめると、リライト設定を書くときは、「Options」で検索をして FollowSymLinks が有効かを確認して Directoryディレクティブで問題ないのか、VirtualHost に書く必要があるのかを検討する必要がありそうだ。
できれば、.htaccess と記述を合わすためにDirectoryディレクティブに書きたい。
ちなみに「Options」が見つからない場合は、有効になっている。
設定されていなければ「Options All」になるためだ。

Options ディレクティブ
https://httpd.apache.org/docs/2.4/ja/mod/core.html#options