我正在尝试从使用基本身份验证的另一个本地 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/blah2
、chgrp -R www-data /blah1/blah2
和chmod 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
希望这对您有帮助。