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:
127
config/harden.sh
Executable file
127
config/harden.sh
Executable 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
73
config/packages.list
Normal 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
24
config/preseed.sh
Executable 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
74
config/secureboot.sh
Executable 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
79
config/setup-wg-server.sh
Executable 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
45
config/setup-wireguard.sh
Executable 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"
|
||||
45
config/wg-server-config-example.conf
Normal file
45
config/wg-server-config-example.conf
Normal 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
|
||||
Reference in New Issue
Block a user