Add `crossmnt` option to NFS Exports

Problem/Justification
When mounting ZFS datasets, with the snapshot directory visble, via NFS, the directories in .zfs/snapshot are empty. This appears to be due to the lack of a crossmnt option for the NFS export. If that option is manually added to /etc/exports, the snapshot directories in the NFS mounted dataset are populated. Having the ability to peruse ZFS snapshots over NFS exports is useful in allowing end users the ability to recover individual files and directories.

Impact
The benefit is that all TrueNAS users would have the option to enable this NFS export option to allow access to ZFS snapshots via NFS mounts. Assuming this feature is properly tested, I don’t see any disadvantages.

User Story
I imagine something as simple as a “crossmnt” checkbox in the NFS export menu would suffice.

1 Like

Would this also include sub-datasets in a NFS exports? For example, I have datasets of pool/Video, pool/Video/TV, and pool/Video/Movies. Each of them needs a separate NFS export, and needs to be mounted separately. Would this option expose all of them to a single mount?

As far as I know, that is exactly what it should do.

From the man page exports(5) - Linux manual page (man7.org):

   crossmnt
              This option is similar to nohide but it makes it possible
              for clients to access all filesystems mounted on a
              filesystem marked with crossmnt.  Thus when a child
              filesystem "B" is mounted on a parent "A", setting
              crossmnt on "A" has a similar effect to setting "nohide"
              on B.

              With nohide the child filesystem needs to be explicitly
              exported.  With crossmnt it need not.  If a child of a
              crossmnt file is not explicitly exported, then it will be
              implicitly exported with the same export options as the
              parent, except for fsid=.  This makes it impossible to not
              export a child of a crossmnt filesystem.  If some but not
              all subordinate filesystems of a parent are to be
              exported, then they must be explicitly exported and the
              parent should not have crossmnt set.

              The nocrossmnt option can explicitly disable crossmnt if
              it was previously set.  This is rarely useful.

This option has serious security implications, for what are likely similar reasons you can’t enable insecure wide links in Samba on TrueNAS. Since datasets are indeed separate file systems, allowing a user to mount into one and traverse into another would be dangerous and bad practice. Especially in a world where people just mapall to root. :\

1 Like

If you wanted to expose some dataset as ro, others as rw, or different dataset to different IP ranges, then clearly you would use separate exports.

But if @dan can use one export with the crossmnt option instead of several, the result is the same filesystem datasets are exposed to the client. Why is this less secure?

If you’re saying the UI should restrict users from making bad choices that’s a different matter. But AFAIK using the crossmnt option where appropriate is not bad practice. What I’ve always understood is good practice in Linux is to define a NFS root in a discrete directory tree which will keep users limited to that mount point and combine this with bind mounts.

https://wiki.archlinux.org/title/NFS

https://help.ubuntu.com/community/NFSv4Howto#NFSv4_without_Kerberos

https://www.stephenrlang.com/2016/01/setup-nfsv4-on-centos/

Using bind mount means additional entries in /etc/fstab or using systemd-mounts. This “good practice” doesn’t fit with SCALE.

What is definitely not “good practice” is the continued use of terms alien to Linux in the NFS UI, you will not find the mapall option in the Linux exports man pages. This has simply been copied from TN CORE/FreeBSD and never changed. Of course, the magic “crossmnt” option does not exist in FreeBSD, which may explain in part why it does not appear as an option in SCALE.

Can you please elaborate on which security implications this are? With crossmnt, you are just exporting a directory tree as you see it in the mounted file system of the server, instead of a single dataset. The differentiation / security boundary without crossmnt is by mount points, which is in my point of view just as arbitrary for a security boundary as a directory tree (with crossmnt) is.
In the end you need to know what you are doing. But for operating a server that holds security relevant data, that should hopefully be the case anyway.

I’m not even saying this necessarily shouldn’t be available. AFAIK crossmnt did not function this way in FreeBSD. For @dan’s usecase it may be appropriate, but it depends. With proper UID/GID mappings, I’d be less concerned, but crossmnt and the mapall root combination is what scares me.