Curing ‘Symbolic link not allowed’ (Apache 2.0)

closeThis post was published 4 years 7 months 24 days ago which may make its actuality or expire date not be valid anymore. This site is not responsible for any misunderstanding.

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:

  • When installing the OS, add the /var mount-point to a larger disk/partition.
  • Add a new (larger) disk to the system, format it accordingly, migrate the old /var/ mount-point to the new partition and change the DocumentRoot in the Apache configuration. This requires backing up old files and pushing them to the new partition and reconfiguring a small part of Apache; could cause a lot of downtime.
  • Use symbolic links within the DocumentRoot.

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):

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:

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:

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:

ls

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

ls -l /var/www/

You should then see something like this:

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 directive:

Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all

Now, restart Apache:

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

[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:

# 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.