[Grml] network boot via iPXE
ipeter88
ipeter88 at centrum.sk
Thu Nov 30 23:01:03 CET 2017
Hi
Here is example of ipxe server configuration for ipv4 network booting of grml (linux distribution only) on both BIOS and UEFI systems.
IPXE server is built on grml system with IP address 192.168.101.1
What we need
- installation files (grml iso image(s))
- tftp server (it is enough to use installed atftpd)
- dhcp server (here isc-dhcp-server)
- web server (here nginx)
- ipxe binaries and scripts
- DNS server (only required when we want to use dns names instead of ip addresses in configuration files)
Installation files
Mount iso image(s) to gain access to installation files
mkdir -p /srv/tftp/dist/grml/grml32
mkdir -p /srv/tftp/dist/grml/grml64
mount -t iso9660 -o loop /srv/tftp/data/grml32-full_2017.05.iso /srv/tftp/dist/grml/grml32
mount -t iso9660 -o loop /srv/tftp/data/grml64-full_2017.05.iso /srv/tftp/dist/grml/grml64
TFTP server
We will use atftps in standalone mode, so its configuration file /etc/default/atftpd should look like:
USE_INETD=false
OPTIONS="--port 69 --tftpd-timeout 300 --retry-timeout 5 --maxthread 100 --verbose=5 /srv/tftp"
DHCP server
Install ISC dhcp server
apt-get update
apt-get install isc-dhcp-server
Create/modify configuration file /etc/dhcp/dhcpd.conf
# next variables will be shown in dhcpd.leases file
set vendorclass-string = option vendor-class-identifier;
set userclass-string = option user-class;
ddns-update-style none;
allow booting;
deny bootp; #default
authoritative;
log-facility local7;
option client-arch code 93 = unsigned integer 16; # RFC4578
subnet 192.168.101.0 netmask 255.255.255.0 {
default-lease-time 3600;
max-lease-time 7200;
option subnet-mask 255.255.255.0;
option routers 192.168.101.1;
option domain-name-servers 192.168.101.1;
next-server 192.168.101.1;
option domain-name "grml.lan";
option domain-search "grml.lan";
option router-discovery false; #flag
pool {
range 192.168.101.50 192.168.101.69;
}
pool {
range 192.168.101.80 192.168.101.99;
}
}
## List an unused interface here
# subnet 192.168.1.0 netmask 255.255.255.0 {
#}
option space ipxe;
option ipxe-encap-opts code 175 = encapsulate ipxe;
option ipxe.priority code 1 = signed integer 8;
option ipxe.keep-san code 8 = unsigned integer 8;
option ipxe.skip-san-boot code 9 = unsigned integer 8;
option ipxe.syslogs code 85 = string;
option ipxe.cert code 91 = string;
option ipxe.privkey code 92 = string;
option ipxe.crosscert code 93 = string;
option ipxe.no-pxedhcp code 176 = unsigned integer 8;
option ipxe.bus-id code 177 = string;
option ipxe.san-filename code 188 = string;
option ipxe.bios-drive code 189 = unsigned integer 8;
option ipxe.username code 190 = string;
option ipxe.password code 191 = string;
option ipxe.reverse-username code 192 = string;
option ipxe.reverse-password code 193 = string;
option ipxe.version code 235 = string;
option iscsi-initiator-iqn code 203 = string;
option ipxe.pxeext code 16 = unsigned integer 8;
option ipxe.iscsi code 17 = unsigned integer 8;
option ipxe.aoe code 18 = unsigned integer 8;
option ipxe.http code 19 = unsigned integer 8;
option ipxe.https code 20 = unsigned integer 8;
option ipxe.tftp code 21 = unsigned integer 8;
option ipxe.ftp code 22 = unsigned integer 8;
option ipxe.dns code 23 = unsigned integer 8;
option ipxe.bzimage code 24 = unsigned integer 8;
option ipxe.multiboot code 25 = unsigned integer 8;
option ipxe.slam code 26 = unsigned integer 8;
option ipxe.srp code 27 = unsigned integer 8;
option ipxe.nbi code 32 = unsigned integer 8;
option ipxe.pxe code 33 = unsigned integer 8;
option ipxe.elf code 34 = unsigned integer 8;
option ipxe.comboot code 35 = unsigned integer 8;
option ipxe.efi code 36 = unsigned integer 8;
option ipxe.fcoe code 37 = unsigned integer 8;
option ipxe.vlan code 38 = unsigned integer 8;
option ipxe.menu code 39 = unsigned integer 8;
option ipxe.sdi code 40 = unsigned integer 8;
option ipxe.nfs code 41 = unsigned integer 8;
option ipxe.no-pxedhcp 1;
if not exists client-arch {
#guessing . . .
filename "ipxe/bin/undionly.kpxe";
} elsif exists user-class and option user-class = "iPXE" {
filename "http://192.168.101.1/tftp/dist/bootstrap.ipxe";
} elsif substring(option client-arch,0,0) = option client-arch {
#guessing . . .
filename "ipxe/bin/undionly.kpxe";
} elsif option client-arch = encode-int (0,16) { # 0 x86 BIOS
filename "ipxe/bin/ipxe.pxe";
} elsif option client-arch = encode-int (7,16) { # 7 x64 UEFI
filename "ipxe/bin-x86_64-efi/ipxe.efi";
} elsif option client-arch = encode-int (9,16) { # 9 EBC
filename "ipxe/bin-x86_64-efi/ipxe.efi";
} elsif option client-arch = encode-int (16,16) { # 16 x64 uefi boot from http
option vendor-class-identifier "HTTPClient";
filename "http://192.168.101.1/tftp/ipxe/bin-x86_64-efi/ipxe.efi";
}
# host testpc1 {
# hardware ethernet 01:02:03:04:05:06;
# fixed-address 192.168.101.10;
# next-server 192.168.101.1;
# if exists user-class and option user-class = "iPXE" {
# filename "http://192.168.101.1/tftp/dist/otherbootstrap.ipxe";
# } else {
# filename "ipxe/bin-x86_64-efi/ipxe.efi";
# }
# }
#
# host testpc2 {
# hardware ethernet 01:02:03:04:05:07;
# fixed-address 192.168.101.20;
# next-server 192.168.101.1;
# filename "lpxelinux.0";
# }
Web server
Install/use nginx
apt-get install nginx
Configure nginx - it is enough to leave default configuration in /etc/nginx/sites-available/default but change directive root.
For debuging purposes you can put also 'autoindex on' directive there. Result is here.
server {
listen 80 default_server;
root /srv;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
autoindex on;
}
}
IPXE
There is ipxe.deb package in standard repository but better results were obtained by own compiled binaries or binaries from home web page
wget http://boot.ipxe.org/ipxe.efi
wget http://boot.ipxe.org/undionly.kpxe
wget http://boot.ipxe.org/ipxe.pxe
mkdir -p /srv/tftp/ipxe/bin
mkdir -p /srv/tftp/ipxe/bin-x86_64-efi
cp undionly.kpxe ipxe/bin/undionly.kpxe
cp ipxe.pxe ipxe/bin/ipxe.pxe
cp ipxe.efi ipxe/bin-x86_64-efi/ipxe.efi
Script /srv/tftp/dist/bootstrap.ipxe
#!ipxe
cpuid --ext 29 && set distribution grml64 || set distribution grml32
chain http://192.168.101.1/tftp/dist/${distribution}.ipxe ||
shell
Script /srv/tftp/dist/grml64.ipxe
#!ipxe
set httpserver 192.168.101.1
set httpbase http://${httpserver}/tftp
set dist grml64
set httpsrc ${httpbase}/dist/${dist}
echo httpsrc=${httpsrc}
set kernelargs initrd=initrd.img boot=live apm=power-off vga=791 nomce fetch=${httpsrc}/live/grml64-full/grml64-full.squashfs nobeep noeject noprompt noblank keyboard=us xkeyboard=us tz=Europe/Bratislava hostname ssh=password
echo 'Loading kernel...'
kernel ${httpsrc}/boot/grml64full/vmlinuz ${kernelargs}
echo 'Loading initrd...'
initrd ${httpsrc}/boot/grml64full/initrd.img initrd.img
boot
# there is also possible to convert syslinux/grub menu distributed on grml installation media to ipxe menu and build this menu to this script
Script /srv/tftp/dist/grml32.ipxe
The same contents as /srv/tftp/dist/grml64.ipxe, only change occurrence of string 64 with 32
DNS server
For this example we are using IP addresses so we will not use/configure DNS server at all
Finale
Start/restart all daemons
systemctl stop atftpd
systemctl stop nginx
systemctl stop dhcpd
systemctl start atftpd
systemctl start nginx
systemctl start dhcpd
Happy booting
Peter
More information about the Grml
mailing list