`.htaccess` のリダイレクト設定が `cgi-bin` ディレクトリだけ効かない

経緯

https://www.example.jp/ から https://new.example.jp/ へのリダイレクトテストのため以下のような .htaccess を用意し、ドキュメントルートに置きました。

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/maintenance/
RewriteRule ^(.*) https://new.example.jp/ [R=301,L]
ErrorDocument 404 https://new.example.jp/

これでリダイレクトのテストを実施しました。

  1. https://www.example.jp/ (トップ)
  2. https://www.example.jp/cgi-bin/hoge.cgi (適当なCGI)
  3. https://www.example.jp/tmp/ (存在しないディレクトリ)
  4. https://www.example.jp/maintenance/ (メンテナンスページトップ)
  5. https://www.example.jp/maintenance/fuga.html (メンテナンスページ下層ページ)

現象

結果は以下。

  1. https://new.example.jp/ へリダイレクト (成功)
  2. www.example.jp の Not found ページ (意図しない挙動)
  3. https://new.example.jp/ へリダイレクト (成功)
  4. https://www.example.jp/maintenance/ のまま
  5. https://www.example.jp/maintenance/fuga.html のまま

2.のみ意図しない挙動になってしまったので調査をしました。

調査

調査したところ、Apacheのグローバル設定である /etc/httpd/conf/httpd.conf に以下の記述がありました。

# less /etc/httpd/conf/httpd.conf

<IfModule alias_module>

## 略

    #
    # ScriptAlias: This controls which directories contain server scripts. 
    # ScriptAliases are essentially the same as Aliases, except that
    # documents in the target directory are treated as applications and
    # run by the server when requested rather than as documents sent to the
    # client.  The same rules about trailing "/" apply to ScriptAlias
    # directives as to Alias.
    #
    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

</IfModule>

この記述から、デフォルトでは各仮想サイトの cgi-bin/ 以下のアクセスは /var/www/cgi-bin/ で一括して処理する、という設定になっているようです。

これにより、

  1. https://www.example.jp/cgi-bin/ 以下へアクセス
  2. 処理するディレクトリ階層が /var/www/example/web/ ではなく /var/www/cgi-bin/ となる
  3. 2.で.htaccess が関与できるディレクトリの外に行ってしまったため、 .htaccess が動作しない

という挙動になったようです。

今回は以下の設定を仮想サイトのディレクティブに追記して回避しました。

ScriptAlias /cgi-bin/ /var/www/example/web/cgi-bin/

これでApacheを再起動し、2.についてもリダイレクトが効くようになったことを確認しました。

……CGI時代も一つの文明だったのだなぁ……と改めて思いました。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。