# PXE Server Setup Guide

Automated build process for deploying an Ubuntu-based PXE boot server that hosts GE Aerospace Windows PE images. The entire setup is air-gapped — no internet required on the target machine.

## Architecture

```
Client PXE boot
  -> Broadcom signed iPXE (Secure Boot)
  -> iPXE boot menu (HTTP, port 4433)
     ├── Windows PE -> wimboot -> boot.wim -> startnet.cmd -> Samba -> Image deployment
     ├── Clonezilla -> vmlinuz/initrd -> Disk cloning/imaging
     ├── Blancco    -> Native kernel + initramfs -> NIST 800-88 drive erasure (auto-reports)
     └── Memtest86+ -> Memory diagnostics
```

### Services on the PXE Server

| Service     | Port      | Purpose                                  |
|-------------|-----------|------------------------------------------|
| dnsmasq     | 67/udp    | DHCP (10.9.100.10-100)                   |
| 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 + backup + reports    |
| Flask Webapp| 9009/tcp  | Web management interface                 |

## Prerequisites

### Hardware
- Server or PC with >= 8 GB RAM, >= 250 GB disk, one wired NIC
- USB thumb drive >= 8 GB (32+ GB if bundling WinPE images)

### Software (on your workstation)
- Ubuntu Server 24.04 ISO — https://ubuntu.com/download/server
- Linux workstation (Ubuntu/Mint) for running download and build scripts
- GE Aerospace Media Creator LITE (for caching WinPE images)

### GE Access Packages
- EPM Rufus Exception Request
- EPM DT Functions
- DLP - Encrypted Removable (USB) Long Term Access

## Setup Process

### Step 1: Download Offline Packages (one-time, requires internet)

```bash
./scripts/download-packages.sh
```

Downloads all .deb packages (ansible, dnsmasq, apache2, samba, wimtools, etc.) into `offline-packages/` and Python wheels (flask, lxml) into `pip-wheels/`. Approximately 252 packages (~140 MB) + 8 Python wheels.

**Packages included:**
- **Server:** dnsmasq, apache2, samba, ufw, cron
- **Automation:** ansible
- **Tools:** wimtools, unzip, p7zip-full
- **Python:** python3-pip, python3-venv
- **Network:** network-manager, wpasupplicant, wireless-tools, linux-firmware

### Step 2: Prepare Boot Tools (optional)

```bash
./scripts/prepare-boot-tools.sh /path/to/blancco.iso /path/to/clonezilla.zip /path/to/memtest.bin
```

Extracts boot files for Blancco, Clonezilla, and Memtest86+ into the `boot-tools/` directory. Automatically patches Blancco's `config.img` to auto-save erasure reports to the PXE server's Samba share.

### Step 3: Build the USB

```bash
# Basic — server only (import WinPE images later)
sudo ./scripts/build-usb.sh /dev/sdX /path/to/ubuntu-24.04-live-server-amd64.iso

# With WinPE images bundled (single USB, larger drive needed)
sudo ./scripts/build-usb.sh /dev/sdX /path/to/ubuntu-24.04.iso /path/to/winpe-images
```

This creates a bootable USB with:
- **Partition 1:** Ubuntu Server installer
- **Partition 2:** CIDATA (autoinstall config, offline .debs, pip wheels, Ansible playbook, webapp, boot tools)

### Step 4: Boot the Target Machine

1. Insert the USB into the target machine
2. Press F12 (or vendor boot key) and select the USB
3. Ubuntu auto-installs — no interaction needed
4. After reboot, the first-boot script installs all .deb packages and runs the Ansible playbook
5. PXE services (dnsmasq, Apache, Samba) are configured automatically
6. Flask webapp starts on port 9009

### Step 5: Connect to Isolated Network

Move the server's wired NIC to the isolated switch for PXE clients.

### Step 6: Import WinPE Content (if not bundled in Step 3)

**Option A:** Use the web interface at `http://10.9.100.1:9009` to import from USB.

**Option B:** Manual copy:
```bash
sudo mkdir -p /mnt/usb2
sudo mount /dev/sdb2 /mnt/usb2
sudo cp -r /mnt/usb2/. /srv/samba/winpeapps/gea-standard
sudo umount /mnt/usb2
```

## Web Management Interface

Access at `http://10.9.100.1:9009` from any machine on the isolated network.

| Page              | URL Path    | Purpose                                       |
|-------------------|-------------|-----------------------------------------------|
| Dashboard         | /           | Service status, disk usage, DHCP clients       |
| Image Import      | /import     | Import WinPE images from USB drives            |
| Unattend Editor   | /unattend   | Edit Windows unattend.xml per image type       |
| startnet.cmd      | /startnet   | Edit startnet.cmd inside boot.wim (wimtools)   |
| Clonezilla Backups| /backups    | Upload/download/manage disk backup images      |
| Blancco Reports   | /reports    | View/download drive erasure reports            |
| Image Config      | /images/*/config | Per-image driver, OS, and hardware config |
| Enrollment        | /enrollment | GCCH bulk enrollment package management         |
| Audit Log         | /audit      | Activity history for all write operations      |

## Verification

1. Connect a test workstation to the isolated switch
2. Set Network Boot (PXE) as first boot in BIOS/UEFI
3. Boot — the client should pull an IP from 10.9.100.x
4. iPXE loads, fetches the boot script from port 4433
5. Select an option from the boot menu:
   - **Windows PE**: Boots via wimboot + boot.wim, maps Samba shares, begins deployment
   - **Clonezilla**: Boots Clonezilla Live for disk imaging
   - **Blancco**: Boots Drive Eraser, auto-saves reports to server
   - **Memtest86+**: Runs memory diagnostics

## Testing with KVM

```bash
# Download Ubuntu ISO
wget -O ~/Downloads/ubuntu-24.04.3-live-server-amd64.iso \
  https://releases.ubuntu.com/noble/ubuntu-24.04.3-live-server-amd64.iso

# Launch test VM
sudo ./test-vm.sh ~/Downloads/ubuntu-24.04.3-live-server-amd64.iso

# Watch progress (Ctrl+] to detach)
sudo virsh console pxe-test

# After install: ssh pxe@10.9.100.1 / http://10.9.100.1:9009

# Clean up
sudo ./test-vm.sh --destroy
```

## Project Structure

```
pxe-server/
├── autoinstall/
│   ├── user-data                 # Cloud-init autoinstall + first-boot script
│   └── meta-data                 # Cloud-init metadata (required, empty)
├── playbook/
│   ├── pxe_server_setup.yml      # Ansible: dnsmasq, Apache, Samba, iPXE, UFW, webapp
│   ├── 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/                   # CSS, JS, fonts, logo (all bundled offline)
│   └── templates/                # Jinja2 HTML templates (10 pages)
├── docs/
│   └── shopfloor-display-imaging-guide.md  # End-user imaging guide
├── boot-tools/                   # Extracted boot files (gitignored, built by prepare-boot-tools.sh)
│   ├── blancco/                  # Blancco Drive Eraser
│   ├── clonezilla/               # Clonezilla Live
│   └── memtest/                  # Memtest86+
├── 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 2-partition installer USB
│   ├── build-proxmox-iso.sh      # Builds self-contained Proxmox installer ISO
│   ├── prepare-boot-tools.sh     # Extracts/patches boot tools from ISOs
│   ├── download-packages.sh      # Downloads all offline packages
│   ├── download-drivers.py       # Downloads Dell drivers from dell.com
│   ├── deploy-bios.sh            # Pushes BIOS updates to enrollment share
│   ├── pull-bios.sh              # Pulls BIOS binaries from upstream cache
│   ├── 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                     # Project overview
└── SETUP.md                      # Detailed setup guide (this file)
```

## Image Types

| 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)        |

## Network Configuration

- PXE server static IP: `10.9.100.1/24`
- DHCP range: `10.9.100.10` - `10.9.100.100`
- Lease time: 12 hours
- DNS: `8.8.8.8` (passed to clients, not used by server)
- Firewall: UFW deny-by-default, allow 67/udp 69/udp 80/tcp 445/tcp 4433/tcp 9009/tcp

## 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 for the isolated network.
