apache 不会从另一个挂载点索引文件夹

apache 不会从另一个挂载点索引文件夹

我正在尝试从使用基本身份验证的另一个本地 ext4 安装中为 Web 根目录之外的文件夹启用目录列表,但我得到的是一个空列表,并且没有记录错误。奇怪的是,如果我在浏览器中输入此目录下文件的已知位置,它会正常下载该文件。

在此处输入图片描述

这是我的example.conf文件:

<virtualhost *:80>

  ServerAdmin [email protected]
  ServerName  example.com
  ServerAlias www.example.com


  DirectoryIndex index.php
  DocumentRoot /var/www/example.com
    <Directory />
    Options FollowSymLinks
    AllowOverride All
    </Directory>

  LogLevel warn
  ErrorLog  /var/apachelogs/error.log
  CustomLog /var/apachelogs/access.log combined

  Alias /blah2 "/blah1/blah2"
    <Location /blah2>
              Options +Indexes +MultiViews +FollowSymLinks
              IndexOptions +FancyIndexing
    </Location>


</virtualhost>

这是我的.htaccess

AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/home/myusername/.htpasswd"
Require valid-user

另外,我已经注释掉IndexIgnore/etc/apache2/mods-enabled/autoindex.conf

#IndexIgnore .??* *~ *# RCS CVS *,v *,t

我已运行chmod -R 755 /blah1/blah2chgrp -R www-data /blah1/blah2chmod a+x -R /blah1/blah2。文件夹所有者是 www-data 的成员。如果我运行,sudo usermod -a -G www-data myusername我可以正常浏览和读取所有文件和文件夹。

进行一些测试后,如果我将 /blah1/blah2 移动到我的主目录下并更改别名,我的配置就可以正常工作。它在另一个挂载点上,这弄乱了 mod_autoindex,尽管 apache 可以清楚地读取文件本身。删除身份验证没有帮助。LogLevel warn我没有收到任何记录的错误。将我的 LogLevel 更改为 trace4 后,这是我的错误日志

以下是来自的安装线/etc/fstab

UUID=[theuuid] /blah1 ext4 rw,nosuid,nodev,errors=remount-ro    0    0

编辑 最后说明:确认 www-data 可以读取和写入我的文件夹,我编写了以下 php 脚本:

<?php

mkdir ("testdir");
var_dump(scandir('.'));

?>

结果:创建目录 testdir,其所有者为 www-data:www-data,并将目录和文件列表作为变量转储。

编辑2 我已运行以下命令来正确设置权限:

chmod 755 /blah1/blah2
chmod 755 /blah1
find /blah1/blah2 -type d -exec chgrp www-data {} +
find /blah1/blah2 -type d -exec chmod o+rx {} +
find /blah1/blah2 -type d -exec chmod g+rwxs {} +

结果还是一样。

答案1

您的配置中有几项可以更改。为了帮助您,我在此提供以下指南,基于默认的 Apache2 配置。

处理文件系统权限

为了访问这些文件,Apache 的用户www-data需要具有对这些文件的读取权限以及读取-执行权限权限对目录,也在这个数字中对整个路径具有读取-执行权限。如果您没有任何特殊要求,我建议您使用其他用户的权限。

假设您要通过 Web 服务器索引的目录名为bar,并且位于用户 的主目录中foo。默认情况下/home,该目录/home/foo必须具有755权限。八进制数字表示所有其他用户对里面的文件有读取-执行权限(内容 rad 访问)。755/home/foo

因此让我们创建目录/home/foo/bar并确保它(及其路径)r-x对其他用户具有权限:

mkdir -p /home/foo/bar                            # create the directory
find /home/foo/bar -type d -exec chmod o+rx {} +  # apply o+rx for the dirs recursively
sudo chmod o+rx /home /home/foo                   # this step is optional

现在让我们创建三个测试文件并确保它们对其他用户具有读取权限:

touch /home/foo/bar/file.{1..3}                  # create three empty test files
find /home/foo/bar -type f -exec chmod o+r {} +  # apply o+r for the files recursively

为了允许www-data写入内容,/home/foo/bar您可以更改目录的组所有权并添加rwxs组权限(更多细节):

find /home/foo/bar -type d -exec chgrp www-data {} +
find /home/foo/bar -type d -exec chmod g+rwxs {} +

通过创建另外三个空文件进行测试:

sudo -u www-data touch /home/foo/bar/file.{4..6}


处理 Apache 的配置

默认情况下,在主配置文件中/etc/apache2/apache2.conf,出于安全原因,对根目录的访问/受到限制。我建议您不要通过虚拟主机配置覆盖这些规则并删除<Directory />标签(以及附带的指令)。

特别是,如果你正在为你的目录之外的目录创建别名DocumentRoot,则可能需要明确允许访问目标目录(源Apache 模块 mod_alias)。

让我们首先创建.htpasswd具有足够权限的文件(使用 2FA 提高安全性 - 第 6 页):

htpasswd -c /home/foo/.htpasswd foo               # authentication for the username 'foo'
chmod 400 /home/foo/.htpasswd                     # restricted the permissions
sudo chown www-data:www-data /home/foo/.htpasswd  # change the ownership

根据上述内容,您的虚拟主机配置文件的相关部分应如下所示:

<VirtualHost *:80>

    # Other configuration directives

    Alias "/bar" "/home/foo/bar"

    <Directory "/home/foo/bar">
            #Require all granted
            Options +Indexes +MultiViews +FollowSymLinks
            IndexOptions +FancyIndexing

            # Allow using of a .htaccess files
            AllowOverride All

            # This section could be moved in .htaccess file
            <IfModule mod_authz_core.c>

                <IfModule mod_authn_file.c>
                    AuthType Basic
                    AuthName "Type some hints here..."
                    AuthUserFile /home/foo/.htpasswd
                </IfModule>

                Require valid-user

            </IfModule>

    </Directory>


</VirtualHost>

启用相关模块并重新启动Apache2以应用新的配置:

sudo a2enmod authz_core authz_user authn_file
sudo systemctl restart apache2.service


示例结果

在此处输入图片描述


更新:

我认为问题在于文件系统的权限问题。解决此问题最简单的方法可能是使用bindfs以下方法将目标目录挂载到 DocumentRoot 目录中:这个答案


工作解决方案:

这是最终的解决方案:放弃让 Alias 正确运行我外部挂载文件夹的想法,而是采纳 @pa4080 的变通建议,并将bindfs文件夹挂载到 webroot 中的 /blah2。我无法让 /etc/fsab 正确初始化我的绑定,因此我决定为该任务编写一个初始化脚本。

首先,安装bindfs:

apt-get update
apt-get install bindfs
mkdir /var/www/example.com/blah2

/var/www/scripts/blahbind.sh接下来我创建了一个在启动时运行的脚本文件:

#!/bin/bash
bindfs -o force-user=www-data,perms=a=rX /blah1/blah2 /var/www/example.com/blah2

然后赋予它正确的权限:

chmod 750 /var/www/scripts/blahbind.sh
chmod +x /var/www/scripts/blahbind.sh

接下来我创建了一个服务脚本:

vi /etc/systemd/system/blahbind.service 

内容如下:

[Unit]
Requires=mydrive.mount
After=mydrive.mount
Description=bind /blah1/blah2 to example.com/blah2 folder

[Service]
ExecStart=/var/www/scripts/blahbind.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

注意,mydrive.mount应替换为/blah1/blah2文件夹的驱动器。使用 获取安装列表systemctl list-units --type=mount

通过运行确认服务脚本正常运行

sudo service blahbind start

然后使用以下命令使服务在重启时继续存在:

sudo systemctl enable blahbind.service

然后,我简化了位置块,Alias没有example.com.conf

   <Location /blah2>
            Options +Indexes +MultiViews +FollowSymLinks
            IndexOptions +FancyIndexing
   </Location>

答案2

Apache 将需要所有目录的执行权限,您的情况/blah1/blah2。如果它遇到一个目录,它没有该目录的组执行权限,它将不会执行列表。

您可能需要修改/blah1为拥有公共执行权限或将其修改www-data为具有组执行权限的组,例如。g+x

答案3

基于example.conf,您已将/var/www/example.com文档根目录和/blah1/blah2目录 ext4 安装。

我们假设文档根目录已符号链接到您的目录并挂载。现在我们需要确认文档根目录的位置。我们将使用复制文件rsync。它会将内容转储到挂载点,而不是将其传输到包含html位置。

$sudo rsync -av /var/www/example.com/html /blah1/blah2

现在我们可以更新配置了

<VirtualHost *:80>

...
...
DocumentRoot /var/www/example.com
<Directory />
    Options FollowSymLinks
    AllowOverride All
</Directory>
...
...
Alias /blah2 "/blah1/blah2"
<Directory "/blah1/blah2">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    IndexOptions FancyIndexing
    Require valid-user
    ...
    ...
    #to ensure the DocumentRoot is updated in rewrites or aliases to reflect the changes at the new location.
    RewriteEngineon
    RewriteCond %{HTTP_HOST} =www.example.com
    RewriteRule ^index\.html$ filename.html
    ...
</Directory>

<VirtualHost>

不要忘记启用mod_rewrite查看此内容文档

最后,我们检查语法并重新启动 Apache。

$sudo apachectl configtest
$sudo systemctl reload apache

希望这对您有帮助。

相关内容