Apache: Create/Mount Same Identical Directory in Different Path

One of our web developer required to have 2 directories to be always identical, which means whatever files contain in directory ‘a’ will be appeared in directory ‘b’. From the server and operating system point-of-view, this can be achieved using several methods:

  • Use symbolic link
  • Use mount bind
  • Use bindfs

Each and every method has advantages and disadvantages which will be explained accordingly. I will using following variables:

OS: CentOS 6 64bit
Document root: /home/user/public_html
Directory #1 (reference): /home/user/public_html/system1/filesharing/
Directory #2 (follower): /home/user/public_html/system2/filesharing/

Method 1: Symbolic Link

1. Before you want to use symlink in Apache, you need to allow the functionality in Apache configuration file. Add following line into /etc/httpd/conf/httpd.conf (this will affect into global configuration):

Options +FollowSymLinks -SymLinksIfOwnerMatch

Or:

You can specifically add following line into user’s public_html directory .htaccess file:

Options +FollowSymLinks -SymLinksIfOwnerMatch

It will required AllowOverride to be turned on in httpd.conf as below:

AllowOverride ALL

2. Restart the Apache server for new configuration to be loaded:

$ /etc/init.d/httpd restart

3. Navigate to the secondary directory and create a symbolic link:

$ cd /home/user/public_html/system2
$ ln -s ../system1/filesharing filesharing

This will virtually map the filesharing directory under system1 into system2 directory using relative path.

Advantages:

  • Symlink can be executed in user level as long as the user has write permission to the current directory.
  • You can use PHP symlink function to create symlink.
  • Whenever you delete the follower directory, it will not delete the reference directory. It only remove the symbolic link.
  • You can use relative path.

Disadvantages:

  • By default Apache will turn above option off. So you might see following error which is popular:
     Symbolic link not allowed or link target not accessible
  • Anyone can remove the symlink easily. For example, user A create symlink to user B folder and user B then can remove symlink without user A acknoledgement.
  • Symlink is one of the most popular method for hackers to browse around directories in server. No matter in which directory they can get into, symlink will be working as long as they have the write permission to the directory, usually /tmp. For example, from /tmp folder I can symlink to /var/lib/mysql and browse all databases name inside the server.

Method 2: Mount bind

1. As root user, you can use mount bind to mount same directory with different name. Create a new directory to be mount in the follower directory:

$ mkdir -p /home/user/public_html/system2/filesharing

2. Mount the follower directory to the reference directory:

$ mount --bind /home/user/public_html/system1/filesharing /home/user/public_html/system2/filesharing

3. Add following line into the /etc/fstab if you want it to mount during boot (sysinit) or /etc/rc.local if you want to mount it after boot complete:

For /etc/fstab:

/home/user/public_html/system1/filesharing    /home/user/public_html/system2/filesharing    none    bind    0 0

For /etc/rc.local:

mount --bind /home/user/public_html/system1/filesharing /home/user/public_html/system2/filesharing

You can unmount it manually using following command:

$ umount /home/user/public_html/system2/filesharing

Advantages:

  • Apache will treat both directories as normal directory, which can bypass some expected error in symlink.
  • Only root and sudoers are able to execute this.
  • Mount command options can be applied to follower directory like read-only, permission and ownership.

Disadvantages:

  • You need to make sure the path is mounted correctly. For example after reboot or whenever the reference’s hard disk is having mounting or I/O problem.
  • Use mount bind with precaution. Most Linux and Unix file systems don’t allow hard links to directories (except for the . and .. entries that mkdir creates itself). The reasons are are pretty obvious: you could really confuse programs like ls (ls -R)find and of course fsck if you created links that recursed back to themselves.

Method 3: Bindfs

1. Bindfs is actually working similar to mount bind, instead it is using FUSE for mounting and having better functionality and permission configuration compare to mount. Before installing bindfs, we need to install FUSE with development package using yum:

$ yum install fuse fuse-devel -y

2. Download bindfs at here and install:

$ cd /usr/local/src
$ wget http://bindfs.googlecode.com/files/bindfs-1.10.3.tar.gz
$ tar -xzf bindfs-1.10.3.tar.gz
$ cd bindfs-* 
$ configure
$ make
$ make install

3. Create the ‘filesharing’ directory and mount the directory as below:

$ cd /home/user/public_html/system2
$ mkdir filesharing
$ bindfs -p 755 /home/user/public_html/system1/filesharing filesharing

3. Add following line into the /etc/fstab if you want it to mount during boot (sysinit) or /etc/rc.local if you want to mount it after boot complete:

For /etc/fstab:

bindfs#/home/user/public_html/system1/filesharing    /home/user/public_html/system2/filesharing    fuse    perms=755    0 0

For /etc/rc.local:

bindfs -p 755 /home/user/public_html/system1/filesharing /home/user/public_html/system2/filesharing

You can use mount command to check whether it is mounting correctly or not:

$ mount | grep bindfs
bindfs on /home/user/public_html/system2/filesharing type fuse.bindfs (rw,nosuid,nodev,allow_other,default_permissions)

To unmount manually, simply use umount command:

$ umount /home/user/public_html/system2/filesharing

Advantages:

  • You can create custom rules depending on the policy as you can refer to the man page here. It is useful if you want different people to access with different attributes instead of following the reference directory attributes.
  • Apache will treat both directories as normal directory, which can bypass some expected error in symlink.
  • Only root and sudoers are able to execute this.

Disadvantages:

  • It run on top of FUSE. In some kernel, FUSE has performance issues and easy to hang.
  • You need to make sure the path is mounted correctly. For example after reboot or whenever the reference’s hard disk is having mounting or I/O problem.