Skip to content

Instantly share code, notes, and snippets.

@iamacarpet
Last active March 22, 2025 10:26
Show Gist options
  • Select an option

  • Save iamacarpet/46c9a03f7527840491c6e47cd9f0891b to your computer and use it in GitHub Desktop.

Select an option

Save iamacarpet/46c9a03f7527840491c6e47cd9f0891b to your computer and use it in GitHub Desktop.

Revisions

  1. iamacarpet revised this gist Feb 8, 2024. 1 changed file with 0 additions and 0 deletions.
    Binary file removed ipxe.zip
    Binary file not shown.
  2. iamacarpet revised this gist Jan 30, 2024. 2 changed files with 7 additions and 3 deletions.
    10 changes: 7 additions & 3 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -8,10 +8,14 @@
    ## Files required

    * `x64/snponly_x64.efi` (Secure Boot signed iPXE from 2Pint Software)
    * `2PXE/File/Boot%5C2PintLogo.png` (splash screen image)
    * `2PXE/File/logo` (PNG splash screen image)
    * `2PXE/Boot` (iPXE script containing boot configuration).
    * `wimboot.x86_64.efi` (Secure Boot signed wimboot, can be stored in remote object storage)

    ## Additional files

    * `x64/snponly_usb_x64.efi` (Secure Boot signed iPXE from 2Pint Software, designed to be booted via USB)

    ## TFTP server

    TFTP server needs to be configured to serve `x64/snponly_x64.efi`.
    @@ -26,13 +30,13 @@ Based on the URL provided in DHCP option 175, iPXE will request some files via H

    It’ll first request:

    `GET /2PXE/File/Boot%5C2PintLogo.png`
    `GET /2PXE/File/logo`

    Then:

    `POST /2PXE/Boot`

    This POST request does include a lot of variables that allow for a dynamic response (see https://gist.github.com/iamacarpet/d37c17bcaf8767093a53265ed4d04b83#file-2pxe-ipxe-L206), however, we want to ignore that & just return a static boot menu file.
    This POST request does include a lot of variables that allow for a dynamic response (see https://gist.github.com/iamacarpet/d37c17bcaf8767093a53265ed4d04b83#file-2pxe-ipxe-L237), however, we want to ignore that & just return a static boot menu file.

    Ideally, we’d serve straight from Google Cloud Storage or similar, but it doesn’t allow POST requests without a specific data structure in the form parameters, so we’re best to use nginx (and this can be remote, over the internet, if it’s easier to host that way, but may need to use an IP address rather than a DNS domain, as it’s not clear if DNS is available here).

    Binary file modified ipxe.zip
    Binary file not shown.
  3. iamacarpet revised this gist Jan 9, 2024. 1 changed file with 0 additions and 0 deletions.
    Binary file added ipxe.zip
    Binary file not shown.
  4. iamacarpet created this gist Jan 9, 2024.
    82 changes: 82 additions & 0 deletions Boot
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    #!ipxe

    # Some menu defaults
    set menu-timeout 60000
    set submenu-timeout ${menu-timeout}
    isset ${menu-default} || set menu-default exit


    ###################### MAIN MENU ####################################

    :start
    menu iPXE boot menu for Example Ltd
    item --gap -- ----------------------- Glazier Images (Blank) --------------------------
    item --key b windows-blank Run Glazier with windows-blank (Windows 11 Pro) configuration
    item --key n win10-blank Run Glazier with win10-blank (Windows 10 Pro) configuration
    item --gap -- -------------------- Glazier Images (autopilot) --------------------------
    item --key y windows-autopilot Run Galazier with windows-autopilot (Windows 11 Pro) configuration
    item --gap -- ------------------------- Advanced options -------------------------------
    item shell Drop to iPXE shell
    item reboot Reboot computer
    item
    item --key x exit Exit iPXE and continue BIOS boot
    choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
    set menu-timeout 0
    goto ${selected}

    :cancel
    echo You cancelled the menu, dropping you to a shell

    :shell
    echo Type 'exit' to get the back to the menu
    shell
    set menu-timeout 0
    goto start

    :failed
    echo Booting failed, dropping to shell
    goto shell

    :reboot
    reboot

    :exit
    exit

    ############ MAIN MENU ITEMS ############

    :windows-blank
    echo Booting WinPE for Glazier with windows-blank configuration
    kernel http://storage.googleapis.com/example-glazier-files/wimboot.x86_64.efi
    ## wimboot allows replacing files inside the WIM by loading them as initrd entires here,
    ## where I believe they end up exposed in C-Windows-System32
    initrd http://storage.googleapis.com/example-glazier-config/blank/autobuild.ps1 autobuild.ps1
    initrd http://storage.googleapis.com/example-glazier-files/Boot/BCD BCD
    initrd http://storage.googleapis.com/example-glazier-files/Boot/boot.sdi boot.sdi
    initrd http://storage.googleapis.com/example-glazier-files/sources/boot.wim boot.wim
    boot || goto failed
    goto start

    :win10-blank
    echo Booting WinPE for Glazier with win10-blank configuration
    kernel http://storage.googleapis.com/example-glazier-files/wimboot.x86_64.efi
    ## wimboot allows replacing files inside the WIM by loading them as initrd entires here,
    ## where I believe they end up exposed in C-Windows-System32
    initrd http://storage.googleapis.com/example-glazier-config/win10-blank/autobuild.ps1 autobuild.ps1
    initrd http://storage.googleapis.com/example-glazier-files/Boot/BCD BCD
    initrd http://storage.googleapis.com/example-glazier-files/Boot/boot.sdi boot.sdi
    initrd http://storage.googleapis.com/example-glazier-files/sources/boot.wim boot.wim
    boot || goto failed
    goto start

    :windows-autopilot
    echo Booting WinPE for Glazier with windows-autopilot configuration
    kernel http://storage.googleapis.com/example-glazier-files/wimboot.x86_64.efi
    ## wimboot allows replacing files inside the WIM by loading them as initrd entires here,
    ## where I believe they end up exposed in C-Windows-System32
    initrd http://storage.googleapis.com/example-glazier-config/autopilot/autobuild.ps1 autobuild.ps1
    initrd http://storage.googleapis.com/example-glazier-files/Boot/BCD BCD
    initrd http://storage.googleapis.com/example-glazier-files/Boot/boot.sdi boot.sdi
    initrd http://storage.googleapis.com/example-glazier-files/sources/boot.wim boot.wim
    boot || goto failed
    goto start
    70 changes: 70 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    # Glazier UEFI network boot

    ## You’ll need
    * A TFTP server
    * A HTTP server (needs to support custom configuration, ideally nginx)
    * The ability to configure custom DHCP options on your existing DHCP server.

    ## Files required

    * `x64/snponly_x64.efi` (Secure Boot signed iPXE from 2Pint Software)
    * `2PXE/File/Boot%5C2PintLogo.png` (splash screen image)
    * `2PXE/Boot` (iPXE script containing boot configuration).
    * `wimboot.x86_64.efi` (Secure Boot signed wimboot, can be stored in remote object storage)

    ## TFTP server

    TFTP server needs to be configured to serve `x64/snponly_x64.efi`.

    It doesn’t need to be in the local subnet, but you can run into some issues if it isn’t.

    It’ll need to only be accessible over a private network, not something that can be exposed or accessed over the internet.

    ## HTTP server

    Based on the URL provided in DHCP option 175, iPXE will request some files via HTTP.

    It’ll first request:

    `GET /2PXE/File/Boot%5C2PintLogo.png`

    Then:

    `POST /2PXE/Boot`

    This POST request does include a lot of variables that allow for a dynamic response (see https://gist.github.com/iamacarpet/d37c17bcaf8767093a53265ed4d04b83#file-2pxe-ipxe-L206), however, we want to ignore that & just return a static boot menu file.

    Ideally, we’d serve straight from Google Cloud Storage or similar, but it doesn’t allow POST requests without a specific data structure in the form parameters, so we’re best to use nginx (and this can be remote, over the internet, if it’s easier to host that way, but may need to use an IP address rather than a DNS domain, as it’s not clear if DNS is available here).


    ### Example nginx configuration
    ```
    server {
    listen 8050 default_server;
    root /srv/tftp;
    index index.html index.htm index.nginx-debian.html;
    server_name _;
    error_page 405 =200 $uri;
    location /healthz {
    access_log off;
    keepalive_timeout 0;
    add_header Content-Type text/plain;
    return 200 "OK";
    }
    }
    ```
    where “/srv/tftp” is the folder containing the HTTP files referenced above.

    *Note the line `error_page 405 =200 $uri;` that allows a POST for a static file.*

    ## Configure the following DHCP options
    * Option 66: TFTP Server IP, e.g. 10.25.0.250
    * Option 67: x64/snponly_x64.efi
    * Option 175 (custom, string): HTTP URL for additional files, e.g. http://10.25.0.250:8050/