Re: NFSv4 on MacOS Monterey

From: Rick Macklem <rmacklem_at_uoguelph.ca>
Date: Thu, 02 Jun 2022 19:42:56 UTC
Adonis Peralta <donileo@gmail.com> wrote:
> I have some NFSv4 (sec=sys) shares on FreeBSD 13.1 which I'm trying to connect correctly with MacOS 12.4 > Monterey.
> I got the basics down but don't think I have permissions and extended attributes working correctly.
Well, here are a few comments. Note that I haven't used Mac OSX in over a decade, so I don't remember
much of anything about it.

> My configuration is as follows:
> 
> SERVER CONFIGURATION
>
> OS: FreeBSD 13.1
>
> ===
> /etc/rc.conf
> # NFS Configuration
> nfs_server_enable="YES"
> nfs_server_flags="-u -t -n 4"
4 is very small, although that will only be a performance issue.

> mountd_enable="YES"
Since you have specified nfsv4_server_only, mountd will be configured correctly (using the -R),
so this line is not needed (although I don't thing it will cause trouble).

> ### mountd_flags="-R"
> ### rpcbind_enable="YES"
> ### rpc_lockd_enable="YES"
>### rpc_statd_enable="YES"
> # Enable NFSv4
> nfsv4_server_enable="YES"
> nfsv4_server_only="YES"
> nfsuserd_enable="YES"
> nfsuserd_flags="-domain rambo.lan"
> ===
> 
> ===
> /etc/exports
> # Exports Configuration
> /drivepool/backups -alldirs -mapall=adonis:wheel
> /drivepool/media -alldirs -mapall=adonis:wheel
> /drivepool/home/adonis -alldirs -mapall=adonis:wheel
> /drivepool/public -mapall=adonis:wheel
These lines mean that the uid/gids in the RPC headers will be ignored and all
RPCs will be done as whatever uid is assigned to "adonis" in the server's password database.

> V4: /drivepool adonis-mbp adonis-pc
> ===
> 
> ===
> /etc/sysctl.conf
> # Asks nfsd to convert remote uids/gid encoded as numeric strings to be mapped to an actual uid/gid
> vfs.nfsd.enable_stringtouid=1
You probably do not want this. Since you are running nfsuserd, it will be mapping between
the client uid/gid <-> the names for the Getattr/Setattr.
If the Mac OSX client does not have "adonis" in its password database, that will be a problem.
(These mappings have nothing to do with the uid/gids in the RPC header. The latter is used
 to set the credentials for the RPC against the server. In your case, completely ignored.
 The name<->uid/gid mappings are used for Setattr/Getattr. Things like "chmod", "stat"...)

> # Applies to both nfs server and client. Asks client/server to send numeric strings for uid/gid.
> ### vfs.nfs.enable_uidtostring=0
For a server, you either set both of the above to 1 and do not run the nfsuserd or set both of the
above to 0 and set them both to 0. I do not know if Mac OSX knows how to do the "uid/gid" in
the string for Getattr/Setattr, That is what you are doing when the above are set to 1 and is the
default for Linux, plus works for FreeBSD so long as you are not using Kerberized mounts.
(To know, you would need to look a Setattr RPC done by the Mac OSX client in wireshark for
 either "chgrp" or "chown" and see how the Owner/Owner_Group string is formatted. A number
 or a "name@domain".)

> vfs.nfsd.debuglevel=3
> ===
>
> The directories above are hosted on ZFS and nfs4 acls support is turned on.
>
> CLIENT CONFIGURATION
>
> OS: MacOS 12.4 Monterey
>
> ===
> nfs.client.mount.options=vers=4.0,intr,namedattr
Named attributes are not supported by the FreeBSD server and won't work.

> nfs.client.default_nfs4domain = rambo.lan
> ===
>
> Note: above I'm using namedattr to try to get the client to connect with named attributes support.
As above, named attributes won't work.

> RESULTS
>
> What I see when I connect via finder is the following:
> 
> 1. I am able to read/write to the shares since /etc/exports contains the -mapall line, yet inspecting a packet > trace shows me:
> 
> ===
> packet #1
> ---
> client ip -> server ip Operations (count: 3): PUTFH, ACCESS, GETATTR
> Opcode: PUTFH (22)
> Opcode: ACCESS (3), [Check: RD LU MD XT DL XE]
> Opcode: GETATTR (9)
>
> packet #2
> ---
> server ip -> client ip Operations (count: 3)
> Opcode: PUTFH (22)
> Opcode: ACCESS (3), [NOT Supported: XE], [Access Denied: MD XT DL], [Allowed: RD LU]
>     Status: NFS4_OK (0)
>     Supported types (of requested): 0x1f
>    Access rights (of requested): 0x03
>        .... ...1 = 0x001 READ: allowed
>        .... ..1. = 0x002 LOOKUP: allowed
>        .... .0.. = 0x004 MODIFY: *Access Denied*
>        .... 0... = 0x008 EXTEND: *Access Denied*
>        ...0 .... = 0x010 DELETE: *Access Denied*
This is saying that the uid for "adonis" on the server does not have write access to the file.

> Opcode: GETATTR (9)
> ===
>
> Why is MD, XT, DL coming up as Access Denied if I can read/write to the share?
Hmm, not sure. If you were to show all the reply fields for the Getattr, then I could probably guess.
It might be Owner (is it "adonis@rambo.lan"). it could be ACLs. To check those, you should be able to
do whatever the Mac OSX equivalent to getfacl is.

> I have a feeling this is because UID/GID mapping is not happening correctly. I can see in the packet trace >that FreeBSD's `nfsd` is sending some credentials as `adonis@rambo.lan`, but MacOS's nfs client is sending uid 501 and gid 20 for my user in the RPC credentials. I don't see how `nfsd` will be able to map uid 501, gid 20 to the server's uid and gid and instead I was expecting `adonis@rambo.lan` to be sent for credentials from the client side.
As noted above, with "-mapall" the uid/gids in the RPC header are completely ignored.

> The link below tells me that this is an inherent issue with NFSv4?
> https://dfusion.com.au/wiki/tiki-index.php?page=Why+NFSv4+UID+mapping+breaks+with+AUTH_UNIX
>
> 2. Extended attributes don't work at all. Here is the result:
> ===
> $ cd /Volumes/media
> $ touch test.txt
> $ xattr -w com.example.color blue test.txt
>
> # Result: xattr: [Errno 1] Operation not permitted: 'test.txt' #
> ===
Yep, as noted above, they aren't supported and will not work. FreeBSD uses the Linux style extended
attribute model, not the resource fork/subfile one that Mac OSX and Solaris use.

rick

--
Adonis