- Boot Ubuntu via http/ftp server with pxe(diskless boot)
- Pxe short info
- How i do it
- Customize initramfs
- Creating squashfs
- Setup bootloader, squashfs, and pxe server
- Conclusion
- UEFI PXE netboot / install procedure
- Step 1: Get the files
- Step 2: Get the files
- Step 3: Install TFTP and DHCP server (for simplicity, dnsmasq is used here)
- Alternative method to create a boot image (all-in-one file)
- Optional Extras
- Install a package cacher
- Debugging Options
- Notes
Boot Ubuntu via http/ftp server with pxe(diskless boot)
PXE is a great solution for booting a diskless computer (or a computer without an OS installed). This method is often used for terminal stations and OS mass installation.
Stock ubuntu (16.04) in pxe-mode can mount rootfs only from NFS. But this is not a great idea: any difficulties with the network/NFS server and the user gets problems.
In my opinion, it’s best to use other protocols, such as http/ftp. Once booting, you will have an independent system
You should add information about the limits of applicability of the proposed solution and what are the dependencies and restrictions.
Pxe short info
PXE (Preboot Execution Environment) is a special method for booting a computer from the bios / EFI.
How it works (simplified scheme):
- The computer bios/uefi sends ordinary dhcp request (DHCPDISCOVER)
- The dhcp server sends a response with the next-server option
- The computer sends DHCPREQUEST/DHCPINFORM request
- The dhcp server sends TFTP server address and the filename to upload
- The computer downloads this file from the tftp server. Its size is limited so, often, it’s a bootloader like pxeinux
- pxelinux reads its own config and downloads Linux kernel using initramfs
- Linux kernel downloads squashfs with main rootfs
- switch_root to its squashfs
Keep in mind that TFTP is a slow protocol. It works around UDP with a small block size (512K). Of course, you can increase this value, but this is a way of unstable operation.
- get bootloader via tftp
- get kernel (+ initramfs) via tftp
- get main rootfs squash via http/tftp
How i do it
- Add modules to initramfs
- Write my own boot script and add it to initramfs
- Make new initramfs
- Create squashfs with future rootfs
- Setup pxe server
- Run it
I used squashfs for rootfs (the simplest way is to create squashfs from installed ubuntu). Overlayfs is necessary to make rootfs writable.
Supported protocols are http/ftp, but you can try to add others via curl/other software.
Customize initramfs
There are 2 places where you can customize initramfs in ubuntu:
I’ll use /usr/share/initramfs-tools. First, I added needed support modules in initramfs:
boozlachu@comp:~$ cat /usr/share/initramfs-tools/modules.d/pxe overlayfs squashfs
Next, I wrote a boot script that does all the work:
boozlachu@comp:~$ cat /usr/share/initramfs-tools/scripts/pxe #!/bin/bash mountroot() < maxTryCount=5 squashfsFile="/tmp/rootfs.squashfs" squashfsMountPoint="/mnt/ro" tmpfsMountPoint="/mnt/rw" overlayfsUppderDir="$tmpfsMountPoint/upper" overlayfsWorkDir="$tmpfsMountPoint/work" overlayfsDir="/mnt/overlayfs" tryCount="1" # run udevadm wait_for_udev 10 # parce kernel cmdline args. rooturl needed for x in $(cat /proc/cmdline); do case $x in rooturl=*) export rooturl=$;; maxTryCount=*) export maxTryCount=$ ;; esac done log_begin_msg "Loading modules" modprobe squashfs || panic "can't modprobe squashfs" modprobe af_packet || panic "can't modprobe af_packet" modprobe overlay || panic "can't modprobe overlayfs" log_success_msg "modules loaded" log_begin_msg "Configure network" configure_networking || panic "Can't configure network" log_success_msg "Network configured" log_begin_msg "Download rootfs" while [ ! -f $ ] && [ $ -le $ ]; do wget $ -O $ || log_failure_msg "Can't download rootfs, count $" tryCount=$(( $ + 1 )) sleep 0.5 done if [ -f $ ] then log_success_msg "Rootfs downloaded" else panic "Can't download rootfs" fi log_begin_msg "Mount rootfs" mkdir -p $squashfsMountPoint mount -t squashfs -o loop $squashfsFile $squashfsMountPoint || panic "Can't mount rootfs" log_success_msg "Rootfs mounted" log_begin_msg "Mount tmpfs" mkdir -p $tmpfsMountPoint mount -t tmpfs none $tmpfsMountPoint || panic "Tmpfs mount failed " log_success_msg "Tmpfs mounted" log_begin_msg "Mount overlayfs" mkdir -p $overlayfsUppderDir $overlayfsWorkDir $overlayfsDir mount -t overlay overlay -o lowerdir=$squashfsMountPoint,upperdir=$overlayfsUppderDir,workdir=$overlayfsWorkDir $overlayfsDir \ || panic "Overlayfs mount failed" log_success_msg "Overlayfs mounted" log_begin_msg "Move tmpfs and squashfs to new root" mkdir -p $overlayfsDir/$tmpfsMountPoint $overlayfsDir/$squashfsMountPoint mount --move $squashfsMountPoint $overlayfsDir/$squashfsMountPoint || panic "squashfs move failed" mount --move $tmpfsMountPoint $overlayfsDir/$tmpfsMountPoint || panic "tmpfs move failed" log_success_msg "Tmpfs and squashfs moved" log_begin_msg "Move overlayfs to new root" mount --move $overlayfsDir $ || panic "" >
The script has a lot of messages for understanding how it works.
After the modules and script, add your need to generate new initramfs:
boozlachu@comp:~$ sudo update-initramfs -c -k all
Creating squashfs
- install ubuntu on drive
- boot from LiveCD
- create squashfs from the installed system
I don’t recommend this way for production since you’ll have a very large squashfs (not the best idea for pxe)!
Setup bootloader, squashfs, and pxe server
I use pxelinux as a pxe bootloader. It’s an easy way. My pxe servers are Debian 10, tftp-hpa,dhcpd, and lighttpd.
I’ll omit the installation details, but I’ll show the important info.
TFRP server file struct (/srv/tftp is root dir fot tftp-hpa):
root@debian:/srv/tftp/ubuntu# tree /srv/tftp/ /srv/tftp/ └── ubuntu ├── firmware.sq ├── initrd ├── ldlinux.c32 ├── libcom32.c32 ├── libutil.c32 ├── menu.c32 ├── pxelinux.bin ├── pxelinux.cfg │ └── default ├── vesamenu.c32 └── vmlinuz
- firmware.sq is squashfs with rootfs
- *c32 are files for pxelinux
- vmlinuz is kernel
- initrd is initramfs(which i rebuild earler)
- pxelinux.bin — main pxelinux file
- default is config for pxelinux
root@debian:/srv/tftp/ubuntu# cat /srv/tftp/ubuntu/pxelinux.cfg/default ui menu.c32 timeout 30 default ubuntu_pxe font UniCyr_8x16.psf menu title PXE Special Boot Menu menu color tabmsg 37;40 #80ffffff #00000000 menu color hotsel 30;47 #40000000 #20ffffff menu color sel 30;47 #40000000 #20ffffff menu color scrollbar 30;47 #40000000 #20ffffff LABEL ubuntu_pxe menu label Run ubuntu pxe kernel vmlinuz append initrd=initrd rooturl=http://192.168.56.2/ubuntu/firmware.sq boot=pxe maxTryCount=10
It’s impotant to set the correct kernel parameters:
- rooturl=http://192.168.56.2/ubuntu/firmware.sq, url for rootfs
- boot=pxe, use my script for boot
- maxTryCount=10, number of tries for rootfs download (optional, default value 5)
And the last one is the dhcp config:
root@debian:/srv/tftp/ubuntu# cat /etc/dhcp/dhcpd.conf subnet 192.168.56.0 netmask 255.255.255.0 < range 192.168.56.10 192.168.56.45; option routers 192.168.56.2; option domain-name-servers 192.168.2.1 ; option broadcast-address 192.168.56.255; default-lease-time 3600; max-lease-time 7200; # Important! Set bootloader file filename "ubuntu/pxelinux.bin"; >
The extended variant (if the dhcp and tftp servers placed on different machines) requires the next-server option for dhcp.
Conclusion
This article shows you how to change the boot mode of ubuntu without any difficulties. Use it as information and write your solutions. This can be a system in the form of firmware (with squashfs), pxe, or another solution.
UEFI PXE netboot / install procedure
This method is an experimental method, which serves a UEFI signed grub image, loads the configuration in grub.cfg and boots the Linux kernel.
The original method on this Wiki page used an all-in-one image, which was good for the simple install on diskless PCs, but made preseeding impossible without modifying the mini.iso
Step 1: Get the files
2. Download the correct netboot.tar.gz archive (navigate to the correct one!): http://cdimage.ubuntu.com/netboot/
3. Extract netboot.tar.gz into /srv/tftp/
Step 2: Get the files
On releases after 14.04; you should also provide the file ‘install/filesystem.squashfs’ via HTTP or FTP to use to complete the netboot install.
1. Create the file /srv/tftp/grub/grub.cfg with the following content. Add other entries as needed:
For standard install (Not Preseeded):
menuentry "Install Ubuntu" set gfxpayload=keep linux /ubuntu-installer/amd64/linux gfxpayload=800x600x16,800x600 --- quiet initrd /ubuntu-installer/amd64/initrd.gz >
On releases after 14.04; add «live-installer/net-image=$PATH_TO_FILESYSTEM_SQUASHFS» before the three dashes to provide a root filesystem for the installer to use as a base for the install; or use «live-installer/enable=false».
For Preseeding (automatic hands-off install — you will need an HTTP server to serve the config):
menuentry "Install Ubuntu" set gfxpayload=keep linux /ubuntu-installer/amd64/linux gfxpayload=800x600x16,800x600 --- auto=true url=http://YOUR_PRESEED_SERVER/preseed.cfg quiet initrd /ubuntu-installer/amd64/initrd.gz >
Step 3: Install TFTP and DHCP server (for simplicity, dnsmasq is used here)
sudo apt-get install dnsmasq
2. Set your computer to use a static IP
3. Configure dnsmasq add these lines to /etc/dnsmasq.conf
interface=eth0 bind-interfaces dhcp-range=192.168.99.10,192.168.99.254 dhcp-boot=grubnetx64.efi.signed enable-tftp tftp-root=/srv/tftp/
sudo service dnsmasq restart
Alternative method to create a boot image (all-in-one file)
- Install a regular Ubuntu system + updates, or use an existing Ubuntu system as the Server. The Server can be any computer with a wired NIC; the Server itself does not need to be UEFI-capable. (I installed ubuntu-11.10-desktop-amd64.iso from a USB stick on to an x220 laptop, but any Ubuntu installation should work).
- On the Server system, fetch a netboot «mini.iso» image and save it with a distinct filename (or substitute a different Ubuntu distro for «trusty»; see Notes below about Debian):
wget http://ftp.ubuntu.com/ubuntu/dists/trusty/main/installer-amd64/current/images/netboot/mini.iso \ -O /tmp/mini-trusty.iso
- the ls|sed sequence generates the list of all modules.
- many of the modules are actually required, but surely not all; I don’t know which are or aren’t required.
sudo apt-get install grub-efi-amd64-bin grub-mkimage --format=x86_64-efi \ --output=/tmp/grubnetx64.efi.signed \ --memdisk=/tmp/mini-trusty.iso \ `ls /usr/lib/grub/x86_64-efi | sed -n 's/\.mod//gp'`
- Note that some modules may cause the installation to stall with a error: no device connected message, in this case you will need to remove the drivers giving the error. For instance, to remove the pata module, change the module listing part to ls /usr/lib/grub/x86_64-efi | sed -n 's/\.mod//gp' | grep -v pata
- This method seems like it should work with Debian wheezy’s netboot/mini.iso also, but it doesn’t quite; the Clients just boot to a grub> prompt instead of a grub installer menu. Perhaps wheezy’s iso contains a grub.cfg someplace other than the /boot/grub dir that Ubuntu’s grub expects?
- If you see a «error: variable `prefix’ isn’t set» message, it can be safely ignored. Really, it doesn’t mean anything. If your installation is stalling and this is visible on-screen, you should look at the «next» error, that’s the one actually stopping it form working. If it really bothers you, play around with the ‘-p’ parameter to grub-mkimage and see you can make it go away.
Optional Extras
Install a package cacher
This will ensure that your internet is not hammered by hundreds of PCs, by caching the downloads required for the install on a local server. If you are using preseed, add this to your HTTP Proxy settings in your preseed config (HTTP Proxy: http://[The IP Address]:3142/).
1. Install apt-cacher-ng to provide http proxy service to the Clients (proxy listens on port 3142):
sudo apt-get install apt-cacher-ng
* The installed Client system will remember the proxy server setting in /etc/apt/apt.conf — remove that file from the installed Client if you don’t plan to keep it attached to the server’s network.
* If you use apt-cacher-ng as described above, subsequent client installs using this Server will be much faster than the first client install.
Debugging Options
A. Watch syslog on the Server with «tail -f /var/log/syslog»
B. Run tcpdump on the server, to check which files are being requested (tcpdump must be installed):
Notes
- It is possible to configure dhcp to offer different images to different clients based on MAC address and some other variables, which could be used to offer UEFI (bootx64.efi) and legacy BIOS (pxelinux.0) images, but this is not covered here.
UEFI/PXE-netboot-install (последним исправлял пользователь cyphermox 2016-09-23 20:55:07)
The material on this wiki is available under a free license, see Copyright / License for details.