4

I have an Ubuntu 11.10 system with an iptables firewall. After pinning the ports for mountd, lockd and statd, then opening them up in iptables, I am able to expose NFS shares through the firewall with no issues.

What I am having a problem with is mounting a share from another NFS server that I have no control over. If I disable the firewall, I can mount the share. I can also mount other NFS shares without disabling the firewall.

So that leads me to two questions:

  • Why would a firewall prevent an NFS client from mounting some servers and not others?
  • Can a client specify ports to use for an NFS mount?

Full config and error info:

The server is NFSv3 according to nfsstat. When I do the mount:

# mount -t nfs -v 192.168.80.48:/location /mnt/tmp
mount.nfs: timeout set for Fri Mar 23 09:13:00 2012
mount.nfs: trying text-based options 'vers=4,addr=192.168.80.48,clientaddr=192.168.40.173'
mount.nfs: mount(2): No such file or directory
mount.nfs: trying text-based options 'addr=192.168.80.48'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: trying 192.168.80.48 prog 100003 vers 3 prot TCP port 2049
mount.nfs: prog 100005, trying vers=3, prot=17
mount.nfs: trying 192.168.80.48 prog 100005 vers 3 prot UDP port 678
mount.nfs: portmap query retrying: RPC: Timed out
mount.nfs: prog 100005, trying vers=3, prot=6
mount.nfs: trying 192.168.80.48 prog 100005 vers 3 prot TCP port 681
mount.nfs: portmap query failed: RPC: Remote system error - Connection timed out

I see the packets being dropped:

Rejected packets: SRC=192.168.80.48 DST=192.168.40.173 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=681 DPT=40325 WINDOW=5792 RES=0x00 ACK SYN URGP=0
Rejected packets: SRC=192.168.80.48 DST=192.168.40.173 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=681 DPT=47419 WINDOW=5792 RES=0x00 ACK SYN URGP=0
Rejected packets: SRC=192.168.80.48 DST=192.168.40.173 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=681 DPT=41238 WINDOW=5792 RES=0x00 ACK SYN URGP=0

showmount fails in the same way. From the verbose mount prints, it looks like portmap is the issue, but I do have that opened.

# rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  32765  status
    100024    1   tcp  32765  status
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    2   tcp   2049
    100227    3   tcp   2049
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    2   udp   2049
    100227    3   udp   2049
    100021    1   udp   4002  nlockmgr
    100021    3   udp   4002  nlockmgr
    100021    4   udp   4002  nlockmgr
    100021    1   tcp   4001  nlockmgr
    100021    3   tcp   4001  nlockmgr
    100021    4   tcp   4001  nlockmgr
    100005    1   udp  32767  mountd
    100005    1   tcp  32767  mountd
    100005    2   udp  32767  mountd
    100005    2   tcp  32767  mountd
    100005    3   udp  32767  mountd
    100005    3   tcp  32767  mountd

# cat /etc/services
sunrpc          111/tcp         portmapper      # RPC 4.0 portmapper
sunrpc          111/udp         portmapper
nfs             2049/tcp                        # Network File System
nfs             2049/udp                        # Network File System

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:sunrpc
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ntp
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:netbios-ns
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:netbios-dgm
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:netbios-ssn
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:microsoft-ds
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:nfs
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:sunrpc
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:3260
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:32765
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:32766
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:32767
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:4001
ACCEPT     udp  --  anywhere             anywhere            udp dpt:domain
ACCEPT     udp  --  anywhere             anywhere            udp dpt:sunrpc
ACCEPT     udp  --  anywhere             anywhere            udp dpt:ntp
ACCEPT     udp  --  anywhere             anywhere            udp dpt:netbios-ns
ACCEPT     udp  --  anywhere             anywhere            udp dpt:netbios-dgm
ACCEPT     udp  --  anywhere             anywhere            udp dpt:netbios-ssn
ACCEPT     udp  --  anywhere             anywhere            udp dpt:https
ACCEPT     udp  --  anywhere             anywhere            udp dpt:microsoft-ds
ACCEPT     udp  --  anywhere             anywhere            udp dpt:nfs
ACCEPT     udp  --  anywhere             anywhere            udp dpt:4002
ACCEPT     udp  --  anywhere             anywhere            udp dpt:32765
ACCEPT     udp  --  anywhere             anywhere            udp dpt:32766
ACCEPT     udp  --  anywhere             anywhere            udp dpt:32767
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:domain
ACCEPT     udp  --  anywhere             anywhere            udp spt:domain
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:sunrpc
ACCEPT     udp  --  anywhere             anywhere            udp spt:sunrpc
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:netbios-ssn
ACCEPT     udp  --  anywhere             anywhere            udp spt:netbios-ssn
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:https
ACCEPT     udp  --  anywhere             anywhere            udp spt:https
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:microsoft-ds
ACCEPT     udp  --  anywhere             anywhere            udp spt:microsoft-ds
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:submission
ACCEPT     udp  --  anywhere             anywhere            udp spt:submission
ACCEPT     tcp  --  anywhere             anywhere            tcp spt:nfs
ACCEPT     udp  --  anywhere             anywhere            udp spt:nfs
3
  • Thank you. I'm aware of that, but you'll notice the DPT changes every time. I can't hit a moving port, which is why I asked about specifying ports from the client side.
    – JoeFish
    Mar 23, 2012 at 13:47
  • You can configure static ports for rpc.mountd and rpc.statd. Does ubuntu come with /etc/defaults/nfs-kernel-server and nfs-common?
    – 3molo
    Mar 23, 2012 at 13:58
  • I have already done that, which is what I meant by "pinning the ports for mountd, lockd and statd" in my question. See the output from rpcinfo for the port numbers.
    – JoeFish
    Mar 23, 2012 at 14:04

1 Answer 1

5

There are settings in sysctl that defines NFS port ranges available for connections.

sunrpc.max_resvport = 1023

sunrpc.min_resvport = 650

These settings define the highest and lowest ports to use for making RPC connections (NFS)

You can open these ports or define a different range depending on your system. You will get denies if it tries to use a port that is blocked either by a firewall or another service using that port.

Edit:

You can also increase / decrease this range. I have a server that had 460 NFS mounts defined in fstab and it would fail after 372 or so. And when I would manually mount one of the failed ones it would mount it but unmount one of the working mounts. I increased this range by 150 and they all mounted. This is not the best way to do it. automounter comes to mind but, it works.

To make the modification you will edit your /etc/sysctl.conf add a line like:

sunrpc.min_resvport = 900

To make the change permanent if you need to change them. Remember if you go above 1024 that those are "unprivileged" ports and normal system users will have access to them vs. - 1024.

Edit 2:

In your NFS mount command can you add the following.

proto=tcp - forces the mount to use TCP/IP

public - bypasses portmapper completely and contacts NFS server on port 2049 unless otherwise specified

So, mount nfs.test.com:/export /test

becomes

mount -o proto=tcp ,public nfs.test.com:/export /test

EDIT 3

OK - here we go!!! root@pressyrluck # ./nowhammies > /dev/please

This information was lifted copied swiped borrowed from Sourceforge NFS

Some of the daemons involved in sharing data via nfs are already bound to a port. portmap is always on port 111 tcp and udp. nfsd is always on port 2049 TCP and UDP (however, as of kernel 2.4.17, NFS over TCP is considered experimental and is not for use on production machines).

The other daemons, statd, mountd, lockd, and rquotad, will normally move around to the first available port they are informed of by the portmapper.

To force statd to bind to a particular port, use the -p portnum option. To force statd to respond on a particular port, additionally use the -o portnum option when starting it.

To force mountd to bind to a particular port use the -p portnum option.

For example, to have statd broadcast of port 32765 and listen on port 32766, and mountd listen on port 32767, you would type:

# statd -p 32765 -o 32766
# mountd -p 3276

lockd is started by the kernel when it is needed. Therefore you need to pass module options (if you have it built as a module) or kernel options to force lockd to listen and respond only on certain ports.

If you are using loadable modules and you would like to specify these options in your /etc/modules.conf file add a line like this to the file:

options lockd nlm_udpport=32768 nlm_tcpport=32768

For the sake of this discussion lets describe a network and setup a firewall to protect our nfs server. Our nfs server is 192.168.0.42 our client is 192.168.0.45 only. As in the example above, statd has been started so that it only binds to port 32765 for incoming requests and it must answer on port 32766. mountd is forced to bind to port 32767. lockd's module parameters have been set to bind to 32768. nfsd is, of course, on port 2049 and the portmapper is on port 111.

We are not using quotas.

iptables -A INPUT -f -j ACCEPT -s 192.168.0.45
iptables -A INPUT -s 192.168.0.45 -d 0/0 32765:32768 -p 6 -j ACCEPT
iptables -A INPUT -s 192.168.0.45 -d 0/0 32765:32768 -p 17 -j ACCEPT
iptables -A INPUT -s 192.168.0.45 -d 0/0 2049 -p 17 -j ACCEPT
iptables -A INPUT -s 192.168.0.45 -d 0/0 2049 -p 6 -j ACCEPT
iptables -A INPUT -s 192.168.0.45 -d 0/0 111 -p 6 -j ACCEPT
iptables -A INPUT -s 192.168.0.45 -d 0/0 111 -p 17 -j ACCEPT
iptables -A INPUT -s 0/0 -d 0/0 -p 6 -j DENY --syn --log-level 5
iptables -A INPUT -s 0/0 -d 0/0 -p 17 -j DENY --log-level 5

The first line says to accept all packet fragments (except the first packet fragment which will be treated as a normal packet). In theory no packet will pass through until it is reassembled, and it won't be reassembled unless the first packet fragment is passed. Of course there are attacks that can be generated by overloading a machine with packet fragments. But NFS won't work correctly unless you let fragments through. See Section 7, “Troubleshooting” for details.

The other lines allow specific connections from any port on our client host to the specific ports we have made available on our server. This means that if, say, 192.158.0.46 attempts to contact the NFS server it will not be able to mount or see what mounts are available.

With the new port pinning capabilities it is obviously much easier to control what hosts are allowed to mount your NFS shares. It is worth mentioning that NFS is not an encrypted protocol and anyone on the same physical network could sniff the traffic and reassemble the information being passed back and forth.

12
  • Thanks for the suggestion. I added these to /etc/sysctl.conf, opened the port ranges and rebooted, and the mount still fails. The packets from the NFS server are still coming in on random ports - 42828, 56194, 51729, 46218, 60394. Is it possible the server just isn't honoring the client's settings?
    – JoeFish
    Mar 23, 2012 at 14:40
  • So, you are getting hung up on the UDP request... The NFS client contacts the servers portmapper or rpcbind daemon to find the mount daemon. Mar 23, 2012 at 14:48
  • @JoeFish - added a new edit to my answer. Mar 23, 2012 at 14:53
  • No luck. public is not a valid mount option. proto=tcp does work, but that just forces tcp and doesn't un-randomize the ports the server is trying to hit. I appreciate the suggestions, though.
    – JoeFish
    Mar 23, 2012 at 15:14
  • @JoeFish: quick question have you allowed port:2049 through the firewall? Mar 23, 2012 at 19:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .