(I didn't write this document.) Diskless CRUX with a FreeBSD server FreeBSD is great. In my humble opinion it is superior to Linux in almost everyway with one exception, the desktop environment. After being totally frustrated with the plethora of desktop applications and games that ,despite having the appearence of platform independance, either perferm poorly, if at all, on my freebsd desktop (even when using linux binaries), I figured I really should get a linux desktop running. The problem was that all my filesystems were in UFS2 format, which linux only has limited read support for. So I decided to investigate the possibility of running a diskless linux that would boot from a bsd server. What follows is a recall of what was required (I even managed to do without a local linux box) This guide will show in a general fashion how to install CRUX on a computer without the need for any removeable media whatsoever. Requirements: A server with the following services: DHCP TFTP NFS NIS (optional) *The server does not even have to be a Linux one :D Your clients NIC must also support PXE bootloading. This is not 100% necessarry, but other network boot methods will require a boot floppy/cd. Part 1: The Kernel You will need to compile your own kernel for booting. The following options should be built into the kernel (ie. not modules) Networking support ---> [*] Networking support Networking options ---> <*> Packet socket ... [*] TCP/IP networking ... [*] IP: kernel level autoconfiguration [*] IP: DHCP support !!Note: you will also need to have your network card driver in the kernel File systems ---> Network File Systems ---> <*> NFS file system support [*] Provide NFSv3 client support ... [*] Root file system on NFS Part 2: The DHCP Server For this I used the ics-dhcp server with the following configuration: allow booting; allow bootp; option domain-name "lan"; option domain-name-servers ns1.lan; option routers 192.168.0.2; default-lease-time 600; max-lease-time 7200; authoritative; ddns-update-style none; subnet 192.168.0.0 netmask 255.255.255.0 { use-host-decl-names on; option subnet-mask 255.255.255.0; option broadcast-address 192.168.0.255; option nis-domain "mydomain"; host grousebox { hardware ethernet 00:0a:48:00:d0:14; fixed-address grousebox.lan; filename "pxelinux.0"; } } One important thing to notice is the filename option, this will be discussed in part 4. Part 3: The TFTP Server TFTP Servers are really easy to setup. But, also really, really insecure. Unfortunately you need this one (see Part 4), however you only need it for bootloading. Here are some tips to make things safer: 1. Only serve what you really need to (in this case, the bootloader and the kernel and nothing else). 2. Run it in a chrooted/jailed environment. 3. Only allow access from trusted hosts, either by use of a firewall (best way) or tcp_wrappers (easiest way). 4. Never, never, ever run TFTP as a privildged user. NEVER!!! In this case I used a chrooted TFTP server serving from /tftpboot Part 4: The bootloader As mentioned earlier I used the PXE bootlading method. This allows you to boot a computer directly over a network (no floppy required), which is great if your NIC supports it. For this I chose to use PXELINUX (from the SYSLINUX project) In the DHCP example in Part 2, there is a line: filename "pxelinux.0"; This is the name of the PXE boot loader relative to the root of your TFTP environment (for example if I chose not to run TFTP in a chroot in would be "tftpboot/pxelinux.0"). In the same location as the PXE bootloader you need a directrory called "pxelinux.cfg". In that directory create a file called "default", here is what mine looks like: default CRUX label install kernel vmlinuz.install append nfsroot=192.168.0.2:/data/crux/install nfsaddrs=::: label CRUX kernel vmlinuz append nfsroot=192.168.0.2:/data/crux/diskless nfsaddrs=::: Part 4: The NFS Server This is also quite simple, you will need to have 2 NFS exports, an installation export and one where you intend in install crux. I used the 2 directories: Installer: /data/crux/install System: /data/crux/diskless *Home: /home (optional) *NOTE: I am not sure if this was an error in my exports but I could not get an install by exporting the cdrom directory, if this turns out to be an issue with exporting iso9660 mountpoints this is an easy way to migrate the files to another filesystem: $ cd /cdrom; tar cf - | tar xf - -C /data/crux/install You should note that by default NFS exports do not allow root permissions even if mouted by root on the remote site, this is not a problem if your server is running CRUX as then you could just export / and have diskless clients run the same system as your server. However, in this case the server is FreeBSD so we want the remote root to have root access ot the export. Security Tip: A safer method would be to create a user for the crux system directory and in your exports file map remote root access to that user. Part 5: The Installation Pre-Install Notes: My client has a stack of ram, so I did not bother with swap space (besides swap over nfs is really quite stupid). However, if you really need it, here is a suggested method: Create a swapfile: $ cd /data/crux/diskless $ dd if=/dev/zero of=swap.img bs=1024k count=512 $ chmod 0600 swap.img Adjust the count to the required size, this example create a 512Mb swapfile **NOTE: I just assumed this would work (it doesn't), us FBSD users have it so easy!! However this can be achieved using Linux's Network Block Device support (explanation coming later) You are now ready to install a diskless CRUX. Installation: If you have set everything up correctly you should be net booting and running the crux installer. For this you can just follow the handbook with exception to the creation of swap and filesystems. Create the filesystem: $ mount NFS_SERV_ADDR:/data/crux/diskless /mnt If you created a swapfile: $ swapon /mnt/swap.img Go through the rest of the install process as normal. When you build your new kernel for the system make sure you keep the options stated in Part 1 in your kernel. Post Installation: /etc/rc.d/net: You will most likely not need to touch this as your network card gets configured by the DHCP server. /etc/rc.conf: At a minimum your services line should be: SERVICES=(net portmap nfsclient) /etc/rc: This file will need to be edited slightly, remove the following lines: ----------------- # Activate swap /sbin/swapon -a # Mount root read-only /bin/mount -n -o remount,ro / # Check filesystems /sbin/fsck -A -T -C -a if [ $? -gt 1 ]; then echo echo "*************** FILESYSTEM CHECK FAILED ******************" echo "* *" echo "* Please repair manually and reboot. Note that the root *" echo "* file system is currently mounted read-only. To remount *" echo "* it read-write type: mount -n -o remount,rw / *" echo "* When you exit the maintainance shell the system will *" echo "* reboot automatically. *" echo "* *" echo "************************************************************" echo /sbin/sulogin -p echo "Automatic reboot in progress..." /bin/umount -a /bin/mount -n -o remount,ro / /sbin/reboot -f exit 0 fi ----------------- If you are using a swapfile make the following changes: ----------------- # Mount local filesystems /bin/mount -n -o remount,rw / /bin/rm -f /etc/mtab* /bin/mount -a -O no_netdev /bin/swapon /swap.img ----------------- /etc/fsab: You will need to define at a minimum your root filesystem: NFS_SERVER:/data/crux/diskless / nfs defaults 0 0 If you mount any other nfs filesystems, be sure to include the _netdev option, eg: NFS_SERVER:/home /home nfs defaults,_netdev 0 0 /vmlinuz: This needs to be placed on your TFTP server, so it can be used by the PXE bootloader. Congratulations, you should now have a diskless CRUX ready to be consumed :D Part 6: NIS I won't go into the details of setting up an NIS environment as there is plenty of good documentation out there already. There is one exception however, freebsd uses a different password system to linux (master.passwd vs shadow). To get password authentication to work across platforms you need to make the following changes to /var/yp/Makefile on the BSD server. 1. Uncomment the 'UNSECURE = "True"' line. 2. In the $(PASSWD) target change the line: print $$1":*:"$$3":"$$4":"$$8":"$$9":"$$10}' $(MASTER) \ to: print $$1":x:"$$3":"$$4":"$$8":"$$9":"$$10}' $(MASTER) \