feat: add minimal Debian image build system with WireGuard-only networking

Add complete build infrastructure for football secure access system:
- Minimal Debian base with only IceWM and Remmina
- WireGuard-only networking with strict firewall (eth0 allows only WireGuard)
- All network traffic routed through mandatory VPN tunnel
- Secure Boot enforced for physical deployments
- Zero remote access - SSH, telnet disabled and blocked
- AppArmor, auditd, and fail2ban for security hardening

Build system generates both VM (qcow2) and physical (raw) images.
WireGuard endpoint IP and port configurable via build script variables.

Includes:
- Package list with minimal dependencies
- System hardening scripts
- WireGuard client and server configuration tools
- Comprehensive documentation (README.md, QUICKSTART.md)
- systemd services for firewall enforcement
- User environment with automatic IceWM startup

💘 Generated with Crush

Assisted-by: GLM-4.7 via Crush <crush@charm.land>
This commit is contained in:
Charles N Wyble
2026-01-13 12:11:18 -05:00
parent 230c4f2d3d
commit 17dcee7e52
21 changed files with 1403 additions and 2 deletions

127
config/harden.sh Executable file
View File

@@ -0,0 +1,127 @@
#!/bin/bash
# Post-installation hardening script for football system
# This script configures strict firewall with WireGuard-only access
# All traffic must go through WireGuard tunnel
set -e
echo "Hardening football system with WireGuard-only access..."
# Disable and remove all remote access services
systemctl disable ssh 2>/dev/null || true
systemctl disable sshd 2>/dev/null || true
systemctl disable telnet 2>/dev/null || true
systemctl disable rsh 2>/dev/null || true
# Mask services to prevent them from being started
systemctl mask ssh 2>/dev/null || true
systemctl mask sshd 2>/dev/null || true
systemctl mask telnet 2>/dev/null || true
systemctl mask rsh 2>/dev/null || true
# Remove remote access packages if any were installed
apt-get purge -y openssh-server telnetd rsh-server 2>/dev/null || true
# STRICT FIREWALL RULES - WireGuard ONLY
# Read WireGuard endpoint configuration
WG_ENDPOINT_IP="${WG_ENDPOINT_IP:-192.0.2.1}"
WG_ENDPOINT_PORT="${WG_ENDPOINT_PORT:-51820}"
echo "Configuring strict firewall: only WireGuard to $WG_ENDPOINT_IP:$WG_ENDPOINT_PORT allowed on eth0"
# Flush all existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Default policies - DROP everything
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow ONLY WireGuard on physical interface (eth0)
# Only UDP to WireGuard endpoint allowed
iptables -A OUTPUT -o eth0 -d $WG_ENDPOINT_IP -p udp --dport $WG_ENDPOINT_PORT -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -s $WG_ENDPOINT_IP -p udp --sport $WG_ENDPOINT_PORT -m state --state ESTABLISHED -j ACCEPT
# Allow all traffic through WireGuard interface (wg0)
iptables -A INPUT -i wg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT
# Allow DHCP on eth0 to get initial IP
iptables -A OUTPUT -o eth0 -p udp --dport 67 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p udp --sport 67 -m state --state ESTABLISHED -j ACCEPT
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
# Same strict rules for IPv6
ip6tables -F 2>/dev/null || true
ip6tables -X 2>/dev/null || true
ip6tables -P INPUT DROP 2>/dev/null || true
ip6tables -P FORWARD DROP 2>/dev/null || true
ip6tables -P OUTPUT DROP 2>/dev/null || true
ip6tables -A INPUT -i lo -j ACCEPT 2>/dev/null || true
ip6tables -A OUTPUT -o lo -j ACCEPT 2>/dev/null || true
ip6tables-save > /etc/iptables/rules.v6 2>/dev/null || true
# Configure network to reject incoming connections
echo "hardening football - disable remote access" > /etc/issue
echo "" >> /etc/issue
echo "No remote access is permitted on this system." >> /etc/issue
echo "Local console access only." >> /etc/issue
# Disable all network filesystem mounts
echo "disable network filesystem mounts" > /etc/modprobe.d/no-network-fs.conf
echo "install nfs /bin/true" >> /etc/modprobe.d/no-network-fs.conf
echo "install nfs4 /bin/true" >> /etc/modprobe.d/no-network-fs.conf
echo "install cifs /bin/true" >> /etc/modprobe.d/no-network-fs.conf
echo "install smbfs /bin/true" >> /etc/modprobe.d/no-network-fs.conf
# Secure SSH configuration (even though service is disabled)
mkdir -p /etc/ssh
cat > /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
PasswordAuthentication no
PermitRootLogin no
X11Forwarding no
AllowTcpForwarding no
GatewayPorts no
EOF
# Configure AppArmor to enforce
echo "Enforce AppArmor profiles" > /etc/apparmor.d/tunables/global.d/force_enforce
# Disable unnecessary kernel modules
echo "disable bluetooth" > /etc/modprobe.d/disable-bluetooth.conf
echo "install bluetooth /bin/true" >> /etc/modprobe.d/disable-bluetooth.conf
echo "install btusb /bin/true" >> /etc/modprobe.d/disable-bluetooth.conf
# Disable wireless if on wired-only system
echo "disable wireless" > /etc/modprobe.d/disable-wireless.conf
echo "install cfg80211 /bin/true" >> /etc/modprobe.d/disable-wireless.conf
echo "install mac80211 /bin/true" >> /etc/modprobe.d/disable-wireless.conf
# Disable unnecessary services
systemctl disable bluetooth 2>/dev/null || true
systemctl mask bluetooth 2>/dev/null || true
# Set secure umask
echo "umask 077" >> /etc/profile
echo "umask 077" >> /etc/bash.bashrc
# Disable core dumps
echo "* hard core 0" >> /etc/security/limits.conf
echo "* soft core 0" >> /etc/security/limits.conf
# Enable auditd
systemctl enable auditd 2>/dev/null || true
echo "Hardening complete - remote access disabled"

73
config/packages.list Normal file
View File

@@ -0,0 +1,73 @@
# Minimal packages for football secure access system
# Base system
linux-image-amd64
firmware-linux
firmware-linux-nonfree
grub2-common
grub-pc-bin
grub-efi-amd64-bin
grub-efi-ia32-bin
shim-signed
initramfs-tools
sudo
locales
keyboard-configuration
console-setup
# Network (client only, no server capabilities)
networkmanager
iproute2
iputils-ping
isc-dhcp-client
wireguard
wireguard-tools
iptables-persistent
# Hardware support
xserver-xorg
xserver-xorg-input-libinput
x11-xserver-utils
xterm
xinit
# Display manager (minimal - no remote access)
xserver-xorg-video-intel
xserver-xorg-video-amdgpu
xserver-xorg-video-nouveau
xserver-xorg-video-ati
# Window manager - IceWM
icewm
icewm-themes
# Remote desktop client - Remmina
remmina
remmina-plugin-rdp
remmina-plugin-vnc
# Basic utilities
vim-tiny
less
psmisc
procps
coreutils
grep
sed
gawk
tar
gzip
bzip2
xz-utils
curl
wget
# Secure boot and boot tools
efibootmgr
mokutil
efivar
# Security hardening
fail2ban
apparmor
apparmor-utils
auditd

24
config/preseed.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Debootstrap preseed configuration for minimal Debian installation
# Non-interactive frontend
export DEBIAN_FRONTEND=noninteractive
# Minimal base system without recommended packages
cat << 'EOF' > /usr/local/sbin/debootstrap-minimal
#!/bin/bash
# Arguments: SUITE TARGET MIRROR
set -e
SUITE=${1:-bookworm}
TARGET=${2}
MIRROR=${3:-http://deb.debian.org/debian}
echo "Bootstrapping minimal Debian $SUITE..."
debootstrap --variant=minbase --arch=amd64 $SUITE $TARGET $MIRROR
echo "Minimal bootstrap complete."
EOF
chmod +x /usr/local/sbin/debootstrap-minimal

74
config/secureboot.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
# Secure Boot configuration script for football system
# This script ensures Secure Boot is properly configured
set -e
echo "Configuring Secure Boot..."
# Check if Secure Boot is supported
if [ ! -d /sys/firmware/efi ]; then
echo "WARNING: EFI not detected. Secure Boot requires EFI system."
echo "This image may need to be deployed on a UEFI system with Secure Boot."
fi
# Install Secure Boot packages
apt-get update
apt-get install -y shim-signed grub-efi-amd64-signed
# Ensure GRUB is signed
echo "GRUB will use signed bootloader (shim-signed)"
# Configure kernel for Secure Boot
echo "Configuring kernel for Secure Boot..."
cat > /etc/default/grub.d/secureboot.cfg << 'EOF'
GRUB_DISABLE_OS_PROBER=true
GRUB_DISABLE_SUBMENU=y
EOF
# Lock GRUB to prevent unauthorized modifications
echo "Locking GRUB configuration..."
cat > /etc/grub.d/40_custom << 'EOF'
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.
# Lockdown: prevent editing GRUB entries
set superusers="football"
password_pbkdf2 football grub.pbkdf2.sha512.10000.$(echo -n "secure-boot-password" | grub-mkpasswd-pbkdf2 -s 2>/dev/null | tail -n +3 | sed 's/^.*grub\.pbkdf2\.sha512\.10000\.//')
EOF
chmod 755 /etc/grub.d/40_custom
# Update GRUB
update-grub 2>/dev/null || true
# Configure kernel command line for lockdown
echo "Configuring kernel lockdown mode..."
if [ -f /etc/default/grub ]; then
sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=""/GRUB_CMDLINE_LINUX_DEFAULT="lockdown=confidentiality,integrity"/' /etc/default/grub
sed -i 's/^GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="lockdown=confidentiality,integrity"/' /etc/default/grub
fi
# Enable UEFI Secure Boot verification in kernel
cat >> /etc/modprobe.d/secureboot.conf << 'EOF'
options efivarfs mode=0444
EOF
# Ensure kernel modules are signed
echo "Verifying kernel module signing..."
for module in /lib/modules/$(uname -r)/*.ko; do
if [ -f "$module" ]; then
sig=$(modinfo "$module" 2>/dev/null | grep -i "signature:" | wc -l)
if [ "$sig" -eq 0 ]; then
echo "WARNING: Module $module is not signed"
fi
fi
done 2>/dev/null || true
echo "Secure Boot configuration complete."
echo ""
echo "IMPORTANT: When deploying to physical hardware:"
echo "1. Ensure UEFI Secure Boot is ENABLED in BIOS/UEFI settings"
echo "2. Verify that the Microsoft UEFI CA is in the key database"
echo "3. The system will only boot with signed kernel and bootloader"
echo "4. Any unsigned kernel modules will be rejected"
echo ""

79
config/setup-wg-server.sh Executable file
View File

@@ -0,0 +1,79 @@
#!/bin/bash
# WireGuard server setup script
# This script helps set up the VPN server that football systems connect to
set -e
echo "============================================="
echo "WireGuard VPN Server Setup for Football"
echo "============================================="
echo ""
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# Install WireGuard
echo "Installing WireGuard..."
apt-get update
apt-get install -y wireguard wireguard-tools iptables-persistent
# Generate server keys
echo ""
echo "Generating server keys..."
SERVER_PRIVATE=$(wg genkey)
SERVER_PUBLIC=$(echo "$SERVER_PRIVATE" | wg pubkey)
echo "Server Public Key: $SERVER_PUBLIC"
echo "Server Private Key: $SERVER_PRIVATE"
# Create config directory
mkdir -p /etc/wireguard
# Create server configuration
cat > /etc/wireguard/wg0.conf << EOF
[Interface]
PrivateKey = $SERVER_PRIVATE
Address = 10.100.0.1/24
ListenPort = 51820
SaveConfig = true
# Enable IP forwarding
EOF
# Enable IP forwarding
echo "Enabling IP forwarding..."
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# Configure NAT
echo "Configuring NAT rules..."
iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o $(ip route | grep default | awk '{print $5}') -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
# Allow WireGuard port
iptables -A INPUT -p udp --dport 51820 -j ACCEPT
iptables-save > /etc/iptables/rules.v4
echo ""
echo "============================================="
echo "Server setup complete!"
echo "============================================="
echo ""
echo "Server Public Key: $SERVER_PUBLIC"
echo ""
echo "Next steps:"
echo "1. Add clients to /etc/wireguard/wg0.conf with their public keys"
echo "2. Enable the interface: systemctl enable wg-quick@wg0"
echo "3. Start the interface: systemctl start wg-quick@wg0"
echo "4. Configure firewall to allow UDP 51820"
echo ""
echo "Example client configuration:"
echo ""
echo "[Peer]"
echo "# Football Client 1"
echo "PublicKey = <CLIENT_PUBLIC_KEY>"
echo "AllowedIPs = 10.100.0.2/32"
echo ""

45
config/setup-wireguard.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# WireGuard configuration script for football system
# This script sets up WireGuard with provided keys
set -e
# Variables - these will be passed from build script
WG_ENDPOINT_IP="${WG_ENDPOINT_IP:-192.0.2.1}"
WG_ENDPOINT_PORT="${WG_ENDPOINT_PORT:-51820}"
WG_PRIVATE_KEY="${WG_PRIVATE_KEY}"
WG_PUBLIC_KEY="${WG_PUBLIC_KEY}"
if [ -z "$WG_PRIVATE_KEY" ] || [ -z "$WG_PUBLIC_KEY" ]; then
echo "ERROR: WireGuard keys not provided"
echo "Set WG_PRIVATE_KEY and WG_PUBLIC_KEY environment variables"
exit 1
fi
echo "Configuring WireGuard..."
# Replace placeholders in template
sed -e "s|<PRIVATE_KEY_PLACEHOLDER>|$WG_PRIVATE_KEY|g" \
-e "s|<PUBLIC_KEY_PLACEHOLDER>|$WG_PUBLIC_KEY|g" \
-e "s|<ENDPOINT_IP>|$WG_ENDPOINT_IP|g" \
-e "s|<ENDPOINT_PORT>|$WG_ENDPOINT_PORT|g" \
/etc/wireguard/wg0.conf.template > /etc/wireguard/wg0.conf
# Secure the configuration
chmod 600 /etc/wireguard/wg0.conf
# Enable and start WireGuard
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
# Verify connection
sleep 2
if ip link show wg0 >/dev/null 2>&1; then
echo "WireGuard interface wg0 is UP"
echo "All network traffic now routed through VPN"
else
echo "WARNING: WireGuard interface not detected"
exit 1
fi
echo "WireGuard configuration complete"

View File

@@ -0,0 +1,45 @@
# Sample WireGuard Server Configuration
# This is the configuration for the WireGuard VPN server
# that football systems will connect to.
#
# Usage: Copy this to /etc/wireguard/wg0.conf on the VPN server
# and adjust as needed for your environment.
[Interface]
# Private key of the VPN server
# Generate with: wg genkey
PrivateKey = <SERVER_PRIVATE_KEY>
# VPN network address (this server)
Address = 10.100.0.1/24
# Port to listen on (UDP)
ListenPort = 51820
# DNS for VPN clients
DNS = 10.100.0.1
# Enable IP forwarding on the server
# Add this to /etc/sysctl.conf: net.ipv4.ip_forward=1
# Then run: sysctl -p
# NAT configuration (POSTROUTING)
# iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE
[Peer]
# Client: football-1
# Public key generated on client with: wg pubkey < client-private.key
PublicKey = <CLIENT_1_PUBLIC_KEY>
AllowedIPs = 10.100.0.2/32
[Peer]
# Client: football-2
PublicKey = <CLIENT_2_PUBLIC_KEY>
AllowedIPs = 10.100.0.3/32
[Peer]
# Client: football-3
PublicKey = <CLIENT_3_PUBLIC_KEY>
AllowedIPs = 10.100.0.4/32
# Add more [Peer] sections as needed for additional football clients