使用.htaccess拒绝直接访问文件或目录

时间:2010-09-24 21:30:19

标签: .htaccess mod-rewrite apache2

我正在玩.htaccess,我想知道在根目录中只有一个.htaccess是否可以阻止来自指向现有文件或目录的浏览器的所有请求。

我们试试这个例子:

RewriteEngine On

RewriteBase /~my_user/my_base/

RewriteRule ^list/$ list.php [L]
RewriteRule ^element_of_list/([a-zA-Z0-9\-]+)/$ element.php?elem_id=$1 [L]

现在,如果我写http://127.0.0.1/~my_user/my_base/list/,这很好,但如果我写http://127.0.0.1/~my_user/my_base/list.php它仍在工作。我不希望这样。我希望用户在最后一种情况下获得404错误。

我们有/etc/apache2/mods-enabled/userdir.conf

<IfModule mod_userdir.c>
        UserDir public_html
        UserDir disabled root

        <Directory /home/*/public_html>
                AllowOverride All
                Options Indexes FollowSymLinks
                <Limit GET POST OPTIONS>
                        Order allow,deny
                        Allow from all
                </Limit>
                <LimitExcept GET POST OPTIONS>
                        Order deny,allow
                        Deny from all
                </LimitExcept>
        </Directory>
</IfModule>

我的第一次尝试是使用RewriteCond

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$ 404.php [L]

但它不起作用。每个请求最终都会重定向到404.php

更新

所以我设法为目录创建了过滤器:

RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !^/~my_user/my_base/$ [NC]
RewriteRule ^(.*)$ 404.php [L]

它的作用是检查所请求的路径(REQUEST_FILENAME)是否存在,如果它不是我的RewriteBase,它基本上是index.php,那么它是一个目录 AND ,然后重定向到404。 PHP

我仍在努力寻找能够为文件做同样事情的东西。我知道我可以使用扩展名文件名选择性地执行此操作,但我希望文件的通用过滤器

2 个答案:

答案 0 :(得分:10)

如果我已正确理解您的要求,您可能会做以下事情:

# This is a real directory...
RewriteCond %{REQUEST_FILENAME} -f [OR]
# Or it's a real file...
RewriteCond %{REQUEST_FILENAME} -d
# And it's not 404.php...
RewriteCond $0 !=404.php
# And it's not the root
RewriteCond $0 !=""
# And it's not any of the above due to an internal redirect...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# So cause a 404 response (you could redirect to 404.php if you want)
RewriteRule ^.*$ - [R=404,L]

# Set the 404 error document
ErrorDocument 404 /~my_user/my_base/404.php

请记住,这会阻止所有存在,因此任何图片,样式表或脚本也会被发送到404页面。如果您只想阻止访问PHP文件,Gumbo's solution更合适。我认为在这种情况下你需要另一个RewriteCond来阻止循环:

# Make sure the reason this request has a .php is because it was requested
# by the user (and not due to a redirect)
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/[^\s]+\.php
# Make sure we aren't on 404.php already
RewriteRule %{REQUEST_URI} !404\.php$
# We aren't, so redirect to 404.php
RewriteRule ^ 404.php [L]

答案 1 :(得分:2)

尝试此规则:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /[^?\ ]*\.php[/?\ ]
RewriteRule .*\.php$ 404.php [L]

这会将其路径中包含.php的所有请求重写为 404.php