9

First, some background:

  • /dev/md1 is a RAID-0 array serving as primary file store. It is mounted to /var/smb.
  • /dev/md2 is another RAID-0 array storing backup snapshots taken from /dev/md1. It is mounted to /var/smb/snapshots.
  • Three directories are made available via Samba: /var/smb/files (publicly-shared files), /var/smb/private (private files), and /var/smb/snapshots (providing read-only access to backup snapshots).

Only users in the smbusers group are allowed to access the files and snapshots shares; similarly, only users in the smbprivate group are allowed to access the files in private. Additionally, Linux permissions prohibit users not in the respective groups from accessing the files and private directories, both on the local system and within the snapshots Samba share.

This is great, because it means that we have a fully functional file server with a self-help "restore from backup" option (users can simply access the snapshots share and retrieve the file(s) they want to restore themselves), but so far I lack one key ingredient: Non-root access on the local system to the /var/smb/snapshots directory.

The snapshots must be strictly read-only to all regular users, however of course the file system must be mounted read-write to allow the backup operation to take place. The permissions on these directories are currently:

root@odin:/var/smb# ll
total 40
drwxrwxr-x  7 root   root        4096 2011-04-11 15:18 ./
drwxr-xr-x 14 root   root        4096 2011-04-10 19:07 ../
drwxrwx--- 15 kromey smbusers    4096 2010-12-07 13:09 files/
drwxrwx---  7 kromey smbprivate  4096 2010-04-07 07:08 private/
drwxrwx---  3 root   root        4096 2011-04-11 15:16 snapshots/

Now, what I want is to provide access to the snapshots directory to non-root users, but in a strictly read-only fashion. I can't mount /dev/md2 read-only, though, because I have to have it read-write to run backups; I can't simply re-mount it read-write for a backup and then re-mount it back to read-only, because that provides a window of time when the backups could be written to by another user.

Previously I did this by making my snapshots directory a read-only NFS export (only to localhost) and mounting that locally (the original secured under a directory lacking traversal rights for non-root users), but this feels like a hack and there seems like there should be a better way to accomplish this. I did try the mount --bind option, but it seems to lack the ability to have different access levels (i.e. read-only versus read-write) on the two directories (unless I'm missing something: mount -r --bind dir1 dir2).

Any ideas how I can accomplish this without NFS, or is that my best option?

TL;DR: How can I make the contents of a file system available read-write to a select user, but strictly read-only to everyone else, while maintaining original permissions and ownerships on the files backed up to this file system?

5
  • Could one do this using acl, perhaps? Off the top of my head, that seems a natural way to go, since acl is an extension of unix file permissions. Also, acl exists alongside standard unix permissions. Apr 12, 2011 at 21:02
  • @Faheem Admittedly, I don't know whether it can or cannot be done with acl, but I suspect not, since one of my requirements here is to preserve existing permissions (to make it easy for users to restore files from backup themselves without having to change permissions again when they do so) while also making the whole thing read-only. I know, that sounds contradictory, but thanks to Gilles' help below, I do have an answer for it.
    – Kromey
    Apr 12, 2011 at 21:45
  • acl can override unix permissions without changing them. The idea is that when users copy back stuff out they have the same permission flags as their original backup, right? So you could set acl to whatever permissions you want for whatever user. If an acl entry is set, it ignores the corresponding unix permission without changing it. See man acl for details. Apr 12, 2011 at 22:11
  • @Faheem Will the extra acl permissions effectively "disappear" when the file is copied out of the backup? If the acl permissions "stick" to the file when it's moved, then it really doesn't matter that the (ignored) underlying Unix permission bits are unchanged. I'll look into it, though, as a possible simpler solution...
    – Kromey
    Apr 12, 2011 at 22:14
  • The acl permissions are set on the directory path, so yes, they "disappear" if the file is moved out. :-) And I don't think any standard unix tools try to preserve them unlike cp -a preserving unix permissions, for example, since in general it would not make sense. acl is not supported in general. The kernel has to support it & you have to enable it on the filesystem when you mount it, as a mount option. Apr 12, 2011 at 22:20

2 Answers 2

7

@Gilles was really close, just ever-so-slightly off the mark for Ubuntu 10.10 (I don't have any reason to doubt he's right for Debian Squeeze, and possibly others). By mounting my read-write snapshots directory under a folder that other users cannot access (e.g. /var/smb/hidden/snapshots, where /var/smb/hidden has permissions 770 and is owned by root:root), I can protect the read-write mount from other users. I can then use mount --bind followed by mount -o remount,ro to bind the mount to an accessible location, then make it read-only.

(The inverse (mount the original file system read-only, then bind it read-write) does not work; similarly, mounting the original read-only, then binding it read-only, then re-mounting the original read-write makes the bound directory also read-write.)

So to recap, here's the solution:

mkdir /var/smb/hidden
chown root:root /var/smb/hidden
chmod 770 /var/smb/hidden
mkdir /var/smb/hidden/snapshots
mksdir /var/smb/snapshots
mount /dev/md2 /var/smb/hidden/snapshots
mount --bind /var/smb/hidden/snapshots /var/smb/snapshots
mount -o remount,ro /var/smb/snapshots

So there is a brief window of time where the backups are read-write and generally accessible, but it's small enough to be usable for my needs. Some trickery with the permissions on /var/smb could protect it during this brief window (i.e. make it non-traversable, then bind the mount, then make it traversable again), if those brief milliseconds are too big a window.

Now I just have to put this all together in a script. Slip it into the start-up process right after everything is mounted perhaps, which should avoid any conflict that might be caused by Samba trying to share the directory I'm binding to.

Note: If your distro supports the mount -o bind,ro version as Gilles posted, I recommend that solution for you; my solution is here should only be used by folks on Ubuntu or other distros that won't permit you to change mount options when binding to another directory.

2
  • 2
    I observe the same (rather confusing!) behavior as you on Ubuntu 10.04. Apr 12, 2011 at 0:49
  • Man, +1! This helped me make a busybox mount work as intended. But I'm still confused. Jul 22, 2012 at 11:40
6

This answer works on Debian (tested on lenny and squeeze). After investigation, it seems to work only thanks to a Debian patch; users of other distributions such as Ubuntu may be out of luck.

You can use mount --bind. Mount the “real” filesystem under a directory that's not publicly accessible. Make a read-only bind mount that's more widely accessible. Make a read-write bind mount for the part you want to expose with read-write access.

mkdir /media/hidden /media/hidden/sdz99
chmod 700 /media/hidden
mount /dev/sdz99 /media/hidden/sdz99
mount -o bind,ro /media/hidden/sdz99/world-readable /media/world-readable
mount -o bind /media/hidden/sdz99/world-writable /media/world-writable

In your use case, I think you can do:

mkdir /var/smb/hidden
mv /var/smb/snapshot /var/smb/hidden
mkdir /var/smb/snapshot
chmod 700 /var/smb/hidden
chmod 755 /var/smb/hidden/snapshot
mount -o bind,ro /var/smb/hidden/snapshot /var/smb/hidden/snapshot

I.e. put the real snapshot directory under a restricted directory, but give snapshot read permissions for everyone. It won't be directly accessible because its parent has restricted access. Bind-mount it read-only in an accessible location, so that everyone can read it through that path.

(Read-only bind mounts only became possible several years after bind mounts were introduced, so you might remember a time when they didn't work. I don't know offhand since when they work, but they already worked in Debian lenny (i.e. now oldstable).)

7
  • Maybe Ubuntu is packing a very out-dated mount (2.17.2 according to mount -V), but that command didn't work (and according to the man page, you cannot change mount options as part of the bind command). However, I did have success (after going through the man page for the fiftieth time) doing mount --bind /var/smb/snapshots /var/smb/test followed by mount -o remount,ro /var/smb/test. (Obviously this was a test, if you couldn't tell by my lovely directory names!)
    – Kromey
    Apr 12, 2011 at 0:07
  • That's strange: mount 2.13.1 happily creates a read-only bind mount on a 2.6.32 kernel (Debian squeeze), and I remember it could on 2.6.26 too (lenny). The man page was correct once but needs updating. Apr 12, 2011 at 0:19
  • I've tried every permutation of the bind and ro options I could think of (incidentally, "bind" is not a valid option to -o, but is a valid switch as --bind or -B), but got nowhere with that. Kernel 2.6.35 (Ubuntu Maverick Meercat). Maybe Debian has an entirely different mount command? But Ubuntu is based on Debian, so that doesn't seem likely. That's a really weird place to find a difference in these two distros...
    – Kromey
    Apr 12, 2011 at 0:34
  • @Kromey: I've just tested on Ubuntu 10.04, and mount -o bind,ro doesn't work there either. So I guess this is a Debian patch after all! Apr 12, 2011 at 0:47
  • 1
    I'm accepting your answer on this one since a) it's (apparently, I can't verify it myself) valid for Debian (and likely others as well), and b) it directly lead me to finding the solution on Ubuntu. However, for future folks reading this one, Gilles' answer won't work on Ubuntu, and you'll instead need my answer.
    – Kromey
    Apr 12, 2011 at 0:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .