Home

Gallery

Archives

Blog

About

Contact Me

"Personal thoughts, ramblings, and nonsense from Drew, himself."

Curing ‘Symbolic link not allowed’ (Apache 2.0)

Awhile back when trying to add a directory to Apache on my Ubuntu 6.06 LTS server, I ran into some issues. These issues, of course were the infamous 403 “Forbidden” error that your web barfs up when you try to access a server that is not publicly viewable, because of permission issues. I’m going to give you my scenario and explain how you can fix this issue, so that you don’t have to go through an hour of throwing your hands up in disgust.

The Scenario

In our example, out DocumentRoot (where all the HTML files are stored on the server) is /var/www/. This is the default on most Linux servers and can be a constant fuss when you don’t have that big of a partition for the /var directory. Things that can be done to prevent this is:

As the shade of green emphasizes, we will be using symbolic links. Of course, this should be a very easy task, but can easily become a hassle to get working. Also note that we could have used the other choices above, but I chose the best solution to this problem. I’ll discuss how to set it up, and then I’ll explain how to fix the “Symbolic link not allowed” error found in your Apache error logs when you get the 403 error in your web browser.

Setting It All Up

To give you an idea of what has to be done, we will setup the symbolic links (which I will now refer to as symlinks) and make sure they point to the right directory and actually work. Then we will need to make the adjustments in the Apache configuration file so that the server will accept the symlinks; this will require an Apache restart, which really doesn’t create downtime for the user, unless something goes wrong. If all goes well, this is great. If you aren’t lucky enough to get it the first try, it probably isn’t your fault entirely, and I’ve got you covered with something that led me to the fix. Just a little sidenote, when I say fix, I don’t mean that there’s a bug in the system, I mean that we will resolve a very small issue that is often overlooked. Alright, now on with the good stuff!

Creating The Symlinks

First off, what is a symlink? A symlink is a special type of file, usually found in Unix, which refers to another file by its pathname. So in laymen terms, a symlink is a folder that is redirected to another folder on a Unix system. To those people that argue about my statement about Linux, I know symlinks can also be used in Windows, but that is another article to be written and is totally different from the Unix side.

Okay, so how do we set that symlink setup? This is extremely easy; we just need a few basic commands to get this done. The only thing we have to make sure of is that the destination target actually exists. After we create (or just make sure that the destination target exists) we create the symlink and then make sure it has become a symlink, which can easily be noticed by color or listing, which depends on your system. So, let’s create the destination directory (if needed):

BASH

mkdir /data/www/newdirectory

After the mkdir command you type in where you want your destination target to be at. This is just a folder that you will put regular files such as .html, .css, .php into; web content. I chose /data/www/newdirectory, but you should choose whatever you want. Remember, this is an if-needed basis. If you already know what you are wanting to create a symlink to and you are just wanting to create the symlink to the destination target keep on reading. Alright, now let’s create the symlink. If your DocumentRoot is the default /var/www/, you will want to create your symlink there. If you do not actually know your DocumentRoot is try running one of the following lines:

BASH

cat /etc/apache2/sites-enabled/000-default | grep "DocumentRoot"
cat /etc/httpd/conf/httpd.conf | grep "DocumentRoot"

This should actually output the DocumentRoot target. So, for simplicity sake, we will say that your DocumentRoot is located in /var/www/; this is the most commonly known default DocumentRoot. So, once in that directory we need to actually create the symlink:

BASH

cd /var/www/
ln -s /data/www/newdirectory/ mysymlink

The ln command stands for link and the -s makes it a symbolic (soft) link. It is alot safer to do a symbolic link rather than a hard link; if you delete a hard link, you also delete the actual files, not just the link. So how do you know if your symlink was actually created successfully. A simple ls command should do the trick:

BASH

ls

To find out if the symlink was a success, in our example, go to /var/www/ and type in:

BASH

ls -l /var/www/

You should then see something like this:

BASH Output

lrwxrwxrwx 1 ftpuser  ftp        21 2006-09-13 16:37 mysymlink -> /data/www/newdirectory/

You can also do an ls -l of the symlink, as you normally would a regular directory and you should see all the files as if they were in your /var/www/ directory, even though they are actually in /data/www/newdirectory/. If all goes well, then we have successfully setup our symlink. Now we have to configure Apache to allow these symlinks to work.

Editing Apache 2.0 Configuration File

In Debian systems such as Ubuntu, I have noticed that Apache uses the sites-enabled configuration. This means you must edit the sites within this directory for the changes to be effective. For other systems such as Red Hat you must edit the /etc/httpd/conf/httpd.conf. The default site in Ubuntu is 000-default, so when editing this file and your server is not using the sites-enabled configuration, Red Hat or any other users should probably edit /etc/httpd/conf/httpd.conf. If you have any issues with this, please let me know so I can update this article with additional details on how to do it for particular systems.

Let’s take a look at /etc/apache2/sites-enabled/000-default and add the correct configuration changes to allow for our symlinks to be used. You should add the following to your <directory /var/www/> directive:

Apache Site Configuration

Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all

Now, restart Apache:

BASH

/etc/init.d/apache2 restart      # Debian/Ubuntu
service httpd restart              # Red Hat (easy)
/etc/init.d/httpd restart          # Red Hat (preferred)

Now that’s complete, you should now be able to access this, using our example by pointing your browser to http://yourdomain.com/mysymlink/. Did it work? If so, great! If not, let’s fix it!

Resolving the permission issues

To resolve this issue, more than likely, it is no longer an Apache issue anymore, as we have correctly configured Apache for SymLinks. More than likely, the cause of this issue is due to permissions on the filesystem. I’m going to stick with the example used here so that I don’t confuse anyone. We have been symlinking to the directory /data/www/newdirectory/. First off, make sure the files in the directory that you are symlinking are assigned to the group www-data (or whatever your Apache user’s group is) and make sure that they have read/execute permissions. If this does not resolve the issue, then it’s a little deeper than just a file, which is usually the case.

If you were symlinking the /data/www/newdirectory/, then the /data, /data/www, and the /data/www/newdirectory directories must have at least read access, so that Apache user can access the directory (we will be using the Apache group to share). To resolve this issue, first find out the Apache group is:

BASH

[root@tangerine ~]# cat /etc/httpd/conf/httpd.conf | grep ^Group
Group apache

In Red Hat, the Apache’s group is apache, but if you are using Ubuntu or Debian Linux, the Apache group is usually www-data. In this case, we need to make sure the apache group has read/execute access to the /data, /data/www, and /data/www/newdirectory directories. To do this, you would run the following command:

BASH

# Execute for Red Hat
chmod -R 755 /data/www/newdirectory/ && chown -R :apache /data/www/newdirectory/ 

# Execute only if using Debian or Ubuntu systems
chmod -R 755 /data/www/newdirectory/ && chown -R :apache /data/www/newdirectory/ 

You should not have to restart Apache for the setting to take effect, as this is only permissions on the filesystem. Go back to your web browser and try to refresh the page or bring the page up if you closed your web browser and see if you still get the insufficient privileges error message. If not, great! This had me stumped for the longest time, until I realized sometimes it’s the most obvious things that are the problems. If this didn’t help you to get things working, let me know and let’s try to get it sorted.

Discussion always soothes thy heart.

1 Kekoa Vincent says: Quote this comment

Minor detail, but when you say,

“If you were symlinking the /data/www/newdirectory/, then the /data, /data/www, and the /data/www/newdirectory directories must have at least read access, so that Apache user can access the directory (we will be using the Apache group to share)”

Actually, all you need is execute permissions for the parent directories, so apache can open files within the folder. Not having a read permissions on the directory prevents a user(including apache) from listing the directory’s contents. If the location name is known(as in the case of a symlink), a user can cd to it without read permissions on parent directories. You will want read permission on the directory that you are symlinking though.

2 luke says: Quote this comment

DOH! didin’t realise that the parent dir permissions were important… been hunting around for hours for a solution to this … THANK YOU

3 Drew says: Quote this comment

DOH! didin’t realise that the parent dir permissions were important… been hunting around for hours for a solution to this … THANK YOU

Awesome! You are very welcome. This was my main issue, too, when I was trying to do this for the first time, thus why I documented it. Glad it helped you.

Thanks,
Drew

4 bernd says: Quote this comment

I’ve done everything - at least I think so - what you have suggested, but symlinking is still not working.
The parts of the http.con-File connected to linking are set like this:


DocumentRoot "/var/www/html"
Options FollowSymLinks
Options FollowSymLinks
AllowOverride None
Options FollowSymLinks
Options Indexes FollowSymLinks

But I still get the error message in /var/log/http/error_log:
Directory index forbidden by Options directive:

I will be thankful for a hint, what might be still wrong!

5 Drew says: Quote this comment

Bernd,

You have three Options FollowSymLinks options in your code. Make sure you only have one.

That is just something you should do. However, the error message you are receiving is due to not having an index page in your directory (the one that is symlinked). In order to have Directory Listing is to add a line in your directive, like so:

Options Indexes

Please let me know if you have any questions.

Regards,
Drew

6 Janet says: Quote this comment

I’ve done everything what you have suggested, but i still get the error message shown below:
Forbidden
You don’t have permission to access /cgi-bin/jha.cgi on this server.
Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.
Apache/2.0.52 (Red Hat) Server at rhino.sbcld.sbc.com Port 80
Below is the soft link i created under /var/www/cgi-bin/
jha.cgi -> /home/emasld/EMAS_WEB_PROD/app/jha.cgi

7 Drew says: Quote this comment

Janet,

I believe CGI is handled differently. Have you tried a test file in a different directory (a non CGI-BIN directory), just to make sure the permissions were right? I would check this first before you mess around with the CGI directories, because I believe there is additional configuration for the CGI-BIN directory, for Apache.

Regards,
Drew

8 Janet says: Quote this comment

i tried one htm file(test.htm) in /var/www/html directory and it is working without any problems. I also tried one test file(test.cgi) that doesn’t have any soft links associated with in /var/www/cgi-bin directory and it is working fine. Below is my cgi-bin configuration from httpd.conf : 545 ScriptAlias /cgi-bin/ “/var/www/cgi-bin/”
546
547 #
548 # “/var/www/cgi-bin” should be changed to whatever your ScriptAliased
549 # CGI directory exists, if you have that configured.
550 #
551
552 AllowOverride None
553 Options All
554 Order allow,deny
555 Allow from all
556

9 Janet says: Quote this comment

551
552 AllowOverride None
553 Options All
554 Order allow,deny
555 Allow from all
556

10 Janet says: Quote this comment

sorry line 551 should be
and line 556 should be

11 Jose says: Quote this comment

I had the same situation described here with a RHEL installation. I thought I had all permissions correct, but still the same Forbidden error. I followed the comments here and did a chown to apache, but still the problem!
After some more searching we found about SELinux causing havoc like this. We turned this off issuing “echo 0 > /selinux/enforce” and all is working. I haven’t done more research to see how you can have this ON while still getting the above working, but for those out there who just need to get it going give this a try.

12 Janet says: Quote this comment

THANK YOU Jose. It works fine after i did echo 0 > /selinux/enforce

Go ahead, say somethin'





The Notebook

Windows Fix: "Insufficient system resources exist to complete the API"
Ugh. Another Windows error. Another Windows error that really doesn’t tell you what is really wrong; some (most) people aren’t nerds. Don’t worry, I’ve got your fix right here. This has to do with memory on your Windows XP system. Have you tried Hibernating or putting your system into standby after upgrading your RAM? If you have, keep on reading. More...

Curing 'Symbolic link not allowed' (Apache 2.0)
Awhile back when trying to add a directory to Apache on my Ubuntu 6.06 LTS server, I ran into some issues. These issues, of course were the infamous 403 “Forbidden” error that your web barfs up when you try to access a server that is not publicly viewable, because of permission issues. I’m going to give you my scenario and explain how you can fix this issue, so that you don’t have to go through an hour of throwing your hands up in disgust. More...

VMWare: "Failed to create named-pipe directory" error
Have you ever received the Failed to create named-pipe directory error message via the vmware-mui error log files, and not able to access the VMWare Management Interface? If so, here’s the fix. More...

/bin/rm: Argument list too long
Removing gigs and gigs, or just alot, of unwanted “opened” email that often clutters the system. More...