ZFS set sharenfs multiple hosts

Hi,

How can I use zfs set sharenfs to setup shares to multiple hosts, I tried below but not work, anyone know ?thanks!!

zfs set sharenfs='-network 192.168.1.0/24, -network 192.168.2.0/24,-maproot=root' zdata/bak
 
I see nowhere that you can specify several network options. In your specific case you can try 192.168.0.0/22.

Edit: it's not equivalent as it should also allow 192.168.3.*.
 
The following works for me:

Code:
# grant access to 192.168.1.0/24
zfs set sharenfs='-network 192.168.1.0,-mask 255.255.255.0,-maproot=root' zdata/bak
# grant access to 192.168.2.0/24
zfs set sharenfs='-network 192.168.2.0,-mask 255.255.255.0,-maproot=root' zdata/bak
# grant access to ANY
zfs set sharenfs='-maproot=root' zdata/bak
# grant access to 192.168.1.1, and 192.168.2.1
zfs set sharenfs='-maproot=root,192.168.1.1,192.168.2.1' zdata/bak
# grant accesss to 192.168.1.0/24, and 192.168.2.1
zfs set sharenfs="-maproot=root,-network 192.168.1.0,-mask 255.255.255.0,192.168.2.1"

I don't know why, but CIDR notation like -network 192.168.1.0/24, and multiple -network definitions never worked for me. Perhaps someone else can enlighten us here ?

My approach to this, is limiting the nfsd et al. using the -h parameter to listen to a specific IP address (multiple -h are allowed), and using packet filtering to limit access based on what I need. Most of the time NFS share access are granted based on ANY (see above).

NFSv4 is a bit worse in my humble opinion, as the V4 line needs to be added manually to /etc/zfs/exports (or I just don't know where to put it), which is lost after every reboot as /etc/zfs/exports is automatically generated every time the host reboots. So I keep my own /etc/zfs/exports file and put it in place, every time I have to restart NFSd et al. . However, if you are already editing your /etc/zfs/exports anyway, you could do as well the following:



Code:
# /etc/zfs/exports
# !!! DO NOT EDIT THIS FILE MANUALLY !!!

/bak -maproot=root -network 192.168.1.0 -mask 255.255.255.0
/bak -maproot=root -network 192.168.2.0 -mask 255.255.255.0
 
NFSv4 is a bit worse in my humble opinion, as the V4 line needs to be added manually to /etc/zfs/exports (or I just don't know where to put it), which is lost after every reboot as /etc/zfs/exports is automatically generated every time the host reboots. So I keep my own /etc/zfs/exports file and put it in place, every time I have to restart NFSd et al. . However, if you are already editing your /etc/zfs/exports anyway, you could do as well the following:
You don't put the V4: line in /etc/zfs/exports (as it is marked clearly "!!! DO NOT EDIT THIS FILE MANUALLY !!!") but in /etc/exports.

nfsv4(4)
Code:
     You will also need to add at least one ``V4:'' line to the exports(5)
     file for NFSv4 to work.


As for
I don't know why, but CIDR notation like -network 192.168.1.0/24, and multiple -network definitions never worked for me. Perhaps someone else can enlighten us here ?
I believe I have read that is not supported by sharenfs, but can't find it right now.
 
You don't put the V4: line in /etc/zfs/exports (as it is marked clearly "!!! DO NOT EDIT THIS FILE MANUALLY !!!") but in /etc/exports.

I did, just to find out it's a symbolic link to /etc/zfs/exports . ? Perhaps I should have mentioned that in my initial post, but I was under the impression that this is common sense.

I believe I have read that is not supported by sharenfs, but can't find it right now.

I read the export(5) several times, there is no mentioning about this, the Internet and this Forum are also no help, that's why I posted my solution.
 
I did, just to find out it's a symbolic link to /etc/zfs/exports . ? Perhaps I should have mentioned that in my initial post, but I was under the impression that this is common sense.
You have /etc/exports symlinked to /etc/zfs/exports? Why?
 
You don't put the V4: line in /etc/zfs/exports ... but in /etc/exports.
I did, just to find out it's a symbolic link to /etc/zfs/exports . ? Perhaps I should have mentioned that in my initial post, but I was under the impression that this is common sense.
You are in error, /etc/exports is not a symbolic link to /etc/zfs/exports, both are separate files. If you have on your system a linked /etc/exports, could it be you set the link yourself? I am definitely sure there is no base system scripted linking happening on its own.

A link wouldn't make sense anyway, for what purpose should the files be linked? mountd(8) reads both files separatly (see first result, rc.d/mountd in spoiler)

Here a grep(1) through the source code :
grep(1) through the source code
Bash:
/usr/src-main/libexec/rc/rc.d/mountd
    62-
    63-         if checkyesno zfs_enable; then
    64:                 rc_flags="${rc_flags} /etc/exports /etc/zfs/exports"
    65-         fi
    66-

/usr/src-main/libexec/rc/rc.d/zfs
    28-         zfs mount -va
    29-         zfs share -a
    30:         if [ ! -r /etc/zfs/exports ]; then
    31:                 touch /etc/zfs/exports
    32-         fi
    33- }

/usr/src-main/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c
    45-
    46- #define _PATH_MOUNTDPID "/var/run/mountd.pid"
    47: #define ZFS_EXPORTS_FILE        "/etc/zfs/exports"
    48- #define ZFS_EXPORTS_LOCK        ZFS_EXPORTS_FILE".lock"
    49-

/usr/src-main/sys/contrib/openzfs/tests/README.md
    40-     verify functionality.  Therefore it is strongly advised that a
    41-     dedicated test machine, which can be a VM, be used for testing.
    42:   * On FreeBSD, mountd(8) must use `/etc/zfs/exports`
    43-     as one of its export files – by default this can be done by setting
    44-     `zfs_enable=yes` in `/etc/rc.conf`.

/usr/src-main/sys/contrib/openzfs/tests/zfs-tests/include/libtest.shlib
  1252-         while read -r mtpt _; do
  1253-                 [ "$mtpt" = "$fs" ] && return
  1254:         done < /etc/zfs/exports
  1255-
  1256-         return 1
--
  1368-                 typeset mountd
  1369-                 read -r mountd < /var/run/mountd.pid
  1370:                 log_must eval "printf '%s\t\n' \"$fs\" >> /etc/zfs/exports"
  1371-                 log_must kill -s HUP "$mountd"
  1372-                 ;;
--
  1395-                 typeset mountd
  1396-                 read -r mountd < /var/run/mountd.pid
  1397:                 awk -v fs="${fs//\\/\\\\}" '$1 != fs' /etc/zfs/exports > /etc/zfs/exports.$$
  1398:                 log_must mv /etc/zfs/exports.$$ /etc/zfs/exports
  1399-                 log_must kill -s HUP "$mountd"
  1400-                 ;;

/usr/src-main/tools/build/mk/OptionalObsoleteFiles.inc
  9181- OLD_FILES+=etc/periodic/daily/404.status-zfs
  9182- OLD_FILES+=etc/periodic/daily/800.scrub-zfs
  9183: OLD_FILES+=etc/zfs/exports
  9184- OLD_DIRS+=etc/zfs
  9185- OLD_LIBS+=lib/libavl.so.2

Besides, I have on multiple machines NFSv4 sharenfs exported datasets, /etc/exports had to be set manually as a independent file.

I read the export(5) several times, there is no mentioning about this, the Internet and this Forum are also no help, that's why I posted my solution.
I didn't read it in a manual or other FreeBSD documentation, but in Bug 147881 [zfs] [patch] ZFS "sharenfs" doesn't allow different "exports" options for different hosts.

Take note of comment #32_
Code:
 Rick Macklem freebsd_committer freebsd_triage 2024-07-27 20:29:22 UTC   Comment 32

The patch is now in OpenZFS's main. I suspect it
will be pulled into FreeBSD someday soon.

See also Differential D45814 Allow ZFS sharenfs to generate multiple export(5) lines
 
You are in error, /etc/exports is not a symbolic link to /etc/zfs/exports, both are separate files. If you have on your system a linked /etc/exports, could it be you set the link yourself? I am definitely sure there is no base system scripted linking happening on its own.
That's great, I was quite surprised my self, when I found that link, didn't question it at the time and just moved on.

I didn't read it in a manual or other FreeBSD documentation, but in Bug 147881 [zfs] [patch] ZFS "sharenfs" doesn't allow different "exports" options for different hosts.

Take note of comment #32_
Code:
Rick Macklem freebsd_committer freebsd_triage 2024-07-27 20:29:22 UTC Comment 32

The patch is now in OpenZFS's main. I suspect it
will be pulled into FreeBSD someday soon.
See also Differential D45814 Allow ZFS sharenfs to generate multiple export(5) lines

Thx for the provided links, just skimmed those links, but it seems this has been cooking for 14 years now, however as soon as there is a RELEASE, I'll remove that symbolic link and split the configuration.
 
I don't know why, but CIDR notation like -network 192.168.1.0/24, [...] never worked for me.
This should work. NFS Shares with ZFS by Dru Lavigne - February 23, 2022:
If you already have a working NFS configuration on a FreeBSD system with OpenZFS filesystems, it is easy to recreate your configuration using zfs set. For example, this line from /etc/exports:
/usr/ports -maproot=root 192.168.15.0/24
is equivalent to this command:
zfs set sharenfs=’on,-maproot=root,192.168.15.0/24’ mypool/usr/ports

This means you can simply run the equivalent zfs set sharenfs=’on,REPLACE_WITH_YOUR_OPTIONS’ poolname/filesystem command for each line in your /etc/exports file.
It could be that the—not to be edited—"FreeBSD intermediate file" (as opposed to Solaris that has NFS fully integrated in its kernel) /etc/zfs/exports does not allow this.

However, NFS Shares with ZFS (my emphasis):
You can use any option listed in exports(5). Basically, if you’re using it now in /etc/exports, you can specify it withzfs set.
The usage of Basically has some reach as it seems that it boils down to weighing two methods against each other:
  1. using the "ZFS-way" of using sharenfs as in zfsprops.7 - sharenfs
  2. using exports(5): /etc/exports
  3. mixed usage of /etc/exports and ZFS' sharenfs*
    See Michael Lucas' quote below.

I don't know why, [...] and multiple -network definitions never worked for me.
Indeed, looks like you cannot (though, as T-Deamon remarked, changes seem to be coming: message #9). Michael Lucas' FreeBSD Mastery: Specialty Filesystems:
Managing NFS with ZFS Properties
[...]
The problem with using ZFS to manage your NFS exports is that you must use the same options for all permitted hosts. That is, if most of your clients use the –maproot=nfsroot option, but you have one problem host that legitimately needs –maproot=root, zfs(8) can’t help you. You must configure such exports via /etc/exports. Similarly, you can define only one permitted network with ZFS properties.

I encourage you in the strongest possible terms to choose a single method of managing NFS and stick with it. Simpler configurations can use ZFS properties, but more complicated NFS setups probably want /etc/exports. Using both /etc/exports and sharenfs
causes confusion. Really, don’t do it(1).

(1) Around now I usually come out in a cheesy long black hooded robe, point a single chubby finger at you, and say in the
deepest voice I can manage: “Doom. Doooom…”

___
* As to the mixed usage, that may have been a source of additional confusion, IMO the stretched if ... otherwise man page language construct does not help in providing clarity. Additionally, because OpenZFS serves multiple OS-es, some references are to non-FreeBSD man pages, like "exportfs(8)" (no exportfs(8) in FreeBSD). ZFS(8) - FreeBSD 10.0-RELEASE:
Rich (BB code):
sharenfs=on | off | opts
	   Controls whether the	file system is shared via NFS,	and  what  op-
	   tions  are  used.  A	file system with a sharenfs property of	off is
	   managed the traditional way via exports(5).	 Otherwise,  the  file
	   system  is  automatically  shared and unshared with the "zfs	share"
	   and "zfs unshare" commands. If the property is set to on no NFS ex-
	   port	options	are used. Otherwise, NFS export	options	are equivalent
	   to the contents of this property. The export	options	may be	comma-
	   separated. See exports(5) for a list	of valid options.

	   When	 the sharenfs property is changed for a	dataset, the mountd(8)
	   daemon is reloaded
However, zfsprops(7) - FreeBSD 14.1-RELEASE:
Rich (BB code):
sharenfs=on|off|opts
	 Controls whether the file system is shared via	NFS, and what  options
	 are  to  be  used.   A	file system with a sharenfs property of	off is
	 managed with the exportfs(8) command and entries in the  /etc/exports
	 file.	 Otherwise,  the  file	system is automatically	shared and un-
	 shared	with the zfs share and zfs unshare commands.  If the  property
	 is set	to on, the dataset is shared using the default options:
	       sec=sys,rw,crossmnt,no_subtree_check

	 Please	 note that the options are comma-separated, unlike those found
	 in exports(5).	 This is done to negate	the need for quoting, as  well
	 as to make parsing with scripts easier.

	 See  exports(5)  for  the meaning of the default options.  Otherwise,
	 the exportfs(8) command is invoked with  options  equivalent  to  the
	 contents of this property.
 
Back
Top