nfs and ipf with IPFILTER_DEFAULT_BLOCK
I had a power failure this afternoon. My UPS worked, but the failure
was just too long for my poor old 800 KVA UPS. All the boxes went down. A pity
as one box was just a few hours from 280 days of uptime. My previous record was 179
days, and that failed because of power as well.
That wasn’t really a problem. The
boxes came back up but not everything was fine. Specifically, my NFS
volumes didn’t mount properly. Which meant some of my web sites weren’t up and
running. The problem was a combination of ipf rules which prevent access and my ipf
configuration being deny-by-default. The offshoot was that when the system tried to
start up as an nfs server, not everything was happy. I spent the better part of four
hours trying to figure out what was going on. I got some help from Odinn in this.
He went through everything with me and it was finally sussed out.
We discovered that rpc.statd was not running. This program is necessary
for NFS. See the man page for more detail. So we tried to start it:
[root@ducky:~] # /usr/sbin/rpc.statd Cannot register service: RPC: Unable to send; errno = No route to host rpc.statd: unable to register (SM_PROG, SM_VERS, udp)
We first suspected my routing was screwed up. But it wasn’t. It was my
rules. They weren’t running. That meant I was deny by default. Hence,
"No route to host". Once I invoked the rules, rpc.statd was up and
running. This was our first hint that there was a conflict somewhere..
Deny by default
I’m using ipfilter (the binary is ipf).
It’s my preferred packet filter. It’s robust. It’s feature rich.
And it’s rock solid. The author, Darren Reed, supports it well. And the
ipfilter community is a good team to work with.
There is a kernel feature,
IPFILTER_DEFAULT_BLOCK, which makes ipf deny everything by default. From a security
point of view, this is a better default than to accept everything. Unfortunately, it
can cause a few problems with the FreeBSD startup. I encountered this problem with
NFS. Luckily, there is a workaround. I have a nify little script.
NFS startup
My existing setup breaks the FreeBSD NFS startup. So I took what
FreeBSD does and took it for my own. The normal /etc/rc.conf options I
used in for enabling NFS are these:
nfs_server_enable="YES" # This host is an NFS server (or NO) nfs_server_flags="-u -t -n 4" # Flags to nfsd (if enabled). nfs_client_enable="YES" # This host is an NFS client (or NO). nfs_client_flags="-n 4" # Flags to nfsiod (if enabled).
These options are used by the script /etc/rc.network. If the above
options exist in , In that file, you’ll find a section which starts like this:
network_pass3() { echo -n 'Starting final network daemons:' case ${nfs_server_enable} in [Yy][Ee][Ss]) if [ -r /etc/exports ]; then echo -n ' mountd' case ${weak_mountd_authentication} in [Yy][Ee][Ss]) mountd_flags="-n" ;; esac
This is the section which I took for my own. Basically, I cobbled togther the
bits and pieces I needed. My script is:
#!/bin/sh # # start the nfs server # echo -n ' mountd' ; mountd -r echo -n ' nfsd' ; nfsd -u -t -n 4 echo -n ' sysctl' ; sysctl -w vfs.nfs.bufpackets=DEFAULT \ > /dev/null echo -n ' rpc.statd' ; rpc.statd # # then mount our NFS client volumes # mount -v fred:/nzmirror/ports/distfiles /usr/ports/distfiles
The steps I go through in the above script more or less duplicate what the /etc/rc.network
when it sees the NFS options I described at the start of this section.
This script is placed in /usr/local/etc/rc.d/nfs.sh. Make sure it is
chmod 750.
Using this script
In order to use this script, make sure that you do not include the nfs
server options in /etc/rc.conf. Remove them. You can leave the client options
in, just don’t mount any of them in /etc/fstab. I commented mine out and
mounted them in my script. I’m sure there are better ways to do this. Please
include your comments and feedback here.