So… maybe someone will laugh and call me an idiot, but for about a day or so I couldn’t figure out how to PXE boot FreeBSD 6.x. I wanted to do this without having a FreeBSD install (in fact, I wanted to do it from my Macbook Pro) which made is particularly interesting.

I had purchased a Soekris Net4826 to replace my dead Apple Airport Extreme access point (sure, a new Airport was cheaper, but the Soekris is just soooo much more fun). I kind of knew what I would do, I would download either m0n0wall or pfSense, burn it to the on board compact flash, and go about my daily life. This is my second Soekris box; I already own a Soekris Net4801 which I use for my primary internet gateway.

Well, the problem came when I couldn’t figure out how to get the image files onto the on-board compact flash on the 4826. On the 4801, it uses an external CF card, so burning it from a USB connector is pretty easy. Completely different with the 4826. So after searching the web, looking through man pages, and getting frustrated…. I found the answer.

The PXE boot tutorial on FreeBSD.org is based on FreeBSD 4.x. It didn’t help me. I found another site that told me how to build FreeBSD to get into a sysinstall menu and do a FreeBSD install, but this was overkill. Looking at the `diskless` manpage resulted in another instance of requiring a FreeBSD installation (oh, by the way, I do have one… I just didn’t want to have to use it for this).

So here’s the solution. This should work for ANY UNIX or UNIX-like Operating system, e.g. FreeBSD, Linux, OpenBSD, OSX, etc. Because of that, I’m not going to get too detailed on where files are. I assume you can find this information yourself.

Getting Started

Let’s define our path, in my case I used /exports/pfsense for everything, so that’ll be the example path used below. You can use whatever you want.

Setting up DHCP

Find your dhcpd.conf file… some OS’s it’s in /etc/dhcpd.conf, some it’s /usr/local/etc/dhcpd.conf. Try locate dhcpd.conf for it, you may not have the package installed. Basically, this is the entry I put into my dhcpd.conf. Keep in mind the Soekris box was crossed over to my Macbook Pro. If you have the Soekris box (or whatever) on the LAN, you may be able to modify your current DHCP server to do this.

dhcpd.conf:

ddns-update-style ad-hoc;
subnet 192.168.0.0 netmask 255.255.255.0 {
host soekris {
hardware ethernet 00:00:24:C9:19:4C;
fixed-address 192.168.0.2;
next-server 192.168.0.1;
filename “/boot/pxeboot”;
option root-path “192.168.0.1:/exports/pfsense”;
}
}

This should be self explanatory for the most part. 192.168.0.1 is my Macbook Pro (the host of the DHCP server, the TFTP server, and the NFS server). I’m assigning the Soekris box a static IP of 192.168.0.2. When it boots, it ill look for /boot/pxeboot, and the root filesystem path will be an NFS mount on my Macbook Pro in the /exports/pfsense directory. The hardware address defines the MAC address of the Soekris LAN controller.

Save your dhcpd.conf and start dhcpd… you shouldn’t see any errors and dhcpd will be in your process list. If it isn’t, you probably have an error. Check your logs, etc.

Setting up TFTP

This can be different depending on whether you’re using inetd.conf or xinetd.conf or launchd on your OSX install. Basically, you want to define your inetd.conf entry to chroot TFTP to the /exports/pfsense directory so that this directory becomes the ‘root’ directory when your login via your TFTP client.

Here’s a typical entry for inetd.conf, on a FreeBSD box…

tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /exports/pfsense

And this is the launchd plist file on my Macbook Pro (from /System/Library/LaunchDaemons/tftp.plist)…

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>InitGroups</key>
<true/>
<key>Label</key>
<string>com.apple.tftpd</string>
<key>ProgramArguments</key>
<array>
<string>/usr/libexec/tftpd</string>
<string>-u</string>
<string>root</string>
<string>-s</string>
<string>/exports/pfsense</string>
<string>-l</string>
</array>
<dict>
<key>Listeners</key>
<dict>
<key>SockServiceName</key>
<string>tftp</string>
<key>SockType</key>
<string>dgram</string>
</dict>
</dict>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<true/>
</dict>
</dict>
</plist>

Make sure after you add or edit the file, you restart inetd or load the plist file using launchctl.

Setting up NFS

This is also a basic NFS setup. Here’s my /etc/exports.

/exports/pfsense -maproot=root

NOTE: I read on the Internet that I could edit the /etc/exports using the Netinfo manager in Applications -> Utilities on my Macbook Pro. This didn’t work, just editing /etc/exports worked fine. This originally frustrated me because I was making changes in Netinfo and they weren’t being reflected in the available mounts.

To startup the NFS daemon, you need portmap (called rpcbind on *BSD), the NFS daemon and mountd. Start reading man pages, this differs OS to OS, but is pretty standard. Make sure you start them all up (in the order mentioned above).

Getting FreeBSD

Now that everything is pretty much set up, we just need to get the FreeBSD sources. We’re going to use 6.2-RELEASE for this example, so follow along.

  1. Create a temporary folder, e.g. /tmp/freebsd.
  2. Log onto a FreeBSD FTP server (e.g. ftp.freebsd.org) and change directory to /pub/FreeBSD/releases/i386/6.2-RELEASE/kernels. This path may change in the future, and I have no control over it, so don’t bitch at me about it if it does.
  3. There are two kernels here, generic and smp. Probably don’t need the SMP kernel, so just get the generic kernel. (note: you may want to issue the bin and prompt commands for the FTP. Also try ‘mget generic.??’ to get all the generic files.
  4. Now, change directory to /pub/FreeBSD/releases/i386/6.2-RELEASE/base (or cd ../base). Now you want to get all the base.?? files (again, use mget).
  5. Log out of the FTP server.
  6. Now you need to decompress all of your generic.?? and base.?? files. First, we’ll do the base… run this command:
  7. cat base.?? | tar --unlink -zxvvf - -C /exports/pfsense

  8. Now decompress the generic kernel, make sure you put it in the right place.

    cat generic.?? | tar --unlink -zxvvf - -C /exports/pfsense/boot

  9. Once all that is done, change directory on your local filesystem to /exports/pfsense/boot, remove the kernel directory (which should be empty), and symlink GENERIC to kernel:
  10. rmdir kernel && ln -s GENERIC kernel

  11. Change into the directory /exports/pfsense/etc and create an empty fstab file:
  12. touch fstab

Guess what?! We’re all done! Now hook up your terminal and boot your PC (or Soekris box) and make sure you’re booting over PXE. You should eventually get the FreeBSD kernel booting and everything looking like a normal FreeBSD install. And then finally… a login prompt.
TADA!

Once you logon, you get plenty of options.

  1. You can run /usr/sbin/sysinstall and install FreeBSD.
  2. You can copy a m0n0wall or pfSense image file into the directory on your NFS server, it will then show up on your client. You can use that to dd the file to your local drive (or Compact Flash). This is what I did… I was able to use the m0n0wall and pfSense image files and just use dd to image the built-in compact flash. (Each distribution has it’s own instructions for this, check out their individual websites for more information).
  3. If you’re a real hacker and have built a nanobsd image from the FreeBSD source tree, you can also image the local drive with that nanobsd image.
  4. Of course, you’re not limited to FreeBSD or *BSD images, you can use any image (so maybe if you have a Linux image or Windows image?).

Some other things you should consider:

  1. You can modify files in /exports/pfsense/etc and they will be immediately reflected on the running system. Likewise, you can edit the rc.conf file to start services that will start the next time the machine reboots. I did this with the SSH daemon.
  2. Network parameters? Sure! Just edit rc.conf with your network configuration!
  3. If you want to boot multiple clients from the same source tree, you may wanna man diskless on your FreeBSD install to see how that’s done. There are already scripts in place to load configurations for each diskless client based on the IP address.
  4. If you want to use this method for doing mass installations for clients and what not with various different installation images, you can define another NFS mount point with all of your software and mount this additional NFS mount in /exports/pfsense/etc/fstab. This way you can have another drive with all your various images that you need, just pick the one you need!
  5. This process can be used to bootstrap and install many systems simultaneously and quickly. You can add additional scripts to automatically burn your images for you, or create menus to choose with image to install, etc.

Anyway. This pretty much covers it. It’s not difficult, just doesn’t seem to be documented anywhere. If you have any additional things that you can use this for, feel free to leave me a message.

Leave a Reply

You must be logged in to post a comment. Login »