Why is NFS client using low-numbered ports

awscoreosnfs

I am running a CoreOS EC2 instance. I run a process on this instance that listens on local port 950. Usually, everything works fine, but after a recent reboot of the CoreOS server the process could not listen on port 950 because it was already taken by another process.

This other process appears to be an NFSv4 client that is used to mount an AWS EFS volume. Here is what netstat tells me:

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 10.30.102.250:950       10.30.102.170:2049      ESTABLISHED

Here is the relevant part of /etc/mtab:

fs-faa33256.efs.us-west-2.amazonaws.com:/ /efs nfs4 rw,relatime,vers=4.1,\
rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,\
clientaddr=10.30.102.250,local_lock=none,addr=10.30.102.170 0 0

A couple of questions: 1. Why is the NFS client on the CoreOS server using a low-numbered port to communicate with the remote NFSv4 server? 2. Can I tell the NFS client to avoid using port 950 (or use only non-privileged ports)?

Best Answer

(The following answer is derived in large part from Jeff Schaller's comments to my original post.)

In order to prevent non-root users from mounting an NFS volume, an NFS server can require that an NFS client use a privileged port (1-1023). However, allowing only root users to mount an NFS volume offers little security these days as anyone who can put a machine on the network can be root on that machine.

Because of this old security practice, some NFS clients will default to using privileged ports when connecting to an NFS server.

This can cause port conflicts if your client needs to run a service on a privileged port. One way to get around this is to set the minimum and maximum privileged ports that the NFS client will use so that the NFS client will avoid ports used by other services. This port range can be set as kernel parameters; in CoreOS these parameters can be stored in the the files /sys/module/sunrpc/parameters/min_resvport and /sys/module/sunrpc/parameters/max_resvport.

You can avoid the whole privileged port issue altogether by adding an option when mounting the NFS volume telling the system to use non-provileged ports. In the case of Linux this is the noresvport option (see also the Linux nfs(5) man page).

This is the mount command we ended up using on our CoreOS server:

fs-faa33256.efs.us-west-2.amazonaws.com:/ /efs nfs4 rw,relatime,vers=4.1,\
rsize=1048576,wsize=1048576,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,\
clientaddr=10.30.102.250,local_lock=none,addr=10.30.102.170 0 0
Related Question