Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

Fedora Linux Automated Workstation Bootstrap

A fully unattended Fedora Linux installation system that takes a machine from a blank drive to a complete, personalised developer workstation — without a single manual step after booting the ISO.


Overview

Setting up a new Linux workstation typically means hours of manual work: partitioning drives, installing packages one by one, configuring repositories, hunting down drivers, and restoring personal files. This project eliminates all of that.

A single script downloads the latest Fedora installer, merges a complete installation recipe into it, and produces a bootable ISO. Boot from that ISO on any compatible machine and walk away — the system installs itself, configures everything, and is ready to use when it reboots.

This is useful for:

  • Rebuilding a workstation quickly after hardware failure
  • Provisioning multiple machines with an identical baseline
  • Ensuring a reproducible, documented system configuration

How It Works

The Two Components

unattend.ks — The Installation Recipe

A Kickstart file is a plain-text script that the Fedora installer (Anaconda) reads to answer every prompt that would otherwise require human input. It describes the entire system: disk layout, user accounts, locale settings, packages to install, and arbitrary shell commands to run after installation.

This file is intentionally safe to store in a public repository — all secrets (user password, fileshare credentials) are represented as placeholders that are substituted at build time, never committed.

build-iso.sh — The Build Script

A Bash script that orchestrates the build process. It:

  1. Prompts interactively for secrets (credentials and user password)
  2. Downloads the latest Fedora netinstall ISO automatically
  3. Performs a safe, in-memory substitution of secrets into a temporary copy of the kickstart file
  4. Uses mkksiso to embed the kickstart into the ISO so no boot parameters need to be set manually

Installation Flow

build-iso.sh
    │
    ├── Prompt for fileshare credentials (x2 confirm)
    ├── Prompt for user password (x2 confirm, converted to SHA-512 hash)
    ├── Detect latest Fedora version
    ├── Download Fedora-Everything-netinstall-x86_64-<ver>.iso
    ├── Inject secrets into a temporary kickstart copy
    └── mkksiso → fedora-kde.iso

        Boot fedora-kde.iso
            │
            ├── %pre   — Auto-detect target disk, write partition layout
            ├── Install — Pull packages from Fedora mirrors
            └── %post  — Configure everything (see below)

Prerequisites

To Build the ISO

Requirement Notes
Fedora Linux (or compatible) mkksiso is from the lorax package
lorax sudo dnf install lorax
openssl For hashing the user password; installed by default on most systems
curl For downloading the netinstall ISO
Internet access To fetch the ISO and detect the latest Fedora version

To Install from the ISO

Requirement Notes
x86_64 machine or VM Physical or virtual, UEFI firmware
20 GB+ disk space More recommended for development use
Internet access Installation pulls packages from Fedora mirrors

Quick Start

# Clone the repository
git clone https://github.com/SamScripting/bootstrap.git
cd bootstrap

# Build the ISO (prompts for all secrets interactively)
./build-iso.sh

# Optionally specify an output filename
./build-iso.sh my-workstation.iso

The script will ask for:

  1. Fileshare username — for fetching SSH keys during post-install
  2. Fileshare password — entered twice to confirm
  3. Password for user sam — entered twice to confirm; converted to a SHA-512 hash before being written anywhere

When the build completes, write the ISO to a USB drive or attach it as a VM boot image.

On Linux:

sudo dd if=fedora-kde.iso of=/dev/sdX bs=4M status=progress

Boot the target machine from the ISO. The installation is fully automatic — no prompts, no interaction required.


What Gets Installed

Desktop Environment

  • KDE Plasma — Full desktop environment (@^kde-desktop-environment)
  • Chromium — Web browser

Storage

Component Detail
EFI partition 600 MB, vfat
/boot 2 GB, ext4
Root + Home Remaining space, Btrfs with separate root and home subvolumes, zstd:1 compression
Swap Via zram — compressed RAM-based swap, no dedicated partition

The target disk is auto-detected at install time using lsblk, so the kickstart works regardless of whether the disk is /dev/sda, /dev/nvme0n1, or any other name.

Development Tools

Tool Description
git Version control
gh GitHub CLI
nodejs + npm JavaScript runtime and package manager
podman + podman-compose + podman-docker Rootless container runtime with Docker compatibility
rclone Cloud storage sync
Docker CE Full Docker engine, with the current user added to the docker group
Visual Studio Code Installed from Microsoft's official repository
PowerShell Cross-platform shell and scripting environment
Claude Code Anthropic's AI coding assistant (via npm)
Gemini CLI Google's AI assistant (via npm)

VS Code Extensions

Installed automatically for the sam user:

  • anthropic.claude-code
  • github.github-vscode-theme
  • google.geminicodeassist
  • mermaidchart.vscode-mermaid-chart
  • ms-python.python + ms-python.vscode-pylance + ms-python.debugpy + ms-python.vscode-python-envs
  • ms-vscode.powershell
  • redhat.vscode-yaml

Multimedia

RPM Fusion (free and non-free) repositories are added, then:

  • Full FFmpeg (swapped from the restricted ffmpeg-free)
  • Complete GStreamer plugin stack
  • H.264 support via Cisco's OpenH264 (Firefox video fix)
  • Hardware-accelerated video decode via VA-API

GPU Drivers (Auto-detected)

The installer detects the GPU vendor at post-install time using lspci and installs the appropriate stack:

Detected GPU What Gets Installed
AMD mesa-va-drivers-freeworld, mesa-vdpau-drivers-freeworld
Intel Same mesa freeworld drivers + intel-media-driver
NVIDIA Prerequisites (kernel-devel, libglvnd-*, etc.), akmod-nvidia, xorg-x11-drv-nvidia-cuda. RTX 4000+ series additionally sets the open kernel module flag.
VM / none detected Skips driver-specific packages gracefully

Flatpak Apps

Flathub is configured as the package source (replacing Fedora's limited default remote):

  • Telegram Desktop
  • Zoom
  • Gearlever (AppImage manager)

System Configuration

  • SELinux — enforcing
  • Firewall — enabled, SSH allowed
  • Root account — locked; sudo access via the sam user
  • AppImage supportfuse and fuse-libs installed
  • Btrfs toolsbtrfs-progs for filesystem management

Personal Configuration (Post-Install)

The installer clones a private backup repository from GitHub and restores:

  • .bashrc
  • SSH config and known_hosts (symlinked)
  • KDE Plasma configuration files (plasmashellrc, kwinrc, kdeglobals, etc.)
  • A Logitech receiver udev rule

SSH private and public keys (fedora, github, opnbackup) are fetched securely over HTTPS from a password-protected private fileshare and placed in ~/.ssh with correct permissions (600 for private keys, 644 for public keys).


Security Design

No Secrets in the Repository

The kickstart file committed to this repository contains only placeholders:

--password=CHANGEME_HASH          ← replaced by build-iso.sh at build time
KS_USER="CHANGEME"                ← replaced by build-iso.sh at build time
KS_PASS="CHANGEME"                ← replaced by build-iso.sh at build time

build-iso.sh performs the substitution into a mktemp temporary file, which is deleted automatically when the script exits (via trap). The real values are never written to disk in the repository directory.

Password Handling in the Build Script

  • Passwords are read with read -rsp (silent, no echo)
  • Each secret is confirmed by entering it twice
  • The user password is converted immediately to a SHA-512 hash with openssl passwd -6; the plaintext is unset from memory before any further work
  • Fileshare credentials are unset from memory immediately after the sed substitution
  • The escape_sed function ensures that special characters in passwords (&, \) cannot corrupt the substitution

On the Installed System

  • Root login is disabled (rootpw --lock)
  • The sam user has sudo access via the wheel group
  • SSH keys are stored with strict permissions and are not readable by other users
  • SELinux runs in enforcing mode

Customisation

Changing the Target User

Search for sam throughout unattend.ks and replace with your username. Key locations:

  • user --name=sam directive
  • usermod -aG docker sam
  • All /home/sam/ paths in %post

Adding or Removing Packages

The %packages section (near the top of unattend.ks) lists packages installed directly from Fedora's repositories. Additional packages installed from third-party sources are handled in the %post section.

Changing the Disk Layout

The %pre section auto-detects the first available disk and generates the partition directives. To modify the layout (sizes, filesystem types, number of subvolumes), edit the cat > /tmp/disk-setup.ks heredoc in %pre.

Targeting a Specific Fedora Version

By default, build-iso.sh detects and downloads the latest stable Fedora release, and the installation source uses $releasever to match whatever version is on the ISO. To pin to a specific version, set FEDORA_VER manually in build-iso.sh before the download step.


File Structure

bootstrap/
├── unattend.ks     # Kickstart installation recipe (safe for public repos)
├── build-iso.sh    # Build script: prompts for secrets, downloads ISO, builds output
└── README.md       # This file

Technical Reference

Installation Source

url --mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&arch=$basearch

$releasever and $basearch are Anaconda/DNF variables resolved at install time from the ISO's embedded RPM database — not shell variables. This ensures the correct package versions are pulled for whatever Fedora release is on the ISO.

Disk Auto-Detection

DISK=$(lsblk -dpno NAME,TYPE | awk '$2=="disk" && $1 !~ /zram/ { print $1; exit }')

Finds the first block device of type disk, excluding zram devices, and uses it as the installation target.

Password Hashing

openssl passwd -6 produces a SHA-512 crypt hash compatible with /etc/shadow and Anaconda's --iscrypted user directive. This replaces the deprecated Python crypt module.

RPM Fusion Installation

dnf install -y \
    https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \
    https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm

$(rpm -E %fedora) is the shell equivalent of $releasever, expanding to the Fedora version number at runtime. This ensures the correct RPM Fusion release package is fetched regardless of which Fedora version is being installed.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages