The NFSv4 server seems to be ignoring the vfs.nfsd.nfs_privport sysctl setting. When I set either vfs.nfsd.nfs_privport=1 sysctl and/or nfs_reserved_port_only="YES" in rc.conf, I am not denied when using an unprivileged port from a NAT'ed VM, but AM successfully denied when using the NFSv3 export. The pertinent section of /etc/rc.conf on the server looks like this: ----------- zfs_enable="YES" rpcbind_enable="YES" rpc_lockd_enable="YES" rpc_lockd_flags="-d 1" rpc_statd_enable="YES" rpc_statd_flags="-d" mountd_enable="YES" mountd_flags="-S -r -p 619" nfs_client_enable="YES" nfs_access_cache="60" nfs_server_enable="YES" nfs_server_flags="-u -t -n 256" nfs_server_managegids="YES" nfs_reserved_port_only="YES" nfs_bufpackets="5" nfsv4_server_enable="YES" nfsuserd_enable="YES" ------------ /etc/exports: ------------ V4: /data moo.cow.com /data/test -alldirs -maproot=nobody moo.cow.com ------------ Output in /var/log/messages from unsuccessful nfs3 mount: ------------ Dec 17 18:40:55 meow mountd[56740]: mount request from 10.10.10.18 from unprivileged port ------------ I happened to stumble on this inconsistency while evaluating the use of NAT'ed virtual machines on our Linux clients. Is this a bug, or a mis-configuration on my part? I'm leaning toward bug, as it DOES work with the NFS3 mounts.
It's explicitly mentioned in sysctl description (and followed in the code): $ sysctl -d vfs.nfsd.nfs_privport vfs.nfsd.nfs_privport: Only allow clients using a privileged port for NFSv2 and 3 For why, I'm not sure (e.g. Solaris/illumos NFS server has the same setting for all protocol versions) thus adding Rick to CC.
(In reply to Yuri Pankov from comment #1) Thanks Yuri! I missed that. Is it true then, that the NFSv4 server on FreeBSD does NOT have the ability to only permit privileged ports?
When NFSv4 was being developed, I recall the specification authors clearly stating the "a reserved port# does not provide security and is not to be required for NFSv4 client mounts". I recall this being stated in the RFC, but I wasn't able to find it on a quick search (they are 275->500+ page documents). As such, the code does not require a reserved port# for NFSv4 mounts. (And I agree with the authors that it does not enhance security, since all it tells the server is that the "mounter" is root on the client. I suppose you can argue that there are machines that are "root secure" but with untrusted users that might try and run malicious fake NFSv4 clients on these machines, but...) If you want any sort of security for NFS mounts, you need to use sec=krb5[ip]. There is work now in progress for NFS over TLS, but that isn't implemented yet. (Just an internet draft at this point.) As such, I consider it a feature and not a bug, rick
Hi Rick! Thanks for the info. I agree with you and the fathers/mothers of NFSv4! The reserved port requirement does NOT make it more secure. However... The inconsistency between the behavior of Linux (and apparently Solaris/Illumos) NFSv4 servers and FreeBSD NFSv4 servers is not expected. Would it be possible to implement a "--security-blanket-for-chaz" argument that would utilize the reserved port sysctl, similarly to the NFSv3 service on FreeBSD? I do have a use case for this though it could also be accomplished using the Kerberos configuration or switching back to NFSv3. The qemu vms that our users would like to use are behind an IPTables NAT or user mode networking. The source port is re-written so that it is greater than 1023, so mounting an export with that sysctl set is not possible with NFSv3 - but is still possible with the NFSv4 export. Obviously this is only a single security concern in a sea of them, and I definitely do not consider this to be an all-encompassing measure. In summary - would it be possible to make the FreeBSD NFSv4 server behave like the Linux and Solaris/Illumos server? (disclaimer: I haven't tested Solaris/Illumos's behavior)
Yes. If Linux has chosen to go this way, then I think changing it is appropriate. I'll ask the "collective" on the freebsd-current@ mailing list. (Whether we like it or not, Linux is now the defacto standard NFS implementation.) Btw, if you want to test it, the patch is trivial. Just change the line in sys/fs/nfsserver/nfs_nfsdkrpc.c (at line# 169 in head) from if (nfs_privport && (nd.nd_flag & ND_NFSV4) == 0) { to if (nfs_privport != 0) { I'll need to test to make sure the FreeBSD NFSv4 client can still do mounts. (I think it must or someone would have noticed a problem mounting a Linux server.) rick
Created attachment 200253 [details] modify the NFSv4 server so that it uses vfs.nfsd.nfs_privport This one line patch makes the NFSv4 server check for a reserved port# when vfs.nfsd.nfs_privport is set. This makes the server compatible with the Linux one. Since the FreeBSD NFSv4 client uses a reserved port# by default, this should not affect most users of the server. (Presumably the Linux client uses a reserved port# as well. I haven't checked, but the reporter of this bug notes that this is the Linux behaviour.)
Thank you Rick and Yuri! I've tested that patch against FreeBSD 10.3-RELEASE-p29 (That's what my test machine happens to be running) and it worked as I expected it to. Additionally, I want to say this: At $WORKPLACE we use Ubuntu. On occasion my team has submitted bug reports and/or patches along with them to package maintainers, etc. Typically we're just ignored or the problem isn't interesting enough...or something. This is -the best- response I've had out of a problem report and I couldn't be happier with the results. I'll be bragging on the FreeBSD group about this (at appropriate times). You all volunteer your time and I'm thankful for it! Again, thank you.
A commit references this bug: Author: rmacklem Date: Thu Dec 20 22:21:42 UTC 2018 New revision: 342286 URL: https://svnweb.freebsd.org/changeset/base/342286 Log: Fix the NFSv4 server to obey vfs.nfsd.nfs_privport. When the NFSv4 server was coded, I believed that the specification authors did not want NFSv4 servers to require a client to use a reserved port#. However, recently it has been noted that the Linux NFSv4 server does support a check for a reserved port#. Since both the FreeBSD and Linux NFSv4 clients use a reserved port# by default, enabling vfs.nfsd.nfs_privport to require a reserved port# for NFSv4 the same as it does for NFSv2, 3 seems reasonable. The only case where this could cause a POLA violation is a FreeBSD NFSv4 server with vfs.nfsd.nfs_privport set, but with NFSv4 clients doing mounts without using a reserved port# (< 1024). Tested by: chaz.newton58@gmail.com PR: 234106 MFC after: 1 week Changes: head/sys/fs/nfsserver/nfs_nfsdkrpc.c
Patch has been tested by Chaz and committed to head. It will be MFC'd in a week.
Patch has been MFC'd.