Apache DirectorySlash Off - 网站崩溃

11
如果我在我的.htaccess文件中设置DirectorySlash Off,并且在没有斜杠的情况下调用目录,则会从服务器上收到403-Forbidden错误。如果加上斜杠,一切都正常。 有人能解释一下为什么吗?这是我的完全匿名化的.htaccess
# GLOBAL CONFIG
Options +FollowSymlinks
DirectorySlash Off
AddDefaultCharset utf-8
php_value post_max_size 256M
php_value upload_max_filesize 256M

# BEGIN WordPress
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
# END WordPress

# REMOVE WWW
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://domain.com$1 [R=301,L]
4个回答

16
如您所知,根据文档,在DirectorySlash设置为Off时,对于请求/folderDirectoryIndex不会被评估。这意味着该请求不会自动映射到/folder/index.phpmod_dir在请求处理的“fixup”阶段执行此检查。当您在.htaccess文件中指定规则时,负责RewriteRule定义的mod_rewrite也在此阶段执行其处理。
然而,它是以对mod_dir等模块的意识进行编程的,并包括一个检查,以确保当前目录是以斜杠结尾的。如果没有,则拒绝处理请求,因为这样做可能会导致未定义的行为。
然后请求进入内容生成阶段,由mod_autoindex处理,因为该请求没有映射到实际文件。鉴于默认情况下在您的主机上禁用了Indexesmod_autoindex返回403 Forbidden,这就是您看到的情况。
请注意,由于DirectoryIndex未被评估,即使mod_rewrite处理该请求,它仍将失败,因为不会发生对index.php的自动解析,并且您的规则也会失败。
RewriteRule . /folder/index.php [L]

由于.需要匹配某些内容(但请求为空),因此无法匹配。

启用DirectorySlash可通过纠正所有先前提到的场景中的被阻止操作来防止这种情况,除了最后一个注释,该注释由于DirectoryIndex将请求映射到index.php而得到解决。


非常感谢!如果我阅读您的答案,很容易理解。 - gearsdigital
2
但是如果我们想混淆我们的目录结构,仍然想为每个请求使用mod_rewrite怎么办?假设我有一个带有/private目录的网站。如果DirectorySlashOn,那么Apache会将我重定向到/private/,因此会泄露信息。如果我只想将/private发送到我的index.php前端控制器,该怎么办? - tonix

12

在Apache 2.4中,您可以通过设置RewriteOptions AllowNoSlash来允许在.htaccess文件中进行重写。

 Changes with Apache 2.3.16
 ...
 *) mod_rewrite: Add the AllowNoSlash RewriteOption, which makes it possible
    for RewriteRules to be placed in .htaccess files that match the directory
    with no trailing slash. PR 48304.
    [Matthew Byng-Maddick <matthew byng-maddick bbc.co.uk>]
 ...

请参阅Apache mod_rewrite文档


2
我认为,当你关闭DirectorySlash时,它会禁用URL的自动修正,并试图显示目录列表,但幸运的是,你可能在某个地方禁用了这个功能(或者在文件权限中),所以它会发送一个403-Forbidden。我猜想,当你打开它时,它就可以正常工作了。 从文档中我理解到,关闭DirectorySlash对于安全性来说并不是很好。 http://httpd.apache.org/docs/2.1/mod/mod_dir.html

Laurent,谢谢你的回答。我也在Apache文档中读到了安全警告,但我需要理解这里出了什么问题。顺便说一下,在我的Web主机后端,默认情况下禁用目录列表。 - gearsdigital
你修改了 rewriteBase is /folder/,所以你需要在URL末尾加上斜杠以匹配。你可以将其设置为 /folder,我认为不需要末尾的斜杠就可以正常工作。 - laurent
如果我按照您的建议,我也会收到403错误。 - gearsdigital

0

正如Tom已经回答的那样,有一个特殊的RewriteOptions选项,但只适用于Apache 2.3.16+,所以如果像我一样,你使用的是旧版本的apache,则无法重写同一目录的url,因为apache不知道这个目录。

例如: "GET /somedir"将在rewrite log中指向<Directory /var/www/html/public>,但(!)访问日志中请求的文件名(%f)仍将是/var/www/html/public/somedir/ - 这是疯狂的apache逻辑。而且apache将显示503(没有Options +Indexes)或带有错误url(例如/subdir/而不是/somedir/subdir/)的目录列表(否则)

因此,我只找到了一个对我有效的解决方案-使用别名:

AliasMatch "/somedir$" "/var/www/html/public/somedir/index.html"

希望这能在2020年帮助到其他人 :D


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接