NetBoot on FreeBSD

December 23, 2010

The Specs

  • I built this system for our Authorized Apple Service Provider where we use it primarily for NetInstalling machines after a hard drive replacement. Getting the right system on the right machine is crucial and NetBoot provides the best platform to do so, in my opinion (as opposed to, say having dozens of drives and/or partitions of installers for every possible Intel Mac, for each of your technicians).
  • We don’t need diskless support (something I’ll probably have to address sooner or later).
  • We don’t support PPC machines (haven’t had the need to do so thus far).

The server is running FreeBSD 8.1. I create the NetBoot images using System Image utility (I have a machine with both 10.5. and 10.6 installed so I can create images of both systems). The images are stored on a RAID-Z pool under /data/nb.

##Installation##

NetBoot essentially consists of 3 pieces (in order of appearance):

  • A DHCP server to provide addressing and initial server discovery
  • A TFTP server for transferring the kernel and extension cache
  • An HTTP or NFS server to provide the actual disk image data

NFS and TFTP are essentially “built in” to FreeBSD, so we only need to install ISC’s DHCP server:

# cd /usr/ports/net/isc-dhcp41-server
# make install clean

On to configuring the DHCP server. I’m assuming you already have the basic functionality sorted and will only focus on the NetBoot-relevant bits:

# nano /usr/local/etc/dhcpd.conf

To which we append the following:

class "AppleNBI-i386" {
  match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
  option dhcp-parameter-request-list 1,3,17,43,60;

  if (option dhcp-message-type = 1) { option vendor-class-identifier "AAPLBSDPC/i386"; }
  if (option dhcp-message-type = 1) { option vendor-encapsulated-options 08:04:81:00:00:67; }

  filename "boot.nbi/i386/booter";
  option root-path "nfs:172.17.65.1:/data/nb:/boot.nbi/NetBoot.dmg";
}

The first four lines inside the class section - I have no idea what they do, but I haven’t tried this without them, so there they are. The last two however make perfect sense - the first defines the path of the booter file (the low-level EFI binary). This is always relative to the root of your tftp server, which by default is /tftpboot. Since my only application for tftpd is NetBoot, I simply symlink /tftpboot to my NetBoot image set repository:

# ln -s /tftpboot /data/nb
# ls /tftpboot
MacBookPro5,2.nbi   Macmini4,1.nbi      boot.nbi        retail_10.6.3_2.nbi
MacBook3,1.nbi      MacBookPro6,2.nbi   MacBook7,1.nbi      MacBookPro7,1.nbi   iMac11,3.nbi
10.5.6_retail.nbi   MacBookAir2,1.nbi   Macmini3,1.nbi      asd_efi_3s123       retail_10.6.3.nbi

I like to name all my CPU-specific install images based on their “Model Identifier” (sysctl hw.model, more on “why” in a later article…). As mentioned previously, the sets are all created using SUI. boot.nbi is a NetBoot set, preferably of a really fresh retail package (or the latest CPU bundle) which is used as the default set. As you can see, I also have an Apple Service Diagnostic image in there, more on that some other time…

The last line sets the network path of the actual NetBoot “payload” - the OS and/or installer that will be booted and mounted. The colons are significant - “nfs” means the file sharing protocol (which will set up in just a bit), “/data/nb” is the path of the NFS share and is separated from the IP of the server so that the client (in our case the OS X kernel) knows what to mount and finally “/netboot.nbi/NetBoot.dmg” is the path of the actual disk image to be mounted.

All that remains is to let dhcpd know we mean business:

# /usr/local/etc/rc.d/isc-dhcpd restart

##TFTP and NFS##

With DHCP set up, let’s configure and test the two other components of this system, starting with TFTP:

# nano +28 /etc/inetd.conf

Uncomment the current and following line and kick inetd:

# /etc/rc.d/inetd restart

Test it by downloading one of the booter files from any Mac. In my environment this would mean:

$ tftp 172.17.65.1
tftp> get boot.nbi/i386/booter
Received 322301 bytes in 14.1 seconds
tftp> quit
$ file booter
booter: Universal EFI binary with 2 architectures, x86_64, i386

Ignore the insane slowness, I’m testing this over VPN. Notice the path that we “get” is exactly the same as the filename parameter in dhcpd.conf. If you didn’t get the “Received…” line, try the same thing locally on the server and go from there…

NFS can be a bit more involved and I’m tempted to simply point you to the handbook, but in a nutshell:

# nano /etc/rc.conf
rpcbind_enable="YES"
nfs_server_enable="YES"
mountd_flags="-r"
# echo /data/nb >> /etc/exports
# rpcbind
# nfsd -u -t -n 4
# mountd -r

You can test the NFS connection from the Finder, with Command-K > nfs://172.17.65.1/data/nb. A number of things can go wrong here, I strongly suggest you check the handbook as well as the server and client logs (may the Lords of Cobol be with you).

##Taking it for a spin##

Everything should now be set up and ready to go. Grab an Intel Mac and boot it with the N-key. You should see the big globe icon (looking for the server), followed by the Apple logo and spinning globe (downloading kernel) and then the normal progress indicator (mounting the DMG and booting). If you get a kernel panic, then booting with N and then Command-V will usually give you a hint as to what’s wrong.

Any number of things could have gone wrong here and I can’t recommend Mike Bombich’s excellent Troubleshooting the NetBoot Process article enough (thank the gods it’s now hosted in a safe place on AFP548).

##Does this mean that…##

… you can use any PC server to NetBoot Macs? Yes. But in all honesty, this is all little more than a clunky workaround for sysadmins desperately strapped for cash (not to mention too much time on their hands). And even though it also serves as a nice “training program” for understanding the inner workings of NetBoot, Apple’s solution is much nicer and waaay easier to use.

For example, as it stands, this system will not support diskless NetBoot, and only the default NetBoot set will be available from the firmware. As I understand, this is because Apple actually uses a proprietary DHCP server (not the stock ISC one that we installed) that has a “special relationship” with the Mac firmware. Oh, and you can forget about limiting certain Mac models to certain NetInstall sets (which would be nice).

But this system works surprisingly well for us and so I decided to write it down. There’s actually one more piece of the puzzle (a “secret sauce”, if you will) that makes this whole thing a bit more useful (which I call “netbless”), but more on that some other time… :-P