NFS Relative Mounts
Help with this article: http://www.bermweb.net/?p=41
And also: http://lukas.zapletalovi.com/2011/05/export-for-both-nfs-v4-and-v3-clients.html
NFSv3 and NFSv4 have a difference between them that NFSv4 supports exports that are virtualized and therefore can be relativized.
NFSv3 – Absolute mounts
Imagine you have the following shares that you want shared (on the server 10.10.10.10, so 10.10.10.10 is the NFS server)
/DATA/share1
/DATA/share2
/DATA/share3
Note we want to share, share1 and share2 but not share3.
And imagine you have the following NFS exports for them
# cat /etc/exports /DATA/share1 *(rw,sync,insecure,no_subtree_check,nohide) /DATA/share2 *(rw,sync,insecure,no_subtree_check,nohide)
NOTE: the exports file is not what NFS actually shares, the final exports file is actually “/var/lib/nfs/etab“. exportfs takes stuff from “/etc/exports” and puts its in in “/var/lib/nfs/etab“. Also if you look into “/var/lib/nfs/etab” you will notice that in all actuality the system adds on extra mount options – similarly to doing a simple mount, then looking at the output of “mount” or “cat /proc/self/mountinfo” and seeing alot of extra options that werent assigned
Just typical export for the shares.
You would then do this to activate those “exports” (Exports, nfs shares, whatever same term in my book right now)
exportfs -a # export all (it will add on to any other exports that are in /var/lib/nfs/etab)
or
exportfs -rv # delete old exports that are no longer valid, then reexport
or
exportfs -v # to see the current exports, you would run
Now to mount them you would do something like this:
mount 10.10.10.10:/DATA/share1 /mnt1/ mount 10.10.10.10:/DATA/share2 /mnt2/
Or you can do a loopback NFS mount from the same machine (from 10.10.10.10)
mount localhost:/DATA/share1 /mnt1/ mount localhost:/DATA/share1 /mnt2/
Just make sure /mnt has nothing in it
NFSv4 – Relative Mounts the Recommended way
With NFSv4 we can make the mount command relative, so like this:
mount 10.10.10.10:share1 /mnt1/ mount 10.10.10.10:share2 /mnt2/
Notice no need to mention the /DATA/ part… Its relative…
Here is how you do that.. You need to create a bind mount first, to create your virtual tree.
So on the 10.10.10.10 server
mkdir /theroot/ mkdir /theroot/share1 mkdir /theroot/share2 mount -t bind /DATA01/share1 /theroot/share1 mount -t bind /DATA01/share2 /theroot/share2
NOTE: now of course in a production environment you would have these bind mounts setup in /etc/fstab. Look up” bind mounts /etc/fstab” in google if unsure how to do that (its super simple)
Now we need to use the option fsid=0 on the primary export directory (its the root of share1, and share2, where all relativity will start from, in this case thats /theroot)
# cat /etc/exports /theroot *(ro,sync,no_subtree_check,insecure,fsid=0) /theroot/share1 *(rw,sync,insecure,no_subtree_check,nohide) /theroot/share2 *(rw,sync,insecure,no_subtree_check,nohide)
NOTE: notice theroot is made ro so that it cant be messed with
Now run one of the exportfs commands again to take on effect (probably want to run exportfs -rv, so as to clear the old exports from /var/lib/nfs/etab)
Now the relative mount should work
As a remote mount from an NFS client:
mount 10.10.10.10:share1 /mnt1/ mount 10.10.10.10:share2 /mnt2/
As a loopback mount from the server machine (10.10.10.10):
mount localhost:share1 /mnt1/ mount localhost:share1 /mnt2/
NFSv4 – Relative Mounts without Bind mounts
If you dont do bind mounts like above, and did the exports like this instead
# cat /etc/exports /DATA1 *(ro,sync,no_subtree_check,insecure,fsid=0) /DATA1/share1 *(rw,sync,insecure,no_subtree_check,nohide) /DATA1/share2 *(rw,sync,insecure,no_subtree_check,nohide)
Well now we can still do the following mounts
mount localhost:share1 /mnt1/ mount localhost:share1 /mnt2/
mount 10.10.10.10:share1 /mnt1/ mount 10.10.10.10:share2 /mnt2/
But we could also infiltrate DATA folder with the following mount
mount 10.10.10.10:. /mnt3 mount localhost:. /mnt3
The “dot” mount will mount fsid=0, now in this case its not a bind mount and DATA will have access (read only as it may) to share1, and share2 and share3 as well (but we dont share3 shared out)
With relative mounts from above, recall look like this:
# cat /etc/exports /theroot *(ro,sync,no_subtree_check,insecure,fsid=0) /theroot/share1 *(rw,sync,insecure,no_subtree_check,nohide) /theroot/share2 *(rw,sync,insecure,no_subtree_check,nohide)
When we do a “dot” mount:
mount 10.10.10.10:. /mnt3 mount localhost:. /mnt3
We will only see share1, and share2 (And we will not see share3, because we dont want to see share3 🙂 )