Archive for the ‘Uncategorized’ Category

Resolving sendmail’s “My unqualified host name unknown; sleeping for retry” in FreeBSD

Friday, August 7th, 2015

Every so often I’ll see the following show up on my FreeBSD 10.0 server’s logs:

Aug 7 03:35:58 mediaserver3 sendmail[5825]: My unqualified host name (mediaserver3) unknown; sleeping for retry
Aug 7 03:35:58 mediaserver3 sendmail[5848]: My unqualified host name (mediaserver3) unknown; sleeping for retry
Aug 7 03:35:58 mediaserver3 sendmail[5849]: My unqualified host name (mediaserver3) unknown; sleeping for retry
Aug 7 03:35:59 mediaserver3 sendmail[5862]: My unqualified host name (mediaserver3) unknown; sleeping for retry

Turns out my hostname (mediaserver3) was not listed in /etc/hosts/:

::1                     localhost               localhost

Adding it to the front seemed to do the trick:

::1                     mediaserver3 localhost               mediaserver3 localhost

Recovering from a kernel panic during zpool -f import

Monday, March 16th, 2015

Several weeks ago, the UPS protecting one of my media servers suffered a catastrophic failure after lightning directly struck the powerlines to my apartment. Like any good UPS, the unit sacrificed itself to protect my equipment, but it wasn’t enough: both my power supply and motherboard needed to be replaced. Fortunately, the drives appear to have survived, as they’re still showing up and responding to S.M.A.R.T. queries.

After replacing the power supply and motherboard, I installed the latest version of FreeBSD (currently, 10.0) on the OS hard drive and tried importing the old zpool (which was from an old FreeBSD 8.2 system).

With all 24 drives connected to the server, I issued a zpool import command with the hope the zpool was recoverable:

[root@mediaserver3 /home/mediaserver]# zpool import
   pool: mediatank
     id: 16704184877843764333
  state: ONLINE
 status: The pool was last accessed by another system.
 action: The pool can be imported using its name or numeric identifier and
	the '-f' flag.

	mediatank                  ONLINE
	  raidz1-0                 ONLINE
	    label/WD2TB-row0-col0  ONLINE
	    label/WD2TB-row0-col1  ONLINE
	    label/WD2TB-row0-col2  ONLINE
	    label/WD2TB-row0-col3  ONLINE
	  raidz1-1                 ONLINE
	    label/WD.5TB-r1-c2     ONLINE
	    label/WD.5TB-r1-c3     ONLINE
	    label/WD.5TB-r1-c0     ONLINE
	    label/WD.5TB-r1-c1     ONLINE
	  raidz1-2                 ONLINE
	    label/WD1TB-r2-c0      ONLINE
	    label/WD1TB-r2-c1      ONLINE
	    label/WD1TB-r2-c2      ONLINE
	    label/WD1TB-r2-c3      ONLINE
	  raidz1-3                 ONLINE
	    label/WD2TB-r3-c0_b    ONLINE
	    label/WD2TB-r3-c1      ONLINE
	    label/WD2TB-r3-c2      ONLINE
	    label/WD2TB-r3-c3      ONLINE
	  raidz1-4                 ONLINE
	    label/HIT2TB-r4-c0     ONLINE
	    label/HIT2TB-r4-c1     ONLINE
	    label/HIT2TB-r4-c2     ONLINE
	    label/HIT2TB-r4-c3     ONLINE
	  raidz1-5                 ONLINE
	    label/FLOOD2WDr5c0     ONLINE
	    label/FLOOD2WDr5c1     ONLINE
	    label/FLOOD2HIr5c2     ONLINE
	    label/FLOOD2HIr5c3     ONLINE
[root@mediaserver3 /home/mediaserver]#

Perfect. The zpool wasn’t degraded. Unfortunately, the lightning strike didn’t give me a chance to properly export the zpool before replacing the motherboard and upgrading the OS, so I’d need to forcefully import the zpool on the this new system using zpool import -f:

[root@mediaserver3 /home/mediaserver]# zpool import -f mediatank

Several seconds later, my SSH connection was severed and I received the following panic on the local console of the machine:

panic: solaris assert: end <= sm->sm_start + sm->sm_size (0x6004e1891c000 <= 0x5000000000), file: /usr/src/sys/modules/zfs/../../cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c, line: 120
cpuid = 0
KDB: stack backtrace
#0 0xffffffff808e7dd0 at kbd_backtrace+0x60
#1 0xffffffff808af8b5 at panic+0x155
#2 0xffffffff81b6723f at assfail3+0x2f
#3 0xffffffff81a7bbf9 at space_map_add+0xb9
#4 0xffffffff81a7c429 at space_map_load+0x229
#5 0xffffffff81a66ee0 at metaslab_activate+0x80
#6 0xffffffff81a66209 at metaslab_alloc+0x6e9
#7 0xffffffff81aa0ad2 at zio_dva_allocate+0x136
#8 0xffffffff81a9e6a6 at zio_execute+0x136
#9 0xffffffff808f5b66 at taskqueue_run_locked+0xe6
#10 0xffffffff808f63e8 at taskqueue_thread_loop+0xa8
#11 0xffffffff8088198a at fork_exit+0x9a
#12 0xffffffff80c758ce at fork_trampoline+0xe
Uptime 5m19s

I then spent a few minutes Googling and reading up on the documentation for zpool import. I then tried:

[root@mediaserver3 ~]# zpool import -f -N -o readonly=on -o failmode=continue mediatank

This seemed to successfully import the old pool in read-only mode using legacy support:

[root@mediaserver3 ~]# zpool status
  pool: mediatank
 state: ONLINE
status: The pool is formatted using a legacy on-disk format.  The pool can
	still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
	pool will no longer be accessible on software that does not support feature
  scan: none requested

	NAME                       STATE     READ WRITE CKSUM
	mediatank                  ONLINE       0     0     0
	  raidz1-0                 ONLINE       0     0     0
	    label/WD2TB-row0-col0  ONLINE       0     0     0
	    label/WD2TB-row0-col1  ONLINE       0     0     0
	    label/WD2TB-row0-col2  ONLINE       0     0     0
	    label/WD2TB-row0-col3  ONLINE       0     0     0
	  raidz1-1                 ONLINE       0     0     0
	    label/WD.5TB-r1-c2     ONLINE       0     0     0
	    label/WD.5TB-r1-c3     ONLINE       0     0     0
	    label/WD.5TB-r1-c0     ONLINE       0     0     0
	    label/WD.5TB-r1-c1     ONLINE       0     0     0
	  raidz1-2                 ONLINE       0     0     0
	    label/WD1TB-r2-c0      ONLINE       0     0     0
	    label/WD1TB-r2-c1      ONLINE       0     0     0
	    label/WD1TB-r2-c2      ONLINE       0     0     0
	    label/WD1TB-r2-c3      ONLINE       0     0     0
	  raidz1-3                 ONLINE       0     0     0
	    label/WD2TB-r3-c0_b    ONLINE       0     0     0
	    label/WD2TB-r3-c1      ONLINE       0     0     0
	    label/WD2TB-r3-c2      ONLINE       0     0     0
	    label/WD2TB-r3-c3      ONLINE       0     0     0
	  raidz1-4                 ONLINE       0     0     0
	    label/HIT2TB-r4-c0     ONLINE       0     0     0
	    label/HIT2TB-r4-c1     ONLINE       0     0     0
	    label/HIT2TB-r4-c2     ONLINE       0     0     0
	    label/HIT2TB-r4-c3     ONLINE       0     0     0
	  raidz1-5                 ONLINE       0     0     0
	    label/FLOOD2WDr5c0     ONLINE       0     0     0
	    label/FLOOD2WDr5c1     ONLINE       0     0     0
	    label/FLOOD2HIr5c2     ONLINE       0     0     0
	    label/FLOOD2HIr5c3     ONLINE       0     0     0

errors: No known data errors

I then needed a way to mount my zpool so that I could peer inside of it and confirm there wasn't any data loss. Unfortunately, neither zpool import nor zfs mount mounts legacy mountpoints. I fell back to using good ol' mount:

[root@mediaserver3 ~]# mkdir /mediatank3
[root@mediaserver3 ~]# mount -t zfs mediatank /mediatank3

Changing directory into /mediatank3 and listing it's contents confirmed everything was there and none of my data had been lost.

Update: After several attempts of trying to clear the read-only flag and get the zpool into a writeable state, I finally gave up. I didn't lose any data but this zpool wasn't ever going to be writeable. I transferred everything to another array using rsync, destroyed the zpool, and re-created it.

Setting Bash as the default shell in FreeBSD

Wednesday, September 24th, 2014

The default shell options on a fresh install of FreeBSD include csh, tcsh, zsh, and sh. Notably, this list does not include bash. This omission is surprising enough to most new users of FreeBSD that the FreeBSD Handbook specifically mentions it in their section on default shells.

To install bash in FreeBSD and make it the default shell, execute the following:

[root@mediaserver3 ~]# portsnap update extract
[root@mediaserver3 ~]# cd /usr/ports/shells/bash
[root@mediaserver3 ~]# make install clean

This may take 10 to 15 minutes to install and compile and there will likely be several prompts regarding additional patches, options, etc. throughout the installation that you will need to answer. Stick with the default options and you’ll be fine.

Once bash finishes compiling and installing, you can set it as the default shell for any user by using the chsh command:

[root@mediaserver3 ~]# chsh -s /usr/local/bin/bash mediaserver3
[root@mediaserver3 ~]# chsh -s bash mediaserver3

To confirm that the shell for that particular user was changed, finger them:

[root@mediaserver3 ~]# finger mediaserver3

Note: The FreeBSD Handbook specifically warns against changing the default shell for root “since shells which are not included in the base distribution are installed to /usr/local/bin. In the event of a problem, the file system where /usr/local/bin is located may not be mounted. In this case, root would not have access to its default shell, preventing root from logging in and fixing the problem.”

I’ll leave the choice of ignoring this warning up to you. For the record, I went ahead and enabled bash as root’s default shell. I reasoned that should I somehow manage to so fundamentally break the system that I’m not even able to log in as root anymore (unlikely), then it’s still trivially easy to boot from the FreeBSD Live CD, mount the drive, and switch root’s shell back to tcsh or fix anything else that’s broken. Your call.

Adding a user to the wheel group in FreeBSD

Sunday, May 11th, 2014

By default, root can only login from a local terminal or console. That is, in a regular install of FreeBSD, an unprivileged user cannot elevate their privileges to super user status through the su command unless you specifically granted them that ability by adding that user to the wheel group.

To see a list of groups a current user a is a member of, use the groups command:

[root@mediaserver3 ~]# groups mediaserver

To add a user called mediaserver to the wheel group, use the pw command:

[root@mediaserver3 ~]# pw user mod mediaserver -G wheel

To see the addition, execute the groups command once more:

[root@mediaserver3 ~]# groups mediaserver

Resolving rsync’s “writefd_unbuffered failed to write to socket [sender]: Broken pipe (32)” error

Sunday, October 6th, 2013

As I’ve mentioned in previous posts, I tend to image an entire harddisk before wiping it and then destroying it. I do this because, sometimes, I need to access data from that harddisk after I’ve already destroyed it.

Usually, after I’ve mounted the relevant partition of the harddisk image I’m interested in, I’ll use the incedibly handy rsync to make a perfect copy of the data from the image. Today, I encountered an unusual error when I tried using rsync to copy some data from an old HFS+ partition:

todd@debian: ~$ rsync -avHAX /mnt/hfsplus_partition/Users/ mediaserver@mediaserver4:/mediatank/dd_images/mbp_laptop_sda1/
sending incremental file list
rsync: writefd_unbuffered failed to write 4 bytes to socket [sender]: Broken pipe (32)
rsync: connection unexpectedly closed (9 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(605) [sender=3.0.9]

Turns out, there’s some kind of incompatibility between rsync‘s -H, -A, and/or -X and an HFS+ parition mounted in read-only mode. Since I didn’t care about preserving hard links, ACLs, or extended attributes, I just removed those arguments and was able to get the data I needed:

todd@debian: ~$ rsync -av /mnt/hfsplus_partition/Users/ mediaserver@mediaserver4:/mediatank/dd_images/mbp_laptop_sda1/

Mounting an image of an HFS+ partition in Linux

Tuesday, October 1st, 2013

As I mentioned in a previous post, I tend to make backups of entire disks before destroying them.

In this particular case, I made a 1:1 copy of a partition from an Apple MacBook Pro using dd and wanted to ensure I could access the data before wiping and donating the machine. The image is located at /mnt/server/dd_images/mbp_laptop_sda1.img. Unlike with the ext4 partition I mounted in the my previous post, this isn’t a full disk image, so I won’t need to determine the offset of the partition within the image file. Instead, I can install the latest version of hfsprogs and just mount it directly:

root@debian:/home/todd# apt-get install hfsprogs
apt-get install hfsprogs
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 120 not upgraded.
Need to get 133 kB of archives.
After this operation, 324 kB of additional disk space will be used.
Get:1 squeeze/main hfsprogs amd64 332.25-8 [133 kB]
Fetched 133 kB in 0s (268 kB/s)  
Selecting previously deselected package hfsprogs.
(Reading database ... 132092 files and directories currently installed.)
Unpacking hfsprogs (from .../hfsprogs_332.25-8_amd64.deb) ...
Processing triggers for man-db ...
Setting up hfsprogs (332.25-8) ...

Next, mount the partition read-only, and you should be good to go:

root@debian:/home/todd# root@debian:/home/todd# mount -t hfsplus -o loop,ro /mnt/server/dd_images/mbp_laptop_sda1.img /mnt/hfsplus_partition/

Once you’ve got your partition mounted, you can access it just as you would normally access any other filesystem.

Mounting an ext4 partition from a full-disk image in Linux

Friday, September 13th, 2013

Before wiping a harddrive and sending it out to be recycled, I always make a complete image of it using dd in case I need to retrieve data from it after it’s gone. The procedure is extremely simple, and is well documented all over the internet. Surprisingly, there’s far less information out there on how to mount the partitions and retrieve data one the image is created.

Let’s say you have a complete dump of an entire harddrive and its partitions stored at /mnt/server/dd_images/old_wd_120gb.img and you’d like to access data stored on one of the partitions of that image. Use parted to determine the offset of the partition you’re interested in within the image file:

root@debian:/home/todd# parted /mnt/server/dd_images/old_wd_120gb.img
GNU Parted 2.3
Using /mnt/server/dd_images/old_wd_120gb.img
Welcome to GNU Parted! Type 'help' to view a list of commands.

Tell parted to display all information in bytes beforing printing the partition table:

(parted) unit B

Print the partition table:

(parted) print
Model:  (file)
Disk /mnt/server/dd_images/old_wd_120gb.img: 120034123776B
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start          End            Size           Type      File system     Flags
 1      1048576B       115128401919B  115127353344B  primary   ext4            boot
 2      115129449472B  120033640447B  4904190976B    extended
 5      115129450496B  120033640447B  4904189952B    logical   linux-swap(v1)

We can now see that the first partition, an ext 4 bootable partition, begins at offset 1048576. Take note of this number: we’ll use it in our mount invocation later on.

Quit parted:

(parted) quit

Next, using the above offset you found with parted, use mount to mount partition directly:

root@debian:/home/todd# mount -o loop,offset=1048576 /mnt/server/dd_images/old_wd_120gb.img /mnt/ext4_partition

In most newer environments, mount will automatically create a loop device for you and use that during the mounting process. However, if you’re in an older environment or running with outdated tools and cannot upgrade, you can always manually create the loop device with losetup and then mount it:

root@debian:/home/todd# losetup -o 1048576 /dev/loop0 /mnt/server/dd_images/old_wd_120gb.img
root@debian:/home/todd# mount /dev/loop0 /mnt/ext4_partition/

If you take this route, you may need to destroy the loop device after you unmount:

root@debian:/home/todd# umount /mnt/ext4_partition
root@debian:/home/todd# losetup -d /dev/loop0

Once you’ve got your partition mounted, you can access it just as you would normally access any other filesystem.

Enabling SSH on Boot in FreeBSD

Sunday, June 3rd, 2012

In FreeBSD, the SSH daemon does not automatically run on start up after a fresh installation. To change this, add the following line to /etc/rc.conf:


You use any text editor to edit /etc/rc.conf, but if you wish to remain on the command line, simply appending the above line to /etc/rc.conf will get the job done:

[root@mediaserver3 ~]# echo ‘sshd_enable=”YES”‘ >> /etc/rc.conf

This will start sshd the next time the system restarts. If you’re unwilling or unable to restart your system at the moment, but still want to enable SSH until the next reboot, use:

[root@mediaserver3 ~]# service sshd start

See the FreeBSD Handbook’s section on OpenSSH for more.

Note: By default, only unprivileged users will be able to login over SSH. If you wish to allow logins from root over ssh, you’ll need to enable the PermitRootLogin option in /etc/ssh/sshd_config. Keep in mind that FreeBSD is a heavily security-minded distribution, and that enabling root logins via SSH is generally seen as an ill-advised move.

Further, by default, root can only login from a local terminal or console. That is, in a regular install of FreeBSD, an unprivileged user cannot elevate their privileges to super user status through the su command unless you specifically granted them that ability by adding them to the wheel group.

Installing DD-WRT on the Netgear WNDR3700-100NAS

Thursday, October 20th, 2011

I’ve been a major fan of the DD-WRT project for almost 6 years now. I first stumbled across the project back in 2006 right after I bought a Linksys WRTSL54GS, a router which was notoriously overpowered and underpriced. After an easy trip to Best Buy and a quick download of DD-WRT, one could turn their $60 consumer-grade router into a $600 piece of professional-grade routing equipment.

Much has changed since then (hardware is far more powerful now than it was back then), but yet, some things have remained the same. DD-WRT, for example, is still the best open source firmware for any router out there, hands down. I installed it once in 2006, again in 2009, and having just flashed my 3rd router now in 2011, I can’t tell you how much it pleases me to know that DD-WRT is not only alive and well, but still King of the Open Source Router Firmware Hill.

If you’re wondering why anyone would want to change their stock firmware, I can only say that installing DD-WRT gives you a far greater degree of control over your network and many more ways to make sure that it’s running at it’s fullest potential. I’ve tried describing the benefits of running DD-WRT before, but have always difficulty with it. I think the best way to describe it is that it’s hard to know what you’re missing until you see it.

If your networking needs are straightforward, and your usage is simple, you may do well to keep your router’s stock firmware where it is. But if you frequently video chat, play games, continuously transfer large amounts of data, get poor wireless reception, or do anything outside the ordinary “surf the web” profile, it’s likely you’ll see benefits from installing DD-WRT.

I particularly enjoy playing around with the Quality of Service controls as well as adjusting the transmission power of my wireless antenna, but these are just 2 of nearly 75 different useful features not commonly found on consumer-grade routers. For a good overview of everything DD-WRT has to offer, I suggest reading through the DD-WRT Wiki, especially their explanatory page What Is DD-WRT?.

If you think installing DD-WRT on your router is something you’re interested in, and you’re in the market for a new router, I recommend checking out the Netgear WNDR3700-100NAS.

It’s well supported by DD-WRT, very popular with many of it’s users, and is currently (October 2011) the best router on the market in both the price and performance categories.

Checking the Supported Devices page of the DD-WRT Wiki, we see that the WNDR3700 has two versions with nearly identical hardware specs:
680 Mhz Atheros AR7161 processor
64 MB of RAM
802.11 a/b/g/h/n support
4 Gigabit LAN ports + 1 Gigabit WAN port
Serial port
JTAG port
USB port

What’s important to note is that the first hardware revision, the WNDR3700v1, has 8 MB of Flash and the second hardware revision, the WNDR3700v2, has 16 MB of Flash. While DD-WRT only needs 2 MB of Flash for a bare-bones installation, the more Flash you have available, the more features you’ll be able to install. A complete installation of DD-WRT usually hovers around 7.5-8.5 MB depending on the release, so I’d recommend getting the WNDR3700v2 and it’s spacious 16MB of Flash just to make sure you never run out of room.

Usually, this is where the hard part would begin: with other router manufacturers, finding the right hardware revision (in our case, revision 2) would be an exercise in extreme patience and several attempts to the store since few manufacturers clearly label their devices with anything but a manufacturing date and serial number.

Fortunately though, Netgear makes it easy for us by printing the relevant information right on the outside of the box. No more comparing serial numbers or manufacture dates or guessing and checking… it’s all clearly printed right on the side of the box. You just look at the side of the box, find 2nd revision one, and buy it. (No wonder they’re so popular with the DD-WRT community.)

With this information in mind, feel free to go out and buy a Netgear WNDR3700v2-100NAS. Once you get the right hardware revision, you’re ready to begin the installation process.

Confirm your Hardware
Unpack your router and flip it over so that you have a clear view of its underside. You should see a fairly large label describing the various ports on your router. Ignore all of this. What you’re interested in is the version number.

Under the large “NETGEAR” brand name, you should see some smaller text that says “N600 Wireless Dual Band Gigabit Router” followed by the model number and revision.

If the label says “WNDR3700″ or “WNDR3700v1″, you have the first hardware revision of the WNDR3700-100NAS. This is not the one you want.

If the label says WNDR3700v2, you have the second hardware revision of the WNDR3700-100NAS. This is the one you want.

Once you’ve confirmed that you have the right hardware, you’re ready to download the DD-WRT firmware.

Prepare to go Offline
You’ll have to perform the actual flashing of your router with a computer that’s been disconnected from the internet. This means that you’ll need to download the firmware ahead of time. The DD-WRT Wiki contains a handy guide written specifically for the WNDR3700, but it’s since been outdated, so we’ll only be using it as a reference.

If you have the WNDR3700v2 and you bought it in North America (NA), you’ll want this version of the firmware:

If you have the WNDR3700v2 and you bought it outside of North America, you’ll want the World Wide (WW) version of the firmware:

Go Offline
Once you’ve downloaded the appropriate firmware for your location, unplug your computer from the internet and connect it to one of the LAN ports on the WNDR3700. Power up the WNDR3700 and let it sit for a minute and assign your computer an IP address. Note: It’s important that you connect to the router over one of the ethernet LAN ports, and not the WAN port or the wireless connection.

Flashing the Firmware
Once you’ve connected your computer and router, open your browser and go to the IP address You’ll be presented with a login screen for the router. The default username is admin and the default password is password.

Once you’ve logged in, you should see a screen similar to this:

In the lower left hand corner, under the “Maintenance” section, you should see a link that says “Router Upgrade”. Click that link.

You will then be brought to the Router Upgrade page. Click the “Choose File” button and select the firmware you just downloaded. Click Upload.

A progress bar should appear with a message stating “Note: It will take about 3 minutes for firmware upgrade. Please don’t turn off the power or press reset button”. You’d do well to heed this warning: if the connection between your computer and your router is interrupted for any reason (loss of power, cable becomes unplugged, browser window is closed) at this stage, it will likely semi-brick your device. I say “semi-brick” because it won’t permanently damage your hardware, but it will require more effort to recover the device back into a working state and you’ll have to start over. Consult the DD-WRT Wiki guide for the Netgear WNDR3700 if something goes wrong.

After the upload completes, the router will then begin installing the new firmware. A new progress bar should appear, and should slowly inch it’s way across the screen over the next few minutes.

When it reaches 100%, the browser will refresh, and Netgear’s interface will be replaced by the default DD-WRT change password screen. I know it might be tempting, but do not change your password yet. Let the device sit for 2 minutes to ensure that the router’s had a chance to finish installing everything.

Once 2 minutes are up, create a username and password for your new DD-WRT installation. This will be the username and password you use to log in to the router from If you forget these values, you can reset the router’s firmware (which is now DD-WRT) to its default values by using the 30/30/30 Method as documented in the DD-WRT Wiki. Note: Pushing the reset button on your newly unlocked router will NOT wipe the DD-WRT firmware from the device, so don’t worry. It will instead only reset DD-WRT to its default values.

Congratulations! You’ve successfully installed DD-WRT on your router and are now ready to begin exploring some of the features your new firmware has to offer! Good luck and have fun!

Mounting an NFS Share within a Virtual Machine

Monday, September 12th, 2011

Let’s say you run a FreeBSD server somewhere on your network and you’ve configured it to export a directory via NFS. Everything works as it should when you connect with clients running OSes on native hardware, but as soon as you try to mount the same share on the same hardware with an OS inside a virtual machine, you’re unable to do so.

So what’s going on here? Well, as it turns out, the default behavior for NFS on FreeBSD is to only accept client connections on ports below 1024. This is because services started on port numbers less than 1024 must be started as root or an equivalent system administrator account, and thus are usually safe to trust.

The problem is, most virtual machines typically don’t have access to ports below 1024 because they aren’t started with root or administrator privileges in the host OS (that would defeat all the added security one gains from sandboxing). In fact, some VM packages (VirtualBox comes to mind) won’t even run if it’s started by root unless it’s explicitly forced to. Thus, under most circumstances, the only port numbers guest OSes have access to begin at 1025 and increase from there.

There are two ways around this problem: run each instance of VirtualBox or VMWare with root capabilities (very insecure), or tell your server to just accept incoming connections on ports less than 1024 (a little bit insecure). To do this, simply fire up your favorite text editor, and add the “insecure” flag (denoted by an -n) to the mountd_flags argument list in /etc/rc.conf.

Here’s an example of /etc/rc.conf:


Save your changes and restart rpcbind, nfsd, and mountd as root:

# /etc/rc.d/rpcbind onerestart ; /etc/rc.d/nfsd onerestart ; /etc/rc.d/mountd onerestart

Now you’re good to go!

Remember: NFS was never a security-minded protocol. It was built for speed, with others layering security on top of it. If one wanted a greater degree of security aside from the IP address whitelisting necessary in /etc/exports (which really isn’t that secure at all), they are many options to choose from including Kerberos authentication or tunneling everything through SSH. Check Google or Chapter 14 of the FreeBSD handbook for some good starting points.