Most sensible people are very wary of NFS and its potential for security holes. If you can at all help it, it's a good idea not to run NFS and portmap on a network interface with direct internet connectivity. However, this isn't always convenient.
As I needed to have NFS sharing on a host exposed to the internet, I set about finding the various places I needed to firewall. The tools I typically use to verify I've done the right things are
netstat -nap on the machine concerned, to check for listening processes, and
nmap from remote hosts to sniff for open ports.
Portmap and its associated programs mostly use 'tcpwrappers' for controlling access. The first step you ought to take in securing portmap is to ensure that your hosts.allow and hosts.deny files are set up to control access properly.
In /etc/hosts.deny, deny access to allcomers:
mountd: ALL statd: ALL portmap: ALL rquotad: ALL
Then in /etc/hosts.allow, let the good guys through (adjust for your network):
mountd: 192.168.0. statd: 192.168.0. portmap: 192.168.0. rquotad: 192.168.0.
On top of this, however, you should firewall off the ports that these programs use. As I found out, this is not as easy as it sounds. Portmap assigns random ports for some of the services it starts.
You can run
rpcinfo -p to see the ports in use. An example run on one of my machines looks like this:
program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100021 1 udp 32770 nlockmgr 100021 3 udp 32770 nlockmgr 100021 4 udp 32770 nlockmgr 100021 1 tcp 32788 nlockmgr 100021 3 tcp 32788 nlockmgr 100021 4 tcp 32788 nlockmgr 100005 1 udp 1005 mountd 100005 1 tcp 1008 mountd 100005 2 udp 1005 mountd 100005 2 tcp 1008 mountd 100005 3 udp 1005 mountd 100005 3 tcp 1008 mountd 100024 1 udp 863 status 100024 1 tcp 866 status
Of these, nfs and portmapper always use the same ports, 2049 and 111, so ensure you block off these.
What about the rest? Happily, there's a way to configure them to use constant ports so we can reliably firewall them. Life would be too easy if all this configuration was in the one place, so here's how to find the different places you need to change.
nlockmgr: you're probably using the kernel NFS server, which means the port needs passing at module load time for the lockd module. Add this line into a new file, /etc/modutils/local-lockd
options lockd nlm_udpport=32768 nlm_tcpport=32768
update-modules to recreate your /etc/modules.conf. The next time you boot these ports will be used for nlockmgr. If you've got the lockd statically compiled into your kernel, you'll need to pass these options as
lockd.nlm_tcpport to the kernel on boot.
status: this is the port used by statd. There's also an outgoing port, on which statd sends outgoing status requests. You can configure them by altering
STATDOPTS in /etc/default/nfs-common, e.g.
STATDOPTS="--port 699 --outgoing-port 700"
mountd: you can control the port used for mountd by editing /etc/default/nfs-kernel-server and altering
Finally, if you're running quotas, be sure to do something similar with
RPCRQUOTADOPTS in /etc/default/quota.
Finally, I ought to note that I've written this up in case it helps anybody else. As with everything I write here, I make no warranty about its accuracy. Security is hard and obscure (but that's no reason not make our best efforts!)