Apache 不会使用符号链接(403 Forban)

我在 Ubuntu 上安装 Apache 时遇到了一些麻烦。我一直在关注 这本指南

# /usr/sbin/apache2 -v
Server version: Apache/2.2.17 (Ubuntu)
Server built:   Feb 22 2011 18:33:02

我的公共目录/var/www 可以成功地提供并执行放置在其中的 PHP 页面。但是,我想在/var/www 中创建一个符号链接,它指向我的主文件夹中的一个目录,并在那里提供页面。

[root /var/www]# ll
total 36
drwxr-xr-x  3 root root 4096 2011-09-11 14:22 .
drwxr-xr-x 14 root root 4096 2011-06-04 22:49 ..
lrwxrwxrwx  1 root root   16 2011-09-11 13:21 about -> /root/site/about

当我试图访问浏览器时,我得到

Forbidden


You don't have permission to access /about on this server.

据我所知,我给了我想要服务的文件足够的特权:

[root ~/site/about]# ll
total 24
drwxr-xr-x 5 root root 4096 2011-09-11 13:20 .
drwxr--r-- 3 root root 4096 2011-09-11 13:19 ..
drwxr-xr-x 2 root root 4096 2011-09-11 13:21 contact
-rwxr-xr-x 1 root root 1090 2011-09-11 13:19 index.php
drwxr-xr-x 2 root root 4096 2011-09-11 13:20 me
drwxr-xr-x 2 root root 4096 2011-09-11 13:21 resume

我知道 FollowSymLinks 选项,并且我相信它是在我的/etc/apache2/site-enable/000-default 文件中设置的:

DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options FollowSymLinks Indexes MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>

知道我会错过什么吗?

153654 次浏览

Check that Apache has execute rights for /root, /root/site and /root/site/about.

Run:

chmod o+x /root /root/site /root/site/about

You can find a more secure way in Elijah's answer.

For anyone having trouble after upgrading to 14.04 https://askubuntu.com/questions/452042/why-is-my-apache-not-working-after-upgrading-to-ubuntu-14-04 as root changed before upgrade = /var/www after upgrade = /var/www/html

I was having a similar problem that I could not resolve for a long time on my new server. In addition to palacsint's answer, a good question to ask is: are you using Apache 2.4? In Apache 2.4 there is a different mechanism for setting the permissions that do not work when done using the above configuration, so I used the solution explained in this blog post.

Basically, what I needed to do was convert my config file from:

Alias /demo /usr/demo/html


<Directory "/usr/demo/html">
Options FollowSymLinks
AllowOverride None
Order allow,deny
allow from all


</Directory>

to:

Alias /demo /usr/demo/html


<Directory "/usr/demo/html">
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>

Note how the Order and allow lines have been replaced by Require all granted

Related to this question, I just figured out why my vhost was giving me that 403.

I had tested ALL possibilities on this question and others without luck. It almost drives me mad.

I am setting up a server with releases deployment similar to Capistrano way through symlinks and when I tried to access the DocRoot folder (which is now a symlink to current release folder) it gave me the 403.

My vhost is:

DocumentRoot /var/www/site.com/html
<Directory /var/www/site.com/html>
AllowOverride All
Options +FollowSymLinks
Require all granted
</Directory>

and my main httpd.conf file was (default Apache 2.4 install):

DocumentRoot "/var/www"
<Directory "/var/www">
Options -Indexes -FollowSymLinks -Includes
(...)

It turns out that the main Options definition was taking precedence over my vhosts fiel (for me that is counter intuitive). So I've changed it to:

DocumentRoot "/var/www"
<Directory "/var/www">
Options -Indexes +FollowSymLinks -Includes
(...)

and Eureka! (note the plus sign before FollowSymLinks in MAIN httpd.conf file. Hope this help some other lost soul.

There is another way that symbolic links may fail you, as I discovered in my situation. If you have an SELinux system as the server and the symbolic links point to an NFS-mounted folder (other file systems may yield similar symptoms), httpd may see the wrong contexts and refuse to serve the contents of the target folders.

In my case the SELinux context of /var/www/html (which you can obtain with ls -Z) is unconfined_u:object_r:httpd_sys_content_t:s0. The symbolic links in /var/www/html will have the same context, but their target's context, being an NFS-mounted folder, are system_u:object_r:nfs_t:s0.

The solution is to add fscontext=unconfined_u:object_r:httpd_sys_content_t:s0 to the mount options (e.g. # mount -t nfs -o v3,fscontext=unconfined_u:object_r:httpd_sys_content_t:s0 <IP address>:/<server path> /<mount point>). rootcontext is irrelevant and defcontext is rejected by NFS. I did not try context by itself.

First disable selinux (vim /etc/selinux/config)

vim /etc/httpd/conf/httpd.conf edit following lines for symlinks and directory indexing:

documentroot /var/www/html
<directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride None
</directory>

If .htaccess file then AllowOverride all

The 403 error may also be caused by an encrypted file system, e.g. a symlink to an encrypted home folder.

If your symlink points into the encrypted folder, the apache user (e.g. www-data) cannot access the contents, even if apache and file/folder permissions are set correctly. Access of the www-data user can be tested with such a call:

sudo -u www-data ls -l /var/www/html/<your symlink>/

There are workarounds/solutions to this, e.g. adding the www-data user to your private group (exposes the encrypted data to the web user) or by setting up an unencrypted rsynced folder (probably rather secure). I for myself will probably go for an rsync solution during development.

https://askubuntu.com/questions/633625/public-folder-in-an-encrypted-home-directory

A convenient tool for my purposes is lsyncd. This allows me to work directly in my encrypted home folder and being able to see changes almost instantly in the apache web page. The synchronization is triggered by changes in the file system, calling an rsync. As I'm only working on rather small web pages and scripts, the syncing is very fast. I decided to use a short delay of 1 second before the rsync is started, even though it is possible to set a delay of 0 seconds.

Installing lsyncd (in Ubuntu):

sudo apt-get install lsyncd

Starting the background service:

lsyncd -delay 1 -rsync /home/<me>/<work folder>/ /var/www/html/<web folder>/

In addition to changing the permissions as the other answers have indicated, I had to restart apache for it to take effect:

sudo service apache2 restart

Yet another subtle pitfall, in case you need AllowOverride All:

Somewhere deep in the fs tree, an old .htaccess having

    Options Indexes

instead of

    Options +Indexes

was all it took to nonchalantly disable the FollowSymLinks set in the server config, and cause a mysterious 403 here.

With the option FollowSymLinks enabled:

$ rg "FollowSymLinks" /etc/httpd/
/etc/httpd/conf/httpd.conf
269:    Options Indexes FollowSymLinks

you need all the directories in symlink to be executable by the user httpd is using.

so for this general use case:

cd /path/to/your/web
sudo ln -s $PWD /srv/http/

You can check owner an permissions with namei:

$ namei -m /srv/http/web
f: /srv/http/web
drwxr-xr-x /
drwxr-xr-x srv
drwxr-xr-x http
lrwxrwxrwx web -> /path/to/your/web
drwxr-xr-x /
drwxr-xr-x path
drwx------ to
drwxr-xr-x your
drwxr-xr-x web

In my case to directory was only executable for my user:

Enable execution by others solve it:

chmod o+x /path/to

See the non executable directory could be different, or you need to affect groups instead others, that depends on your case.

As recommended on this discussion on the Arch wiki, the default approach of setting the whole path for the other group using:

chmod o+x /root /root/site /root/site/about

is not the most secure way, since any user with access to the server will be able to access and execute files on the path exposed.

Preferably, you should set permissions to a particular user using ACL permissions. In the case of the Apache HTTP server, that user would be "http", and permissions could be set by doing (in arch, you will need the acl package installed):

setfacl -m "u:http:--x" /path/to/directory"

You will have to set this recursively (first to /path, then /path/to, etc).

Compared to the most voted solution, only a particular user will be able to access this directory, so security is increased.

Bonus tip: if the path is mounted on a zfs pool, you will need to add the option acltype in your zpool configuration. This can be done with:

zfs set acltype=posixacl your_zpool

Then, by restarting the machine, the volume will be mounted again with the correct configuration, and the code above will work.

In my case, all of the above function, except that SElinux was blocking all symlink request. Additionally to httpd.conf, grp and file permissions, and lsyncd, I also set SELinux to permissive and it works!

In my case I was having symlinks in my /Sites folder which suddenly stopped working and resulting in a 403. If you're on a Mac, check the Security & Privacy screen and see if http has access to your folder.

The checkbox under Files and Folders for httpd was somehow unchecked. (Perhaps due to an update, since it seems I have 2 httpd's). Enabling the checkbox fixed the issue.

enter image description here