Kickstarting from my DD-WRT router

Kickstarting is a convenient way to install an operating system on multiple machines without the need to manually interact with the installation process. After a few hiccups I was able to get everything to run from my router with no other network servers necessary.

USB Storage

My router does not have enough non-volatile storage space for an operating system repository, so I plugged in a 128GB drive (into the front, not the back which is only USB 2.0). The thumb drive appeared in Services >> USB once I enabled “Core USB Support” and “Automatic Drive Mount.”

Although it wasn’t necessary, I decided to format my drive with EXT4. I read somewhere that would make it faster. The web interface in Services >> NAS didn’t work for me, so I had to format the drive from the command line. First, I enabled SSH access: Services >> Services >> Secure Shell >> enable SSHd. I disabled password login and added my authorized key for password-less login. Apply, reboot, and then “ssh root@192.168.1.1” to get in.

I used these commands to format the drive as EXT4:

# format ext4 for drives <2TB:
umount /opt # unmount if necessary
fdisk -l # confirm the location of the drive is /dev/sda
fdisk /dev/sda # partition the drive
"d" to delete the partitions
choose "n" to add a new partition
choose "p" for primary partition
type "1" and press enter to give the partition a name
use default values for cylinders
type "w" and enter to write our changes
mke2fs -j /dev/sda1 # format partition
tune2fs -m 0 /dev/sda1 # recapture reserved 5% of space

Reboot the router. Under Services >> USB, copy the UUID and paste it in the “Mount this Partition to /opt” field. Reboot the router again to make it really mount to /opt.

Install Entware

Entware replaced something called Optware as the best source of extra packages for DD-WRT. Here is the long list of packages available in Entware. I used commands from this installation tutorial to install it for my dual-core ARM processor:

cd /opt
wget http://bin.entware.net/armv7sf-k3.2/installer/generic.sh
sh generic.sh
opkg update
opkg upgrade

As the installation tutorial says, the final step is to add the following commands to the start-up script (Administration >> Commands). The sleep value can be adjusted, but 10 is long enough for most USB hard drives/routers:
sleep 10
/opt/etc/init.d/rc.unslung start

and before shutdown:
/opt/etc/init.d/rc.unslung stop

Install a TFTP server

Nearly every computer can boot off the network. You just set the BIOS configuration to try booting off the network interface before booting up normally. Then, during bootup, the computer asks the DHCP server if there is a TFTP server available with instructions for network booting. The DHCP server will reply with the IP address of the TFTP server for further instructions. So, I set up a TFTP server right on the router with instructions for kickstarting an OS install:

Under Services >> Services >> DNSMasq enable Dnsmasq, and add this line to “Additional Dnsmasq Options:”

dhcp-boot=pxelinux.0,,192.168.1.1

I applied those settings and then ran these commands on the router through ssh:

opkg install xinetd
opkg install tftpd-hpa
opkg install nano
mkdir /opt/tftproot
mkdir /opt/tftproot/pxelinux.cfg
echo "test" > /opt/tftproot/testfile.txt
nano /opt/etc/xinetd.d/tftp

Nano is just a text editor I like. I used it to create a TFTP config file “/opt/etc/xinetd.d/tftp” with the following contents:

service tftp
{
	   flags            = REUSE
	   socket_type      = dgram
	   protocol         = udp
	   instances        = 30
	   wait             = yes
	   user             = root
	   server           = /opt/sbin/tftpd-hpa
	   server_args      = -4 -B 1468 -s /opt/tftproot
	   cps              = 100 2
	   log_on_success   = HOST PID
	   log_on_failure   = HOST
	   disable          = no
}

After ctrl-o <enter> to save and ctrl-x to exit, I then tested the TFTP server from my Ubuntu-Mate laptop:

sudo apt install tftp
tftp 192.168.1.1
tftp> get testfile.txt
Received 6 bytes in 0.0 seconds
tftp> quit

With the TFTP server working, I made a file that would give me three options each time a machine boots. If I don’t press a button, then the machine defaults to just booting normally. The filename is “/opt/tftproot/pxelinux.cfg/default” and has this content:

default menu.c32
prompt 0
timeout 300
ONTIMEOUT 1

menu title ########## PXE Boot Menu ##########

label 1
  menu label ^1) Boot from local drive
  menu default
  localboot 0xffff
label 2
  menu label ^2) Install CentOS 7 x64 with Local Repo using Kickstart
  kernel vmlinuz
  append initrd=initrd.img inst.ks=ftp://192.168.1.1/anaconda-ks.cfg
label 3
  menu label ^3) Memory test
  kernel memtest
  append -

Setup an FTP server

When option 2 is selected, the kickstart installer will load, and it will look for the file “anaconda-ks.cfg” on the FTP server specified. I enabled that FTP server under Services >> NAS >> ProFTPD with the following settings:

Below that, on the same page, I set up file sharing. The leading slash in Subdir is required:

I think I rebooted after this, and tested the FTP server with FileZilla.

Configure Kickstart

The easiest way to create the anaconda-ks.cfg file for kickstarting is to just install CentOS 7 how you want it on one machine. CentOS saves your installation choices to “/root/anaconda-ks.cfg” and you can copy that file (with a few edits) to the FTP server.

For my install, I downloaded CentOS-7-x86_64-DVD-2003.iso and “burned” it to a separate thumb drive:

sudo umount /media/me/USB
sudo dd if=CentOS-7-x86_64-DVD-2003.iso of=/dev/sda

I then did a minimal install on the test server and copied the file “/root/anaconda-ks.cfg” over to the router at “/opt/tftproot/anaconda-ks.cfg”. I then made just two changes to the file so it would install in text mode using files from the FTP server instead of the cdrom:

Copy files for kickstarting

There are a few files on the test server that I needed to copy onto the router. But they only get created when syslinux is installed, and I couldn’t figure out which software groups to select during installation to get syslinux installed. So, after the doing the minimal install on the test server, I mounted the installation thumb drive and installed the syslinux package, along with its dependency:

# mount usb device to get pxelinux.0
# see which one is the usb drive
fdisk -l
mkdir /mnt/usb
mount /dev/sdb1 /mnt/usb
cd /mnt/usb/Packages
rpm -i mtools-4.0.18-5.el7.x86_64.rpm
rpm -i syslinux-4.05-15.el7.x86_64.rpm
cd ~
umount /mnt/usb

Then from my laptop, I copied these files from the test server:

/usr/share/syslinux/pxelinux.0
/usr/share/syslinux/menu.c32
/usr/share/syslinux/mboot.c32
/usr/share/syslinux/chain.c32
/usr/share/syslinux/memdisk

to the router:

/opt/tftproot/pxelinux.0
/opt/tftproot/menu.c32
/opt/tftproot/mboot.c32
/opt/tftproot/chain.c32
/opt/tftproot/memdisk

Next, I copied the full contents of the CentOS 7 installation iso over to the router. DO NOT EXTRACT THE CONTENTS USING ENGRAMPA!! In Ubuntu, I double-clicked the iso file, and Engrampa helpfully let me extract the contents. However, it truncated some filenames to only 64 characters, and that messed me up for quite a while. Instead, a better way to get the contents was to mount the installation iso on my laptop and copy the files from it to the router with scp:

sudo mkdir /mnt/iso
sudo mount ~/Downloads/CentOS-7-x86_64-DVD-2003.iso /mnt/iso -o loop
scp -r /mnt/iso root@192.168.1.1:/opt/tftproot/centos7

Next I copied just three more files into position, which were already on the router:

cp /opt/tftproot/centos7/images/pxeboot/initrd.img /opt/tftproot/
cp /opt/tftproot/centos7/images/pxeboot/vmlinuz /opt/tftproot/
cp /opt/tftproot/centos7/isolinux/memtest /opt/tftproot/

Firewall rules

In my last post on setting up DD-WRT, I listed the firewall rules I used to secure the research VLAN (vlan3). Now, I need to allow traffic back and forth between the router and vlan3. So, I added these lines to the end of the firewall rules:

iptables -I OUTPUT -o vlan3 -j ACCEPT
iptables -I INPUT -i vlan3 -j ACCEPT

Conclusion

That’s it! Now I can install the same operating system on each computer in my makeshift research cluster extremely easily. I’ll handle the rest of the configuration with Ansible, but this is a nice start. More information can be found in the official kickstart guide.