A freshly installed server could not build standard or engineer: about 8 GB they install from existed only on the running server. scripts/capture-site-content.sh pulls it over SSH into the gitignored payload: - _shared/Applications/extra (Office, Adobe, OpenText, Java, fonts, Wi-Fi, Zscaler), without pxe-status/ (the playbook deploys that); - each image's own Deploy/Applications files and folders (GE CA certificates, the Engineering Layer payload), without the repo-managed Install-EngineeringLayer.ps1 and without stale BPRT copies; - the links images keep there, as links.txt; - fresh bios-staging (*.exe plus models.txt, which the Dell update rewrites), boot.wim, and the known Blancco file set. It dry-runs by default, compares by checksum (a Blancco config.img had the same size and time as the stale copy), writes SHA256SUMS, and refuses what FAT32 cannot hold: files of 4 GiB or more, Windows-illegal names, and case-only name clashes. build-usb.sh copies site-content/ unsplit and refuses to build without it (unless --skip-site-content), or when SHA256SUMS is missing or does not cover every file. The playbook checks SHA256SUMS, then merges the content into winpeapps and recreates the links. It only links to folders that exist, so it never creates an empty _shared BPRT, which would stop the first MCL import from seeding it. Link lines are validated before anything is copied. pull-bios.sh is gone. It read a path the server no longer uses, with a hard-coded password.
251 lines
13 KiB
Markdown
251 lines
13 KiB
Markdown
# GE Aerospace PXE Boot Server
|
|
|
|
Automated, air-gapped PXE boot server for deploying GE Aerospace Windows images. Built on Ubuntu 24.04 Server with zero-touch provisioning via autoinstall and Ansible.
|
|
|
|
## Overview
|
|
|
|
This project provides a complete, repeatable build process for a PXE boot server that serves Windows PE images to client machines on an isolated network. Everything runs offline after initial setup — no internet required on the target server.
|
|
|
|
### Boot Chain
|
|
|
|
```
|
|
Client PXE boot (UEFI Secure Boot)
|
|
-> iPXE (TFTP, Broadcom-signed for Secure Boot)
|
|
-> iPXE boot menu (HTTP, port 4433)
|
|
-> User selects boot option:
|
|
├── Windows PE -> wimboot -> boot.wim -> startnet.cmd -> Samba share -> Image deployment
|
|
├── Clonezilla -> vmlinuz/initrd -> Disk cloning/imaging
|
|
├── Blancco -> Native kernel + initramfs -> NIST 800-88 drive erasure
|
|
(memory test: Dell F12 > Diagnostics)
|
|
```
|
|
|
|
### Services
|
|
|
|
| Service | Port | Purpose |
|
|
|-------------|-----------|------------------------------------------|
|
|
| dnsmasq | 67/udp | DHCP (172.16.9.10-100, 12h lease) |
|
|
| dnsmasq | 69/udp | TFTP (serves ipxe.efi) |
|
|
| Apache | 80/tcp | HTTP (wimboot, WinPE boot files, proxy) |
|
|
| Apache | 4433/tcp | iPXE boot script (GetPxeScript.aspx) |
|
|
| Samba | 445/tcp | Deployment content + Clonezilla + Blancco|
|
|
| Flask Webapp| 9009/tcp | Web management interface |
|
|
|
|
### Network
|
|
|
|
- **PXE server IP:** `172.16.9.1/24`
|
|
- **DHCP range:** `172.16.9.10` - `172.16.9.100`
|
|
- **Firewall:** UFW deny-by-default, only service ports open (22, 67, 69, 80, 445, 4433, 9009)
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
**On your workstation (internet-connected):**
|
|
- Ubuntu 24.04 (or Linux Mint / similar) for downloading packages
|
|
- Ubuntu Server 24.04 ISO
|
|
- GE Aerospace Media Creator LITE (for WinPE images)
|
|
- USB drive >= 8 GB (32+ GB if bundling WinPE images)
|
|
|
|
**GE Access Packages (MyAccess portal):**
|
|
- EPM Rufus Exception Request
|
|
- EPM DT Functions
|
|
- DLP - Encrypted Removable (USB) Long Term Access
|
|
|
|
### Step 1: Download Offline Packages
|
|
|
|
```bash
|
|
./scripts/download-packages.sh --iso /path/to/ubuntu-24.04.x-live-server-amd64.iso
|
|
./scripts/check-updates.py # expect: PASSED, 0 security updates
|
|
./scripts/fetch-ipxe.sh
|
|
```
|
|
|
|
`fetch-ipxe.sh` downloads the Secure Boot iPXE chain into `boot-files/`, pinned by sha256: the iPXE release
|
|
tarball (its snponly build becomes `ipxe.efi`) and iPXE's dual-signed shim (Microsoft UEFI CA 2011 + 2023),
|
|
which every UEFI client boots as `ipxe-shim.efi`. Keep the old Broadcom-signed `boot-files/ipxe.efi` too: the
|
|
playbook installs it as `ipxe-bcm.efi`, the rollback boot file.
|
|
|
|
Downloads all .deb packages and Python wheels for offline installation (~140 MB of debs, ~20 MB of wheels).
|
|
|
|
### Step 2: Prepare Boot Tools (optional)
|
|
|
|
```bash
|
|
./scripts/prepare-boot-tools.sh /path/to/blancco.iso
|
|
```
|
|
|
|
Extracts and configures boot tool files (Blancco, Clonezilla with Debian's signed shim for Secure Boot). Automatically patches Blancco's config.img to auto-save erasure reports to the PXE server's Samba share.
|
|
|
|
### Step 3: Build the USB
|
|
|
|
```bash
|
|
sudo ./scripts/build-usb.sh /dev/sdX /path/to/ubuntu-24.04-live-server-amd64.iso
|
|
```
|
|
|
|
Creates a bootable USB with two partitions:
|
|
- **Partition 1:** Ubuntu Server installer
|
|
- **Partition 2:** CIDATA (autoinstall config, offline .debs, pip wheels, Ansible playbook, webapp, boot tools)
|
|
|
|
### Step 4: Install on Target Server
|
|
|
|
1. Insert USB into the target machine
|
|
2. Press F12 and boot from USB
|
|
3. Ubuntu auto-installs with no interaction
|
|
4. After reboot, the first-boot script:
|
|
- Installs all offline .deb packages
|
|
- Runs the Ansible playbook (configures dnsmasq, Apache, Samba, UFW, webapp)
|
|
- Configures static IP `172.16.9.1/24`
|
|
5. Move the server's wired NIC to the isolated PXE switch
|
|
|
|
### Step 5: Access the Web Interface
|
|
|
|
Open `http://172.16.9.1:9009` from any machine on the isolated network.
|
|
|
|
## Web Management Interface
|
|
|
|
The Flask webapp (port 9009) provides a browser-based management UI:
|
|
|
|
- **Dashboard** — Service status overview, disk usage, connected DHCP clients
|
|
- **Image Import** — Import WinPE deployment images from USB drives
|
|
- **Unattend Editor** — Edit Windows unattend.xml files per image type (XML syntax highlighting)
|
|
- **startnet.cmd Editor** — Modify the startnet.cmd inside boot.wim without Windows (uses wimtools)
|
|
- **Clonezilla Backups** — Upload, download, and manage disk backup images
|
|
- **Blancco Reports** — View, download, and manage drive erasure reports (auto-collected via Samba)
|
|
- **Image Config** — Per-image configuration editor (drivers, OS packages, hardware models)
|
|
- **Enrollment** — Upload, download, and manage GCCH bulk enrollment packages
|
|
- **Audit Log** — Activity history for all write operations (imports, edits, deletes)
|
|
|
|
### Image Types Supported
|
|
|
|
| Image Type | Domain | Description |
|
|
|----------------------|-----------------|-------------------------|
|
|
| gea-standard | geaerospace.com | Standard desktop |
|
|
| gea-engineer | geaerospace.com | Engineering desktop |
|
|
| gea-shopfloor | geaerospace.com | Shop floor kiosk |
|
|
| ge-standard | ge.com | Standard desktop |
|
|
| ge-engineer | ge.com | Engineering desktop |
|
|
| ge-shopfloor-lockdown| ge.com | Shop floor (locked) |
|
|
| ge-shopfloor-mce | ge.com | Shop floor (MCE) |
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
pxe-server/
|
|
├── autoinstall/
|
|
│ ├── user-data # Cloud-init autoinstall config + first-boot script
|
|
│ └── meta-data # Cloud-init metadata (required, empty)
|
|
├── playbook/
|
|
│ ├── pxe_server_setup.yml # Ansible playbook: all server configuration
|
|
│ ├── inventory.ini # Ansible inventory
|
|
│ ├── startnet.cmd # WinPE startup script (injected into boot.wim)
|
|
│ ├── blancco-init.sh # Custom initramfs for Blancco PXE boot
|
|
│ ├── blancco-preferences.xml # Blancco auto-report preferences
|
|
│ ├── check-bios.cmd # Pre-imaging BIOS update checker
|
|
│ ├── FlatUnattendW10-shopfloor.xml # Shopfloor unattend.xml
|
|
│ └── shopfloor-setup/ # PC type setup scripts (Standard, CMM, Display, etc.)
|
|
├── webapp/
|
|
│ ├── app.py # Flask application (~1600 lines)
|
|
│ ├── requirements.txt # Python deps (flask, lxml)
|
|
│ ├── static/
|
|
│ │ ├── ge-aerospace-logo.svg # GE Aerospace branding
|
|
│ │ ├── favicon.ico # Browser favicon
|
|
│ │ ├── app.js # Frontend JavaScript
|
|
│ │ ├── bootstrap.min.css # Bootstrap 5 (bundled offline)
|
|
│ │ ├── bootstrap.bundle.min.js
|
|
│ │ ├── bootstrap-icons.min.css
|
|
│ │ └── fonts/ # Icon fonts (woff/woff2)
|
|
│ └── templates/
|
|
│ ├── base.html # Layout with GE branding and sidebar nav
|
|
│ ├── dashboard.html # Service status and overview
|
|
│ ├── import.html # USB image import wizard
|
|
│ ├── unattend_editor.html # XML editor for unattend files
|
|
│ ├── startnet_editor.html # startnet.cmd WIM editor
|
|
│ ├── image_config.html # Per-image driver and hardware config
|
|
│ ├── enrollment.html # GCCH bulk enrollment packages
|
|
│ ├── backups.html # Clonezilla backup management
|
|
│ ├── reports.html # Blancco erasure reports
|
|
│ └── audit.html # Activity audit log
|
|
├── docs/
|
|
│ └── shopfloor-display-imaging-guide.md # End-user imaging guide
|
|
├── boot-tools/ # Extracted boot tool files (gitignored)
|
|
│ ├── blancco/ # Blancco Drive Eraser
|
|
│ └── clonezilla/ # Clonezilla Live
|
|
├── boot-files/ # WinPE boot files (boot.wim, wimboot, ipxe.efi, BCD)
|
|
├── offline-packages/ # .deb files (gitignored, built by download-packages.sh)
|
|
├── pip-wheels/ # Python wheels (gitignored, built by download-packages.sh)
|
|
├── enrollment/ # PPKGs and run-enrollment.ps1 (gitignored)
|
|
├── bios-staging/ # Dell BIOS update binaries (gitignored)
|
|
├── scripts/ # Build, deploy, and helper scripts
|
|
│ ├── build-usb.sh # Builds the installer USB (2-partition)
|
|
│ ├── build-proxmox-iso.sh # UNSUPPORTED (use build-usb.sh --image)
|
|
│ ├── prepare-boot-tools.sh # Extracts and patches boot tool files
|
|
│ ├── download-packages.sh # Downloads offline .debs + pip wheels
|
|
│ ├── download-drivers.py # Downloads Dell drivers directly from dell.com
|
|
│ ├── deploy-bios.sh # Pushes BIOS updates to enrollment share
|
|
│ ├── capture-site-content.sh # Pulls site content + fresh payload from a live server
|
|
│ ├── sync_hardware_models.py # Syncs hardware model configs across images
|
|
│ ├── Upload-Image.ps1 # Windows: upload MCL cache to PXE via SMB
|
|
│ └── Download-Drivers.ps1 # Windows: download hardware drivers from GE CDN
|
|
├── config/ # Site-specific configuration overrides
|
|
├── startnet-template.cmd # startnet.cmd template (synced with playbook copy)
|
|
├── README.md # This file
|
|
└── SETUP.md # Detailed setup guide
|
|
```
|
|
|
|
## Proxmox Deployment
|
|
|
|
`scripts/build-proxmox-iso.sh` is no longer supported: it was a second,
|
|
drifted copy of the installer. Build a disk image with
|
|
`scripts/build-usb.sh --site-vars site-vars.yml --image pxe-usb.img auto UBUNTU.iso`
|
|
and import it on the Proxmox host (`qm importdisk <vmid> pxe-usb.img
|
|
<storage>`), attached after the system disk in the boot order. The VM needs
|
|
two NICs: one on an isolated imaging bridge (no other DHCP server) and one
|
|
on the corp bridge; their MACs go in `site-vars.yml`.
|
|
|
|
### Import WinPE Images
|
|
|
|
After the server is running, import deployment images via the web interface at `http://172.16.9.1:9009/import` or by mounting a USB drive with WinPE content.
|
|
|
|
## Samba Shares
|
|
|
|
| Share | Path | Purpose |
|
|
|-----------------|---------------------------|--------------------------------|
|
|
| winpeapps | /srv/samba/winpeapps | WinPE deployment images |
|
|
| clonezilla | /srv/samba/clonezilla | Clonezilla disk backup images |
|
|
| blancco-reports | /srv/samba/blancco-reports| Blancco erasure reports (auto) |
|
|
| enrollment | /srv/samba/enrollment | GCCH bulk enrollment packages |
|
|
| image-upload | /home/pxe/image-upload | Image upload staging area |
|
|
|
|
All shares use guest access (no authentication) for ease of use on the isolated network.
|
|
|
|
## Blancco Drive Erasure
|
|
|
|
Blancco Drive Eraser 7.15.1 boots via a native Ubuntu kernel with a custom initramfs (`blancco-init.sh`) that downloads and mounts the Blancco rootfs over HTTP. XML erasure reports are automatically saved to the PXE server's Samba share (`blancco-reports`). The server supports BMC cloud licensing for Blancco activation over WiFi.
|
|
|
|
Reports are viewable and downloadable from the web interface at `http://172.16.9.1:9009/reports`.
|
|
|
|
## Notes
|
|
|
|
- Run `download-packages.sh --iso <the server ISO>` before building the USB: it builds the offline apt repo (every update for the ISO's base plus the explicit packages, wimtools included) that the installer patches and installs from
|
|
- The webapp uses session-based CSRF tokens on all POST forms and API endpoints
|
|
|
|
## Commit History
|
|
|
|
| Commit | Description |
|
|
|---------|--------------------------------------------------------------------|
|
|
| 5791bd1 | Initial project setup: automated PXE server provisioning |
|
|
| cee4ecd | Add web management UI, offline packages, WinPE consolidation |
|
|
| f614596 | Fix unattend.xml path to match actual image structure |
|
|
| e7313c2 | Add multi-boot PXE menu, Clonezilla backups, GE Aerospace branding|
|
|
| 89b5834 | Add wimtools and startnet.cmd editor for boot.wim modification |
|
|
| 05dbb7e | Add Blancco erasure reports Samba share and webapp viewer |
|
|
| ef75839 | Auto-patch Blancco config.img for network report storage |
|
|
| 92c9b0f | Fix review findings: offline assets, security, audit logging |
|
|
| 725c8f4 | Change webapp to port 9009, add test VM script |
|
|
| f3a384f | Add Proxmox ISO builder, CSRF protection, boot-files integration |
|
|
| 1a5c4f7 | Eliminate USB requirement for WinPE PXE boot |
|
|
| dd2fec5 | Blancco PXE boot via Ubuntu kernel switch_root |
|
|
| 86660a0 | Remove UEFI HTTP Boot config from dnsmasq |
|
|
| 6d0e6ee | BIOS check fix, parallel downloads, shopfloor hardening |
|
|
| 7616549 | Shopfloor PC type system, webapp enhancements |
|
|
| b7cd097 | Blancco 7.15.1 upgrade: native kernel boot, BMC cloud licensing |
|
|
| 163e58a | Fix dnsmasq reboot cron: use /etc/cron.d/ instead of crontab |
|