Apache won't follow symlinks (403 Forbidden)

148,474

Solution 1

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.

Solution 2

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>/

Solution 3

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

Solution 4

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.

Solution 5

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.

Share:
148,474
Tim
Author by

Tim

Updated on July 08, 2022

Comments

  • Tim
    Tim almost 2 years

    I'm having some trouble setting up Apache on Ubuntu. I've been following this guide.

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

    My public directory, /var/www, can successfully serve up and execute PHP pages that are placed in it. However, I want to create a symlink in /var/www that points to a directory in my home folder and serve pages there.

    [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
    

    When I try to access /about on browser, I get

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

    As far as I know, I gave sufficient privileges to the files I want to serve:

    [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
    

    I'm aware of the FollowSymLinks option, and I believe it's set in my /etc/apache2/sites-enabled/000-default file:

    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>
    

    Any idea what I could be missing?

  • Tim
    Tim almost 13 years
    Thanks a lot... I didn't realize the parent directories also had to be executable.
  • Michal Rzemieniecki
    Michal Rzemieniecki almost 12 years
    Well, I'm not telling it won't work but in general, giving o+x on /root is not a good idea ;)
  • Pieter le Roux
    Pieter le Roux over 10 years
    Michal is right. I found I could use ACLs (in Mac, at least): chmod -R +a "_www allow list,search,readattr" /root /root/site /root/site/about, which grants those permissions to just the apache app (_www), which is a bit safer than "other".
  • Ernani Joppert
    Ernani Joppert almost 10 years
    On the Mac OS (10.9.4) my ~/Documents had no execution rights and I had a git repo where it would host my site files. Granting chmod o+x on ~/Documents did the trick! Thanks!
  • Ernani Joppert
    Ernani Joppert almost 10 years
    Also adding chmod +a "_www allow list,search,readattr" ~/Documents does the trick as well
  • whoan
    whoan about 9 years
    Finally got the answer! Thanks.
  • coffeeak
    coffeeak over 8 years
    This saved my day! Been creating alias and thinking why the hell it's not working?! This solution worked in 1 minute!
  • Alexis Wilke
    Alexis Wilke over 7 years
    Note that the Order/Allow/Deny commands are still available on most computers. In newer versions, it is implemented in the access_compat module. If that module is enabled, the first part is not unlikely to work as expected. If it is not there, then trying to start Apache2 should fail with errors.
  • mkasberg
    mkasberg over 7 years
    The sudo -u www-data ... is a great way to check if there is a permissions problem! Note that the user could be www-data, apache, or something else depending on your distro.
  • deesto
    deesto about 7 years
    In Apache 2.4, your solution will invalidate the config and httpd will fail to start, as you can't combine '+' and '-' in a single Options line.
  • kalabalik
    kalabalik about 7 years
    Arghh, finally! I was already doubting my most basic abilities!
  • myol
    myol over 6 years
    Lost hours to this and it was encryption in the end!
  • rogerdpack
    rogerdpack about 6 years
    Yep that was it, even though I had declared a DocumentRoot "earlier" in the file it was overridding the child Directory section (what?)
  • Aaron Franke
    Aaron Franke over 4 years
    Which config? The /etc/httpd/conf/httpd.conf does not exist on my system, and also, the directory /etc/httpd/ does not exist.
  • Aaron Franke
    Aaron Franke over 4 years
    What if I don't have the /etc/httpd/ folder on my system?
  • RightHandedMonkey
    RightHandedMonkey over 4 years
    @AaronFranke Do you have apache installed? Could be here: /etc/apache2/httpd.conf /etc/apache2/apache2.conf /etc/httpd/httpd.conf /etc/httpd/conf/httpd.conf
  • Aaron Franke
    Aaron Franke over 4 years
    Yes I have Apache installed, and I'm on Ubuntu. /etc/apache2/apache2.conf exists for me.
  • Elijah
    Elijah about 3 years
    This is not the most secure way. Preferably, you should do something as described here. Basically you set permissions specifically to the http user with "setfacl -m "u:http:--x" /path".
  • palacsint
    palacsint about 3 years
    @Elijah: Thanks for the great hint! Could you write it as a new answer, please? I'd upvote that.
  • Elijah
    Elijah about 3 years
    Thanks @palacsint, I just did! You can find it here.