[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