なぜ index.html.bak が index.php (Apache) よりも優先されるのでしょうか?

なぜ index.html.bak が index.php (Apache) よりも優先されるのでしょうか?

新しい仮想 Debian 11 インストールで奇妙な動作に遭遇しました。user/public_html の下でページにいくつかの変更を加えたところ、ある時点でブラウザがインデックス ファイルをレンダリングする代わりにダウンロードし始めました。

問題が index.html.bak ファイルにあることに気づくまで、かなり時間がかかりました。これは、フォルダー内に index.php があるにもかかわらずダウンロードされていたファイルでした。

configs と .htaccess で DirectoryIndex を設定することでこれをテストしましたが、index.html が index.php の前に設定され、DirectoryIndex が設定されていない場合は、常に問題を再現できます。index.html.bak は常に index.php の前に提供されます。index.php が DirectoryIndex で最初に設定されている場合、index.php は正しく提供されます。

奇妙なことに、これは public_html の下でのみ発生し、/var/www の下では発生しません。

古い Apache を搭載した古い Debian サーバーではこれを再現できません。

これはバグでしょうか、それとも設定に問題があるのでしょうか? この新規インストール以降、設定にはほとんど触れていません。

Apacheのバージョンは Server version: Apache/2.4.54 (Debian) Server built: 2022-06-09T04:26:43

答え1

Apache モジュールmod_mime

Apacheのmod_mime設定とApache 2.4mod_mimeドキュメント特にMultiviewsMatchディレクティブ設定と関連文書

同じ文書から抜粋した次の警告に注意してください。「拡張子を認識しないAny場合でも、一致する拡張子」mod_mime引き起こす可能性があります「ウェブマスターが予期していなかったファイルの配信など、予期しない結果が生じる可能性があります.old。 」.bak

Apache モジュールmod_mime
このモジュールは、HTTPレスポンスに選択されたコンテンツにコンテンツメタデータを割り当てるために使用されます。URIまたはファイル名のパターンをメタデータ値にマッピングするたとえば、コンテンツ ファイルのファイル名拡張子は、多くの場合、コンテンツのインターネット メディア タイプ、言語、文字セット、およびコンテンツ エンコーディングを定義します。この情報は、そのコンテンツを含む HTTP メッセージで送信され、代替案を選択する際のコンテンツ ネゴシエーションで使用されます。これにより、提供可能な複数のコンテンツの中から 1 つを選択する際に、ユーザーの好みが尊重されます。mod_ネゴシエーション詳細についてはコンテンツ交渉

複数の拡張子を持つファイル

ファイルには複数の拡張子が付けられる場合があります。拡張子の順序は通常は無関係です。たとえば、ファイルがようこそコンテンツタイプtext/htmlと言語フランス語にマップされ、ファイルようこそまったく同じ情報にマッピングされます。

ファイル名の最後のドット区切り部分のみを特定のメタデータにマッピングしたい場合は、追加指令。

MultiviewsMatch指令

// apache.org > 2.4 > mod_mime > マルチビューマッチ

MultiviewsMatch3つの異なる動作を許可しますmod_ネゴシエーションのマルチビュー機能:Any   NegotiatedOnly   Filters|Handlers [ハンドラー|フィルター]

マルチビューを使用すると、ファイルに対する要求 (例: ) がindex.html、基本要求に続くネゴシエートされた拡張子 (例: index.html.en、、index.html.frまたは )と一致することが可能になりますindex.html.gz

このNegotiatedOnlyオプションは、ベース名に続くすべての拡張子がmod_mime、コンテンツ ネゴシエーションで認識される拡張子 (Charset、Content-Type、Language、Encoding など) と相関する必要があることを指定します。これは、予期しない副作用が最も少ない最も厳密な実装であり、デフォルトの動作です。
 

Handlersおよび/またはに関連付けられた拡張機能を含めるにはFiltersMultiviewsMatchディレクティブを Handlers、Filters、または両方のオプション キーワードに設定します。

拡張子が認識されないAny場合でも、最終的に拡張子の一致を許可することができます。これにより、ウェブマスターが予期していなかったファイルが提供されるなど、予期しない結果が発生する可能性があります。mod_mime.old.bak

答え2

ユーザーに感謝ブラインドスポットの答え私はこの謎を(少なくとも大部分は)解き、適切な構成を実装することができました。

私の当初の質問に対する回答:

index.html が index.php より前に順序付けられている場合DirectoryIndex、Apache は最初に index.html を優先し、次に index.html の代替バージョン (例: index.html.bak) を優先し、代替バージョンがない場合は index.php を提供します。

私の Apache mods-enabled/userdir.conf では、すでにデフォルトで設定されています。このオプションにより、foo.html.fr などの代替ファイルを提供できるようにするディレクティブOptions MultiViewsの使用が有効になります。MultiviewsMatch

私の Apache メイン設定 apache2.conf では、Options MultiViews/var/www のオプションはデフォルトで有効になっていませんでした。そのため、問題の動作はユーザーの public_html サイトでのみ発生していました。

なぜこの 2 つのデフォルト設定が異なるのかはわかりません。

.bak ファイルの場合、Debian では MIME タイプがapplication/x-trashデフォルトで設定されています。このため、ブラウザは .html.bak ファイルをレンダリングするのではなくダウンロードします。

私の Debian ベースのシステム上の Apache でメモした内容と Apache のドキュメントの間には矛盾があります。

apache ドキュメント mod_mime.html#multiviewsmatch

最終的には、mod_mime が拡張子を認識しない場合でも、任意の拡張子の一致を許可できます。これにより、Web マスターが予期していなかった .old ファイルや .bak ファイルが提供されてしまうなど、予期しない結果が発生する可能性があります。

実際、.old ファイルと .bak ファイルは、MultiviewsMatch NegotiatedOnly設定されていても提供されます。これらのファイル拡張子には、Debian の /etc/mime.types で MIME タイプが割り当てられますapplication/x-trash。私にとって、この動作はあまり意味をなさず、ドキュメントにも矛盾しているため、ある意味ではこれは実際にはバグです。

ここで、完全に無効にするのではなくMultiviews、いくつかの既知のファイルタイプの提供を無効にしたい場合は、たとえば と を使用RemoveType bakして、 mods-enabled/mime.conf の apache からそれらの MIME タイプを削除できますMultiviewsMatch NegotiatedOnly

関連情報