#!/usr/bin/env bash # Setup network boot on the provisioning LXC: DHCP + TFTP on eth1, NAT so LAN uses eth0 for internet. # Run inside the LXC (as root), or from your machine: ./setup-network-boot-on-lxc.sh root@10.130.60.141 # When run with ssh target, rsyncs lxc/ and runs this script inside the container. set -e TARGET="${1:-}" if [[ -n "$TARGET" ]]; then # Run remotely: sync lxc/ and script, then execute inside LXC SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$(dirname "$SCRIPT_DIR")" echo "Syncing lxc config and script to $TARGET ..." rsync -a "$REPO_DIR/lxc/" "$TARGET:/tmp/cm4-network-boot-lxc/" --exclude='.git' scp "$SCRIPT_DIR/setup-network-boot-on-lxc.sh" "$TARGET:/tmp/cm4-network-boot-lxc/setup.sh" ssh "$TARGET" "bash /tmp/cm4-network-boot-lxc/setup.sh" echo "Done. Next: ensure /srv/tftpboot has RPi boot files (see docs/NETWORK-BOOT-LXC.md)." exit 0 fi # --- Running inside the LXC from here --- echo "Configuring network boot (DHCP + TFTP on eth1, NAT via eth0) ..." # 1) Install dnsmasq if ! command -v dnsmasq >/dev/null 2>&1; then apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq dnsmasq fi # 2) dnsmasq config for eth1 only (DHCP + TFTP) mkdir -p /etc/dnsmasq.d cat > /etc/dnsmasq.d/network-boot.conf << 'DNSMASQ' # DHCP + TFTP on eth1 only (provisioning LAN) interface=eth1 bind-interfaces dhcp-range=10.20.50.100,10.20.50.200,12h enable-tftp tftp-root=/srv/tftpboot dhcp-option=66,10.20.50.1 dhcp-option=67,start4cd.elf log-dhcp log-queries port=0 DNSMASQ # 3) TFTP root and minimal placeholder so TFTP serves something mkdir -p /srv/tftpboot if [[ ! -f /srv/tftpboot/start4cd.elf ]]; then echo "TFTP root /srv/tftpboot is empty. You need Raspberry Pi 4 boot files (start4cd.elf, fixup4cd.dat, config.txt, cmdline.txt, kernel8.img)." echo "Download from: https://github.com/raspberrypi/firmware/ (branch master, boot/ folder) and copy into /srv/tftpboot" echo "Or from a Pi: scp -r pi@:/boot/firmware/* root@:/srv/tftpboot/" fi # 4) IP forwarding (LAN clients use WAN) echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-cm4-network-boot.conf sysctl -p /etc/sysctl.d/99-cm4-network-boot.conf 2>/dev/null || sysctl -w net.ipv4.ip_forward=1 # 5) NAT: 10.20.50.0/24 -> eth0 (masquerade) if command -v nft >/dev/null 2>&1; then mkdir -p /etc/nftables.d cat > /etc/nftables.d/nat-lan.conf << 'NFT' table ip nat { chain postrouting { type nat hook postrouting priority srcnat; policy accept; ip saddr 10.20.50.0/24 oifname "eth0" masquerade } } NFT if ! nft list table ip nat 2>/dev/null | grep -q postrouting; then nft -f /etc/nftables.d/nat-lan.conf fi # Ensure main config includes our drop-in (Debian) if [[ -f /etc/nftables.conf ]] && ! grep -q 'nftables.d/nat-lan' /etc/nftables.conf 2>/dev/null; then echo 'include "/etc/nftables.d/nat-lan.conf"' >> /etc/nftables.conf fi echo "NAT rule added (nftables) and saved to /etc/nftables.d/nat-lan.conf" else # Fallback iptables iptables -t nat -C POSTROUTING -s 10.20.50.0/24 -o eth0 -j MASQUERADE 2>/dev/null || \ iptables -t nat -A POSTROUTING -s 10.20.50.0/24 -o eth0 -j MASQUERADE echo "NAT rule added (iptables)." fi # 6) Enable and start dnsmasq systemctl enable dnsmasq systemctl restart dnsmasq echo "Network boot setup done." echo " - DHCP + TFTP on eth1 (10.20.50.1), range 10.20.50.100-200" echo " - NAT: 10.20.50.0/24 -> eth0 (internet)" echo " - Put RPi 4 boot files in /srv/tftpboot (see above or docs/NETWORK-BOOT-LXC.md)"