Apache出现403禁止访问错误

54

好的,我之前设置了两个虚拟主机,它们都可以正常工作。它们都托管简单的Web项目,并且在浏览器中使用http://project1http://project2也能正常访问。

无论如何,我现在要添加另一个虚拟主机。我编辑了/etc/hosts文件,加入了127.0.0.1 project3,并复制粘贴了以前为project2输入的条目,并编辑了文件路径。

我检查了所有的文件和文件夹权限(实际上我是从project2复制并粘贴过来),并在index.php文件中简单地放置了一条“Hello World”的消息。

当我访问http://project3时,却收到了403禁止访问的错误信息。

为什么会这样呢?我只想知道我错过了哪一步,因为似乎一切都设置正确了。


你重启了Apache吗? - emco
9个回答

50

请确保以下内容:

  • Apache 可以物理访问该文件(运行 Apache 的用户,可能是 www-data 或 apache,在文件系统中可以访问该文件)
  • Apache 可以列出该文件夹的内容(读取权限)
  • Apache 对该文件夹有一个 "Allow" 指令。例如,/var/www/ 应该有一个默认的虚拟主机,您可以检查它。

此外,您可以查看 error.log 文件(通常位于 /var/log/apache2/error.log),该文件将描述为什么会出现 403 错误。

最后,您可能需要重新启动 Apache,以确保所有配置都已应用。这通常可以使用 /etc/init.d/apache2 restart 来完成。在某些系统上,脚本将被称为 httpd,请确定。


我收到了“服务器配置拒绝客户端”的错误信息... 有什么线索吗?谢谢。 - user2672288
1
不用等!我想我搞定了。我重新启动了apachectl,看起来可以工作了。简单得难以置信。谢谢。 - user2672288
附加部分解决了我的问题,请从错误日志中获取实际错误。 - Newbie
我缺少了allow指令。谢谢。 - Michael
1
我没有看到上面命名的任何问题,但仍然出现错误。有趣的是,/var/log/apache2/error.log文件只有两行。第一行是:“<日期时间> [mpm_prefork:notice] [pid 2302]”等等。第二行是:“<日期时间>[core:notice] [pid 2302] AH00094: Command line:”等等。我还可以在哪里查找? - Dennis
"由mod_access_compat提供的Allow、Deny和Order指令已被弃用,并将在未来版本中消失。您应避免使用它们,并避免使用过时的教程推荐其使用。" https://httpd.apache.org/docs/current/howto/access.html - student91

30

我在苦苦挣扎几天后终于解决了这个问题。以下是对我有效的方法:

首先,检查您的Apache error_log文件,并查看最近的错误消息。

  • 如果它说类似于:

access to /mySite denied (filesystem path
'/Users/myusername/Sites/mySite') because search permissions
are missing on a component of the path

如果您遇到文件权限问题,您可以通过从终端运行以下命令来修复它们:

$ cd /Users/myusername/Sites/mySite
$ find . -type f -exec chmod 644 {} \;
$ find . -type d -exec chmod 755 {} \;

然后,刷新应该显示您网站的URL(例如http://localhost/mySite)。 如果仍然出现403错误,并且您的Apache error_log 仍然显示相同的内容,则逐步向上移动目录树并在此过程中调整目录权限。 您可以通过终端执行以下操作:

$ cd ..
$ chmod 755 mySite
如果需要,继续进行以下步骤:
$ cd ..
$ chmod Sites 

并且,如果必要的话,

$ cd ..
$ chmod myusername

不要继续向上移动。这可能会彻底破坏您的系统。 如果您仍然收到错误消息,表示路径中某个组件的搜索权限缺失,我不知道您应该怎么做。但是,我遇到了另一个错误(如下所示),我是这样解决的:

  • 如果您的error_log显示类似以下内容的信息:

    client denied by server configuration:
    /Users/myusername/Sites/mySite
    

    如果您的问题不是文件权限问题,而是Apache配置问题。

    请注意,在您的 httpd.conf 文件中,您将看到一个默认配置如下(Apache 2.4+):

    <Directory />
        AllowOverride none
        Require all denied
    </Directory>
    

    或者像这样(Apache 2.2):

    <Directory />
      Order deny,allow
      Deny from all
    </Directory>
    

    不要更改这个!我们将不会全局覆盖这些权限,而是在您的httpd-vhosts.conf文件中覆盖。 然而,在此之前,请确保您的vhost Include行在httpd.conf中是取消注释的。它应该看起来像这样。(您的确切路径可能不同。)

    # Virtual hosts
    Include etc/extra/httpd-vhosts.conf
    

    现在,打开你刚刚 Includehttpd-vhosts.conf 文件。如果你还没有网页的条目,请添加一个。它应该看起来像这样。 DocumentRootDirectory 路径应该相同,并且应该指向你的 index.htmlindex.php 文件所在的位置。对于我来说,那就是在 public 子目录中。

    对于 Apache 2.2:

    <VirtualHost *:80>
    #     ServerAdmin webmaster@dummy-host2.example.com
        DocumentRoot "/Users/myusername/Sites/mySite/public"
        ServerName mysite
    #     ErrorLog "logs/dummy-host2.example.com-error_log"
    #     CustomLog "logs/dummy-host2.example.com-access_log" common
        <Directory "/Users/myusername/Sites/mySite/public">
            Options Indexes FollowSymLinks Includes ExecCGI
            AllowOverride All
            Order allow,deny
            Allow from all
            Require all granted
        </Directory>
    </VirtualHost>
    

    这几行话说:

    AllowOverride All
    Require all granted
    

    这是Apache 2.4+的关键设置。如果没有这些设置,您将无法覆盖在 httpd.conf 中指定的默认Apache设置。请注意,如果您使用的是Apache 2.2,则这些行应该改为:

    Order allow,deny
    Allow from all
    
    这个更改对于像我这样的谷歌用户来说是一个重要的困惑来源,因为复制和粘贴这些Apache 2.2行在Apache 2.4+中不起作用,在旧的帮助线程中仍然可以找到Apache 2.2行。
    一旦您保存了更改,请重新启动Apache。此命令取决于您的操作系统和安装方式,如果需要帮助,请单独查找。
    希望这能帮到其他人!
    附注:如果您无法找到这些.conf文件,请尝试运行find命令,例如:
    $ find / -name httpd.conf
    

  • 1
    非常好的答案,我遇到了版本冲突的问题(我使用的是2.4+),这导致了“客户端被服务器配置拒绝”的错误。 - Namanyay Goel
    ExecCGI在PHP中缺失。感谢指点! - andraaspar

    8

    restorecon命令的工作原理如下:

    restorecon -v -R /var/www/html/
    

    17
    这是做什么用的? - Alexander Mills
    运行 apt install policycoreutils 命令安装该工具,然后使用 man restorecon 命令来恢复文件的默认 SELinux 安全上下文(-v:显示更改,-R:递归)。 - xinthose
    这个应该被点赞。 - junnyea

    2

    请注意,造成这种情况的另一个可能原因是父目录的 "FollowSymLinks" 选项被您项目目录的选项误写覆盖了。这在我的情况下就是如此,让我一直苦恼,直到找出了原因!

    以下是这种错误的一个例子:

    <Directory />
            Options FollowSymLinks
            AllowOverride all
            Require all denied
    </Directory>
    
    <Directory /var/www/>
            Options Indexes # <--- NOT OK! It's overwriting the above option of the "/" directory.
            AllowOverride all
            Require all granted
    </Directory>
    

    现在,如果您检查Apache的日志消息(tail -n 50 -f /var/www/html/{your_site的错误日志文件}),您将看到这样的错误:

    Options FollowSymLinks and SymLinksIfOwnerMatch are both off, so the RewriteRule directive
    is also forbidden due to its similar ability to circumvent directory restrictions
    

    这是因为上述规则中/var/www目录的索引正在覆盖/目录的FollowSymLinks。现在你知道了原因,为了解决这个问题,你可以根据需要采取许多措施。例如:

    <Directory />
            Options FollowSymLinks
            AllowOverride all
            Require all denied
    </Directory>
    
    <Directory /var/www/>
            Options FollowSymLinks Indexes # <--- OK.
            AllowOverride all
            Require all granted
    </Directory>
    

    甚至包括这个:

    <Directory />
            Options FollowSymLinks
            AllowOverride all
            Require all denied
    </Directory>
    
    <Directory /var/www/>
            Options -Indexes # <--- OK as well! It will NOT cause an overwrite.
            AllowOverride all
            Require all granted
    </Directory>
    

    上面的示例不会导致覆盖问题,因为在Apache中,如果选项是“+”,它只会覆盖“+”选项,如果是“-”,则只会覆盖“-”选项......(虽然我没有参考任何资料,但这是我通过journalctl -xe检查Apache错误消息得出的解释:“所有选项必须以+或-开头,或者不能有选项。”当一个选项有符号而另一个选项没有符号时(例如,FollowSymLinks -Indexes)。因此,我的个人结论是——应该带着一颗谨慎的心态——如果我使用了-Indexes作为选项,那么Apache将把它视为与其他没有符号的选项在“/”中形成的完整不同的选项集,因此最终不会发生烦人的重写,我可以通过自己项目目录中的上述规则成功确认。

    希望这能帮助您减少很多困扰! :)


    2

    然而,这并不能解决问题,因为在例如open SUSE Tumbleweed上,自定义源构建会触发默认网页上相同的401错误,该网页已根据Indexes和配置正确设置。

    Require all granted
    

    1

    添加

    <Directory "/path/to/webroot">
            Options Indexes FollowSymLinks Includes ExecCGI
            AllowOverride All
            Order allow, deny
            Allow from all
            Require all granted
    </Directory>
    

    这段代码告诉Apache2覆盖之前的所有配置,并允许来自所有人的(200)请求,然后拒绝。 (403) 它还要求授予所有请求。这段代码必须放在每个虚拟主机文件中,但它确实有效。我已经使用了一年多。
    将此代码添加到您的配置文件中(例如/etc/apache2/sites-enabled/000-default.conf) 在Debian 11上测试过LAMP堆栈。

    1
    您的答案可以通过添加更多支持性信息来改进。请编辑以添加进一步细节,例如引用或文档,以便他人可以确认您的答案是正确的。您可以在帮助中心中找到有关编写良好答案的更多信息。 - Community

    1

    服务器可能需要您的主目录和其中的 .htaccess 文件夹的读取权限


    2
    当我创建了用户的家目录/home/username并且公共html文件夹处于可执行状态时,使用chmod 711 /home/username来使组和其他人能够访问它,我成功解决了403错误。我原本以为只需要在public_html上授予执行权限,因为我从http://www.petefreitag.com/item/793.cfm中的阅读所得到的理解是,里面的文件夹是Webroot,但我错了。 - rhand

    0
    您可以尝试禁用selinux,然后使用以下命令再次尝试:
    setenforce 0
    

    0

    在我的情况下,它失败了,因为源服务器的IP未被列入目标服务器的白名单。

    例如,我正在尝试从运行在我的源服务器上的应用程序访问https://prodcat.ref.test.co.uk。 在源服务器上通过ifconfig查找IP

    此IP应在目标服务器的apache配置文件中列入白名单。如果没有,则将其列入白名单。

    添加IP以进行白名单处理的步骤(如果您也控制目标服务器) ssh到apache服务器 sudo su - cd /usr/local/apache/conf/extra(实际目录可能因您的配置而异)

    查找目标应用程序的配置文件,例如prodcat-443.conf

    RewriteCond %{REMOTE_ADDR} <YOUR Server's IP> 
    for e.g.
    RewriteCond %{REMOTE_ADDR} !^192\.68\.2\.98
    

    希望这能帮助到某个人


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