Red Hat Bugzilla – Bug 1480848
NFS fails to forward SELinux labels in some export/mount configurations
Last modified: 2018-01-09 05:52:05 EST
Description of problem:
Some time ago the kernel got the ability to forward SELinux labels over NFS. (For a short while I believe it was the default, but then later changed to an opt-in functionality.) I had this working for a while, but it isn't any more.
Version-Release number of selected component (if applicable):
Steps to Reproduce (on a single host):
1. Export /usr/local with the security_label option:
[root@mimmi Hämtat]# exportfs -s | grep local
2. Mount it with the seclabel option:
[root@mimmi Hämtat]# mount -o seclabel,vers=4.2 mimmi:/usr/local /mnt
3. List the labels in the mounted directory:
[root@mimmi Hämtat]# ls -lZ /mnt
drwxr-xr-x. 3 root root system_u:object_r:nfs_t:SystemLow 4096 6 aug 17.31 bin
drwxrwxr-x. 27 göran familj system_u:object_r:nfs_t:SystemLow 4096 6 jul 16.18 böcker
drwxr-s---. 11 göran göran system_u:object_r:nfs_t:SystemLow 4096 14 feb 22.46 'D&D'
drwxr-xr-x. 2 root root system_u:object_r:nfs_t:SystemLow 4096 1 aug 2003 doc
drwxr-xr-x. 3 root root system_u:object_r:nfs_t:SystemLow 4096 31 jul 15.43 etc
All files and directories in the mounted have the SELinux type nfs_t.
The files should have the same types as in the source /usr/local directory (usr_t mostly, some of them bin_t or lib_t).
I got it to work by exporting entire filesystems - it would not work with subdirectories of mount points.
This page says you need to set fsid=0:
But if you export root it automatically gets fsid 0, others just get a UUID and everything seems to work. (check /proc/fs/nfsd/exports)
Thanks for the tip Chuck. Unfortunately, after reading that and experimenting a bit, I'm even more confused!
The page you referred to is a bit old it seems. Some google hits I found suggested fsid=0 wasn't needed any more. But it was a bit confusing as I said.
I'm also uncertain where to put this fsid=0 in my actual case. The server has one big file system containing (almost) everything mounted as /. From it, I export a handful of directories (/home, /var/spool/mail, /usr/local, etc.). I also have a /remote/pluto which is the root file system of a diskless client.
Which one of these should have the fsid=0? All of them? Do I have to export / from the server for security labels to work?
As an experiment, I did exactly that, on the command line adding an export of / to one client. I didn't include fsid=0, but did include security_label. On the client I mounted that under /mnt. I do indeed see the security labels.
Then I tried to unmount and again mount a couple of the directories normally mounted on the client. In one case the security labels show up. On the other, all the files show up as "unlabeled_t"!
Did I mention I got even more confused?
I didn't mean this to become a request for help. It did work previously, without exporting the entire file system and without fsid=0 anywhere. It did look like a regression to me; I thought it was a bug.
I investigating a bit more, using the following export from a host "freddi":
If I do
mount -o seclabel,vers=4.2 freddi:/ /mnt
I see the correct security labels.
If I create a directory /tmp/etc and do
mount -o seclabel,vers=4.2 freddi:/etc /tmp/etc
I still see the correct security labels.
If I also make a directory /tmp/usr and do
mount -o seclabel,vers=4.2 freddi:/etc /tmp/etc
mount -o seclabel,vers=4.2 freddi:/usr /tmp/usr
all files in both trees show up with the type unlabeled_t.
Is this really the intended behaviour?
I had a similar problem - see bug 1478135. The problem has disappeared in the last weeks - I don't know why but I think some of updated packages has solved it.
Have you installed all updates now?
I had not updated to the latest version. Unfortunately, doing so doesn't help. The test cases in comment 3 behave as before. Case 1 and 2, where i mount only one directory, works as expected. But mounting two directories, as in case 3, makes everything become "unlabeled_t".
(Note that you need to unmount everything between each test, and mount both directories before checking. If you do e.g. "ls" in a mounted directory, the attributes from that directory are cached, and may hide the problems for a while.)
Ok, it is a different problem than mine.
I have tried your test case 2 of comment #3. I see type unlabeled_t too.
But if I don't export "/", but using two exports like
then mounting as in case 2 works fine. Then I see the correct selinux labels.
A personal note:
Why do you want to export the whole file tree starting from / with write permissions and no root squash? From a security point of view I think this is a very bad idea. Every system in the subnet can manipulate even the running kernel memory on the nfs server (at least in theory, I didn't try it), because you even export /dev, /proc/, /sys, etc. with full root access.
If you want to share /etc or /usr, I would export them read-only, and use some overlay fs on it if clients need to write files on them. If you want to use diskless systems, then each client should have at least its own directory for /etc and /var in directory or partition different from nfs servers /etc and /var directories.
Interesting! Exporting /etc and /usr separately does indeed work.
But only one level below the root of the file system! Here is a fourth test case.
Export /usr/bin only:
Mount it on the client side:
mount -o seclabel,vers=4.2 freddi:/usr/bin /mnt
Now it fails again. In a slightly different way, the files don't show up with unlabeled_t this time, but with nfs_t. But labels are not exported, all the same.
As for wanting to export the root file system. It's not what I really want to do in most cases. (In one case I backup a client by mounting its root on a server and backing up that way.) All the hosts involved have the same administrators, and "trust" each other anyway.
But I tried to test the behaviour, and to create a simplified test case. (Maybe too simplified as it turns out.)
I can confirm that there is still a problem with nfs and selinux labels with current updated Fedora 26.
- If the mount point of a local file system is exported, excluding "/", using export option security_label, then selinux labels are forwarded to nfs clients for nfs mounts of the exported mount point or a subdirectory of this.
- Exporting "/" does not forward selinux labels.
- If a direct subdirectory of "/" (first level) is exported, then selinux labels are forwarded to nfs clients for nfs mounts of this exported subdirectory or a subdirectory of this.
- Exporting only a subdirectory of a local file system does not forward selinux labels.
But if exporting the mount point of the local file system too, then a nfs mount of the exported subdirectory contains the forwarded selinux labels.
About test case of comment #7:
Try to export "/usr" in addition to "/usr/bin", then the client side should see the forwarded labels.
Thanks for that suggestion, Edgar Hoch! It was a combination I hadn't tried, and it does indeed work. It makes it possible for me to work around the issue in my actual use cases. (I have to export a bit too much. But as I mentioned above, it doesn't really matter in this context.)
Edgar Hoch's nice workaround doesn't seem to work any more. I have upgraded to
After reboot, all NFS files on the client, apparently regardless of level in the tree this time, are back to "unlabeled_t".
(In reply to Göran Uddeborg from comment #10)
> Edgar Hoch's nice workaround doesn't seem to work any more. I have upgraded
> After reboot, all NFS files on the client, apparently regardless of level in
> the tree this time, are back to "unlabeled_t".
I cannot confirm this. On my systems the nfs client behaviour with these packages is the same as before.
Ok, so I have messed something up again. I'll dig into it again, and report if it seems relevant to anyone else.
When I boot the client with an old 4.12.9-300.fc26.x86_64 kernel, it does see the labels again. When I boot with 4.13.13-300.fc27.x86_64 or (4.13.6-300.fc27.x86_64). It's the same client, the same selinux version (3.13.1-283.17.fc27), and the same userspace otherwise. Only different kernels are chosen at boot.
The server is running 4.13.13-300.fc27.x86_64 in all three cases.
I wonder why it works for you, Edgar, but not for me.
I tried kernel 4.14.8-300.fc27, but with that the files also show up as "unlabeled_t". Going back to 4.12.9-300.fc26 it still works as it should, with "user_home_t" in the home directories etc.
Another data point:
On a different client box (F26, mainly running MythTV) I tried the kernel 4.14.11-200.fc26. Then the label forwarding disappeared, and I was back to "nfs_t". Going back and booting 4.12.14-300 I see normal labels again. This is a diskless client which has nfs root. It mounts /remote/pluto which is exported like this from the server, same server as above:
The file system /remote is exported following the advice in comments in this bugzilla; nothing actually mounts /remote directly.