为什么 index.html.bak 优先于 index.php(Apache)?

为什么 index.html.bak 优先于 index.php(Apache)?

我在新安装的虚拟 Debian 11 上偶然发现了一个奇怪的行为。在 user/public_html 下,我对一个页面进行了一些更改,但某个时候我的浏览器开始下载索引文件而不是渲染它。

过了好一会儿我才意识到问题出在 index.html.bak 文件上。虽然文件夹中有 index.php,但这个文件还是被下载了。

我已经通过在配置和 .htaccess 中设置 DirectoryIndex 对此进行了测试,并且只要 index.html 在 index.php 之前设置,并且 DirectoryIndex 未设置,我始终可以复制该问题。Index.html.bak 始终在 index.php 之前提供。如果在 DirectoryIndex 中首先设置 index.php,则 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

请检查您的 Apachemod_mime设置和Apache 2.4mod_mime文档。特别是你的MultiviewsMatch指令设置和相关文件

请注意以下从中摘录的警告:允许Any扩展名匹配,即使mod_mime无法识别该扩展名”可以引起“不可预测的结果,例如提供网站管理员从未预料到的文件。.old.bak

Apache 模块mod_mime
此模块用于将内容元数据分配给 HTTP 响应所选的内容通过将 URI 或文件名中的模式映射到元数据值。例如,内容文件的文件扩展名通常定义内容的 Internet 媒体类型、语言、字符集和内容编码。此信息在包含该内容的 HTTP 消息中发送,并在选择替代方案时用于内容协商,以便在选择要提供的多个可能内容之一时尊重用户的偏好。请参阅mod_negotiation更多信息内容协商

具有多个扩展名的文件

文件可以有多个扩展名;扩展名的顺序是通常情况下无关。例如,如果文件欢迎.html.fr映射到内容类型 text/html 和语言法语,然后文件欢迎.fr.html将映射到完全相同的信息。

如果你希望文件名的最后一个点分隔部分只映射到特定的元数据,那么不要使用添加指令。

MultiviewsMatch指示

// apache.org > 2.4 > mod_mime > multiviewsmatch

MultiviewsMatch允许三种不同的行为mod_negotiation的多视图功能:Any   NegotiatedOnly   Filters|Handlers [处理程序|过滤器]

多视图允许对文件进行请求,例如index.html,以匹配基本请求后的任何协商扩展,例如index.html.enindex.html.frindex.html.gz

NegotiatedOnly选项规定,基本名称后面的每个扩展名都必须与mod_mime内容协商的可识别扩展名相关联,例如 Charset、Content-Type、Language 或 Encoding。这是最严格的实现,具有最少的意外副作用,并且是默认行为。
 

要包含与Handlersand/or相关的扩展Filters,请将MultiviewsMatch指令设置为 Handlers、Filters 或两个选项关键字。

您最终可能会允许Any扩展程序匹配,即使mod_mime无法识别该扩展程序。这可能会导致不可预测的结果,例如提供网站管理员从未期望过的文件.old.bak

答案2

感谢用户盲点的答案我能够解决这个谜团(至少大部分)并实现合适的配置。

我所有原始问题的答案:

如果DirectoryIndexindex.html 排在 index.php 之前,Apache 将首先优先考虑 index.html,然后再考虑 index.html 的替代版本(例如 index.html.bak),如果 index.php 不存在,则先提供这些版本。

在我的 Apache mods-enabled/userdir.conf 中,Options MultiViews已默认设置。此选项允许使用MultiviewsMatch指令来提供替代文件(如 foo.html.fr)。

在我的 Apache 主配置 apache2.conf 中,Options MultiViews/var/www 选项默认未启用,因此有问题的行为仅发生在用户的 public_html 网站下。

我不知道为什么这两个默认设置不同。

application/x-trashDebian 默认为 .bak 文件设置了 mime 类型。这就是浏览器下载 .html.bak 文件而不是渲染它们的原因。

我在基于 Debian 的系统上的 Apache 中注意到的内容与 Apache 文档之间存在一些不一致:

apache 文档 mod_mime.html#multiviewsmatch

您最终可能会允许匹配任何扩展名,即使 mod_mime 无法识别该扩展名。这可能会导致不可预测的结果,例如提供网站管理员从未想过会提供的 .old 或 .bak 文件。

事实上,即使MultiviewsMatch NegotiatedOnly配置了 .old 和 .bak 文件,也会提供这些文件。这些文件扩展名application/x-trash在 Debian 上的 /etc/mime.types 中分配了 mime 类型。对我来说,这种行为没有多大意义,而且也与文档相矛盾,所以在某种程度上这实际上是一个错误。

现在,如果您不想Multiviews完全禁用但想要禁用提供某些已知文件类型,您可以在 mods-enabled/mime.conf 中的 apache 中使用例如RemoveType bak并使用删除它们的 mime 类型MultiviewsMatch NegotiatedOnly

相关内容