I can't get apache to follow symlinks outside the web root directory, even though permissions look OK and FollowSymLinks is on. The details are below.

I have two world-readable text files: /tmp/hello and /var/www/html/hello. Also in webroot I have symlinks to both those files. Both seem fine.

$ ll /tmp
drwxrwxrwt. 27 root   root       4096 Jul  8 13:55 ./
dr-xr-xr-x. 23 root   root       4096 Jul  4 23:24 ../
-rw-r--r--.  1 root   root          6 Jul  8 13:55 hello

$ ll /var/www/html
drwxr-xr-x. 3 root   root   4096 Jul  8 13:56 ./
drwxr-xr-x. 6 root   root   4096 Apr  4 12:57 ../
-rw-r--r--. 1 root   root     20 Jul  8 14:03 hello
lrwxrwxrwx. 1 root   root      5 Jul  8 14:04 link-local -> /var/www/html/hello
lrwxrwxrwx. 1 root   root     10 Jul  8 13:56 link-tmp -> /tmp/hello

$ cat /var/www/html/link-local 

$ cat /var/www/html/link-tmp 

Apache can follow the link to the web root:

$ curl http://localhost/link-local

But Apache won't follow the symlink to /tmp/:

$ curl http://localhost/link-tmp
<title>403 Forbidden</title>
<p>You don't have permission to access /hellolink on this server.</p>
<address>Apache/2.2.15 (CentOS) Server at localhost Port 80</address>

This is on CentOS 6; http runs as user apache, group apache.

Why is this happening? How can I fix it?

  • After further experimentation, I suspect the problem is to do with some sort of permission problem on the /tmp/hello file. But I still don't understand the details. – Bennett McElwee Jul 8 '14 at 10:54

Yes, It looks as if SELinux is the culprit:

The -Z switch will work with most utilities to show SELinux security contexts (e.g, 'ls -Z', 'ps axZ' etc).

$ ll -Z /var/www/html/hello
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/hello

$ ll -Z /tmp/hello
-rw-r--r--. root root unconfined_u:object_r:user_tmp_t:s0 /tmp/hello

The two target files have different types (httpd_sys_content_t vs user_tmp_t), which explains the difference in accessibility.

The SELinux page at centos.org explains the -Z switch and much, much more.

  • 1
    For myself, SELinux was disabled, but the status showed permissive mode. After a reboot, the status was "disabled" and my original symlink config worked as before. All of my Unix permissions were correct, but apparently a mismatched SE security context even in permissive mode will cause Apache to fail. – jimp Dec 6 '18 at 20:29

Are you setting FollowSymlinks in an .htaccess file? or in a <Directory> block?

Apache 2.2 Options documentation suggests that FollowSymlinks will only work in these contexts - could you post the relevant config?

(posting as an answer due to insufficient points to comment)

  • FollowSymLinks is set in a <Directory> block. Note that Apache does follow the link-local symlink, but not the link-tmp symlink in the same directory. – Bennett McElwee Jul 8 '14 at 10:53
  • 1
    It's perhaps a shot in the dark: do you have SELinux enabled? That could be causing what you're seeing... also, have you tried achieving the same thing using an Alias directive? httpd.apache.org/docs/2.2/urlmapping.html#outside – Andrew Jul 8 '14 at 18:48
  • it appears that SELinux is enabled (getenforce results in Enforcing). I will have to do some experimenting to see if that's the cause. – Bennett McElwee Jul 8 '14 at 22:23
  • I'm sure I could use an Alias to do this, but for me a symlinks is clearer and more transparent - a simple ls -l will tell you where files are being serves from, rather than having to go looking through httpd.conf. Also I just wanted to know why the symlink doesn't work! :) – Bennett McElwee Jul 8 '14 at 22:26
  • 2
    It's almost certainly due to SELinux being enabled - once you've disabled it, you may also need to reboot, since the file system may have been mounted with security contexts enabled, and simply setting selinux permissive or disabled may not clear down the file ACLs - I've had that happen to be before, and only a reboot will fix this. (In spite of online resources/docs suggesting using setenfore to set this on the fly) – Andrew Jul 9 '14 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.