Production-grade shell script to download, verify, configure, build, and optionally install upstream vanilla Linux kernel Debian packages — fully automated, VM-aware, and security-hardened.
This script builds an upstream vanilla Linux kernel directly from kernel.org into Debian packages using the in-tree Kbuild target make bindeb-pkg. It handles the entire lifecycle — from downloading and cryptographically verifying the source tarball to configuring, compiling, packaging, and installing the resulting .deb files.
Designed for Debian, Ubuntu, Proxmox VE, and all Debian-based distributions.
- OpenPGP signature verification of kernel.org tarballs before extraction using WKD-imported developer keys (Torvalds, Kroah-Hartman, Levin)
- Hardened GPG invocation with
--no-auto-key-importand--no-auto-key-retrieveto prevent silent key injection - Debian certificate sanitization for vanilla upstream sources (
SYSTEM_TRUSTED_KEYS,SYSTEM_REVOCATION_KEYS,MODULE_SIG_KEY) - Input validation with regex-based kernel version checks to prevent path or command injection
- Strict Bash mode (
set -Eeuo pipefail) with ERR, INT, and TERM signal traps - Path canonicalization via
readlink -fto prevent symlink-based path traversal
- Isolated build directory per kernel version and timestamp — no cross-contamination between builds
- Flexible config seeding: seed from running kernel (
/boot/config-*),defconfig,localmodconfig, or none - Interactive and non-interactive modes:
menuconfig,nconfig,oldconfig,olddefconfig, or skip entirely - Debug info control: disabled by default to dramatically reduce build time and package size
- Parallel compilation with configurable job count (defaults to
nproc) - Custom versioning: set
LOCALVERSIONsuffix andKDEB_PKGVERSIONoverride - Release-candidate support: versions like
6.15-rc7automatically use kernel.org/testingdirectory
Automatically detects the hypervisor at runtime using systemd-detect-virt and DMI/SMBIOS data, then applies hypervisor-specific kernel configuration:
| Hypervisor | Detection | Kernel Options Enabled |
|---|---|---|
| KVM / QEMU / Proxmox | kvm, qemu, bochs, proxmox |
Full VirtIO stack: virtio-pci, virtio-blk, virtio-scsi, virtio-net, virtio-balloon, virtio-console, virtio-input, virtio-rng, virtio-crypto, virtio-vsock, virtio-fs, 9p, net-failover |
| VMware | vmware |
VMXNET3, PVSCSI, VMware Balloon, VMCI, VMCI vsock, vmwgfx, vmmouse |
| Generic VM | virtualbox, xen, microsoft |
HYPERVISOR_GUEST, PARAVIRT, PARAVIRT_CLOCK, HIGH_RES_TIMERS, PCI_MSI, VSOCKETS |
- Driver mode control: choose between loadable
moduleorbuiltinfor paravirtual drivers - Guest tools auto-install: optionally installs and enables
qemu-guest-agentoropen-vm-tools
- Smart package discovery from actual build artifacts (no fragile filename globs)
- Automatic dependency repair with
apt-get -f installfallback afterdpkg -i - GRUB bootloader refresh via
update-grubafter successful installation - Selective installation: install
linux-image+linux-headersby default, optionally includelinux-libc-dev - Safe cleanup: removes source tree and archives after build while preserving all generated
.debpackages
Validate all inputs, paths, and environment configuration without making any system changes:
sudo DRY_RUN=1 ./debian_kernel_build.sh 6.12.93- OS: Debian, Ubuntu, Proxmox VE, or any Debian-based distribution
- Shell: Bash 5.0+
- Privileges: Root access (
sudo) - Network: Internet access to download kernel sources from
cdn.kernel.org - Disk space: At least 20–30 GB free (kernel source + build artifacts)
- RAM: Minimum 2 GB, recommended 4 GB+ for parallel builds
All build dependencies are installed automatically by the script:
bcbinutilsbisonbuild-essentialca-certificatescpiodirmngrdpkg-devfakerootflexgitgnupgkmodlibelf-devlibncurses-devlibssl-devopensslpaxctlperlpython3wgetxz-utilszstdOptional:
dwarves(pahole) ·lz4·liblz4-tool
This guide walks you through the entire process. No prior kernel-building experience is required.
Open a terminal on your Debian-based system and run:
wget https://raw.githubusercontent.com/alsyundawy/DebianKernelBuild/master/debian_kernel_build.sh
chmod +x debian_kernel_build.shVisit kernel.org to find the latest stable version (e.g., 6.12.93). You can also use release candidates like 6.15-rc7.
Run the script with sudo and pass the kernel version as the argument:
sudo ./debian_kernel_build.sh 6.12.93The script will automatically:
- Install all required build dependencies via APT (you do not need to install anything manually)
- Detect your VM hypervisor (KVM, VMware, etc.) if you are running inside a virtual machine
- Install VM guest tools (qemu-guest-agent or open-vm-tools) when a supported hypervisor is detected
- Download the kernel source tarball from
cdn.kernel.orgover HTTPS - Verify the OpenPGP signature to ensure the source has not been tampered with
- Extract the source tree into an isolated, timestamped build directory
- Seed
.configfrom your currently running kernel (/boot/config-*) - Open
menuconfigfor you to review and customize kernel options — just save and exit when done - Sanitize the config (disable debug info, clear Debian cert paths, apply VM optimizations)
- Compile the kernel using all available CPU cores (
make -j$(nproc) bindeb-pkg) - Install the generated
.debpackages (linux-imageandlinux-headers) - Refresh the GRUB bootloader so the new kernel appears in the boot menu
- Clean up the source tree and archives (the
.debpackages are preserved)
sudo rebootAfter rebooting, confirm the new kernel is active:
uname -rYou should see the version you just built (e.g., 6.12.93).
# Standard interactive build with menuconfig
sudo ./debian_kernel_build.sh 6.12.93# Fully non-interactive build — ideal for CI pipelines or scripted deployments
sudo CONFIG_MODE=olddefconfig INSTALL_AFTER_BUILD=0 ./debian_kernel_build.sh 6.12.93# VMware guest with modular paravirtual drivers
sudo VM_GUEST_OPTIMIZE=vmware VM_DRIVER_MODE=module ./debian_kernel_build.sh 6.12.93
# KVM/Proxmox guest with built-in drivers and custom kernel suffix
sudo VM_GUEST_OPTIMIZE=kvm VM_DRIVER_MODE=builtin LOCALVERSION=-pvefast ./debian_kernel_build.sh 6.12.93# Build a release candidate kernel (automatically uses kernel.org /testing directory)
sudo ./debian_kernel_build.sh 6.15-rc7# Build packages but do not install them, and keep the source tree
sudo INSTALL_AFTER_BUILD=0 CLEANUP_SOURCE=0 ./debian_kernel_build.sh 6.12.93# Skip OpenPGP verification (use only for emergency testing)
sudo VERIFY_TARBALL=0 ./debian_kernel_build.sh 6.12.93
# Dry-run — validate inputs and environment without making any changes
sudo DRY_RUN=1 ./debian_kernel_build.sh 6.12.93
# Build with debug symbols enabled (for crash analysis, kgdb, BTF, SystemTap)
sudo DISABLE_DEBUG_INFO=0 ./debian_kernel_build.sh 6.12.93# Add a custom suffix to the kernel version string
sudo LOCALVERSION=-alsyundawy ./debian_kernel_build.sh 6.12.93
# Override the Debian package version
sudo KDEB_PKGVERSION=1.0-custom ./debian_kernel_build.sh 6.12.93All behavior is controlled through environment variables. Every option has a sensible default — you only need to set the ones you want to change.
| Variable | Default | Description |
|---|---|---|
KERNEL_WORKDIR |
/opt/linux |
Base directory for isolated build trees |
JOBS |
$(nproc) |
Number of parallel make jobs |
LOCALVERSION |
(empty) | Custom kernel version suffix (e.g., -alsyundawy) |
KDEB_PKGVERSION |
(empty) | Override the Debian package version string |
| Variable | Default | Description |
|---|---|---|
CONFIG_SEED |
running |
Initial .config source: running · defconfig · localmodconfig · none |
CONFIG_MODE |
menuconfig |
Configuration frontend: menuconfig · nconfig · oldconfig · olddefconfig · none |
DISABLE_DEBUG_INFO |
1 |
Disable CONFIG_DEBUG_INFO and BTF to reduce build time and size |
SANITIZE_DEBIAN_CERTS |
1 |
Clear Debian-specific certificate paths for vanilla sources |
| Variable | Default | Description |
|---|---|---|
VERIFY_TARBALL |
1 |
Verify OpenPGP signature of the kernel tarball before extraction |
GPG_AUTO_LOCATE_KEYS |
1 |
Auto-import kernel.org developer keys via WKD |
| Variable | Default | Description |
|---|---|---|
VM_GUEST_OPTIMIZE |
auto |
VM detection mode: auto · kvm · qemu · proxmox · vmware · generic · none |
VM_DRIVER_MODE |
module |
Paravirtual driver linkage: module (loadable) · builtin (compiled-in) |
INSTALL_VM_GUEST_TOOLS |
1 |
Auto-install qemu-guest-agent or open-vm-tools when a hypervisor is detected |
| Variable | Default | Description |
|---|---|---|
INSTALL_AFTER_BUILD |
1 |
Automatically install linux-image and linux-headers after build |
INSTALL_LIBC_DEV |
0 |
Also install linux-libc-dev from this build |
REFRESH_BOOTLOADER |
1 |
Run update-grub after successful package installation |
CLEANUP_SOURCE |
1 |
Remove source tree, tarball, and signature after build |
DRY_RUN |
0 |
Validate all inputs and environment without making any system changes |
┌─────────────────┐
│ Validate Input │ Version format, env vars, boolean checks
└────────┬────────┘
│
┌────────▼────────┐
│ Install Deps │ APT packages, optional tools (dwarves, lz4)
└────────┬────────┘
│
┌────────▼────────┐
│ Detect VM │ systemd-detect-virt + DMI/SMBIOS probing
└────────┬────────┘
│
┌────────▼────────┐
│ Guest Tools │ qemu-guest-agent / open-vm-tools (optional)
└────────┬────────┘
│
┌────────▼────────┐
│ Download │ wget from cdn.kernel.org (HTTPS, timeout, retries)
└────────┬────────┘
│
┌────────▼────────┐
│ Verify (GPG) │ OpenPGP signature via detached .tar.sign
└────────┬────────┘
│
┌────────▼────────┐
│ Extract │ tar -xf into isolated build directory
└────────┬────────┘
│
┌────────▼────────┐
│ Seed .config │ running kernel / defconfig / localmodconfig
└────────┬────────┘
│
┌────────▼────────┐
│ Config Frontend │ menuconfig / nconfig / oldconfig / olddefconfig
└────────┬────────┘
│
┌────────▼────────┐
│ Sanitize Config │ Certs, debug info, VM options, olddefconfig sync
└────────┬────────┘
│
┌────────▼────────┐
│ Build (bindeb) │ make -jN bindeb-pkg → .deb packages
└────────┬────────┘
│
┌────────▼────────┐
│ Install │ dpkg -i with auto dependency repair
└────────┬────────┘
│
┌────────▼────────┐
│ Cleanup │ Remove source, preserve .deb packages
└────────┬────────┘
│
┌────────▼────────┐
│ Summary │ List packages, boot notes, VM recommendations
└─────────────────┘
The custom kernel is installed as standard Debian packages. You can remove it at any time using APT:
# List all installed kernel packages
dpkg -l | grep linux-image
# Remove a specific kernel version
sudo apt remove --purge linux-image-6.12.93
sudo apt remove --purge linux-headers-6.12.93
# Update the bootloader to remove stale entries
sudo update-grub- Always verify the GRUB bootloader entry before rebooting production systems.
- The script does not run
kexecautomatically. Use a controlled reboot to activate the new kernel. - For Proxmox/QEMU VMs: configure VirtIO SCSI (or VirtIO Block) and VirtIO NIC on the hypervisor side for optimal performance with the built kernel.
- For VMware VMs: use VMXNET3 for networking and PVSCSI for high-I/O virtual disks.
- Debug symbols: set
DISABLE_DEBUG_INFO=0if you need crash analysis, kgdb, BTF, or SystemTap workflows. - Build time: a full kernel build typically takes 15–60 minutes depending on CPU speed, number of cores, and kernel configuration. Setting
CONFIG_MODE=olddefconfigandDISABLE_DEBUG_INFO=1(the default) produces the fastest builds.
This script adheres to professional shell scripting standards:
- ✅ ShellCheck compliant — zero warnings at
-S styleseverity level - ✅ Strict Bash mode —
set -Eeuo pipefailwith ERR, INT, and TERM traps - ✅ Locale-safe —
LC_ALL=Cfor reproducible text parsing across environments - ✅ Secure defaults — GPG verification, HTTPS-only downloads, path canonicalization
- ✅ Clean code — modular functions, descriptive logging, comprehensive input validation
- Performed a full end-to-end code audit covering logic, security, and ShellCheck compliance.
- Fixed ShellCheck SC2155: split local declaration and command substitution in
seed_kernel_configto avoid masking return values. - Hardened GPG invocation with
--no-auto-key-importto prevent silent key injection from untrusted sources during OpenPGP signature verification. - Added
wget --timeout=60and--tries=3to prevent indefinite hangs on slow or unreachable network endpoints during kernel tarball and signature downloads. - Fixed
on_errortrap exit code: when the ERR trap fires withexit_code=0(edge case in complex pipelines), the trap now defaults toexit 1to prevent silent success. - Restored ERR trap alongside
errexitinrun_localmodconfigby usingset -Eeinstead ofset -eto keep the error trap active after re-enabling strict mode. - Added INT and TERM signal traps for graceful cleanup of the temporary GPG home directory when the script is interrupted by Ctrl-C or system signals.
- Added
LC_ALL=Cexport early in initialization for reproducible text parsing across different locale environments during build operations. - Canonicalized
KERNEL_WORKDIRusingreadlink -f(when available) to resolve symbolic links and prevent path traversal issues in build directory setup. - Removed
wget -c(continue) flag from signature download to prevent partial or corrupt file reuse during OpenPGP verification. - Added
wget --no-hstsflag to avoid unnecessary HSTS database writes during kernel downloads.
- Audited the full script from start to finish after adding VM optimization.
- Fixed
localmodconfighandling so it remains safe undererrexitandpipefail. - Added
kmodandpython3to the required dependency set for modern kernel package builds. - Changed core VirtIO symbols to built-in enablement while keeping concrete device drivers controlled by
VM_DRIVER_MODE=module|builtin. - Added
VIRTIO_MENUandSCSI_LOWLEVELenablement to improve dependency resolution for VirtIO and VMware SCSI drivers. - Added optional
REFRESH_BOOTLOADER=1to refresh GRUB whenupdate-grubexists after successful package installation. - Added
DRY_RUN=1support for syntax, path, and argument validation without making system changes. - Kept security sane: no
mitigations=off, no unsafe kernel command-line tweaks, and no global scheduler or sysctl tuning.
- Added automatic VM guest detection for KVM/QEMU/Proxmox and VMware using
systemd-detect-virtand DMI/SMBIOS data. - Added safe VM-focused kernel configuration patching for responsiveness and lower virtual I/O overhead.
- Added VirtIO stack optimization for Proxmox/QEMU guests:
virtio-pci,virtio-blk,virtio-scsi,virtio-net,virtio-balloon,virtio-console,virtio-rng,virtio-vsock,virtio-fs,9pover virtio, andnet-failover. - Added VMware stack optimization:
vmxnet3,vmw_pvscsi,vmw_balloon,vmw_vmci, VMware VMCI vsock transport,vmwgfx, andvmmouse. - Added optional VM driver mode control through
VM_DRIVER_MODE=module|builtin. - Added optional runtime guest tools installation through
INSTALL_VM_GUEST_TOOLS.
- Kept the working structure from the previous corrected version.
- Converted all comments, usage text, log messages, warnings, and errors to English as requested.
- Added release-candidate URL handling: versions containing
-rcNuse the kernel.org/testingdirectory automatically. - Added stronger
KERNEL_WORKDIRvalidation to avoid accidental root-level or empty-directory operations. - Added
dirmngrto dependencies to improve GnuPG WKD/key discovery reliability. - Moved config sanitization after the selected config frontend so the final build config is always safe unless explicitly disabled by environment.
- Added a safe
localmodconfigpipeline wrapper compatible withpipefail. - Preserved generated
.debpackages while making cleanup path-scoped and safe.
- Added strict mode:
set -Eeuo pipefailand an ERR trap. - Added kernel version validation to prevent path or command injection.
- Added a broader Debian build dependency set:
flex,bison,dwarves/pahole,dpkg-dev,ca-certificates,gnupg,wget,zstd, andlz4fallback support. - Added OpenPGP verification for kernel.org tarballs before extraction.
- Replaced global
/opt/linuxcleanup with an isolated build directory per kernel version and timestamp. - Replaced fragile
dpkgfilename globs with package discovery from actual build artifacts. - Added environment-variable controls without removing the original workflow.
- Quoted all variable expansions and used array-safe
apt/dpkginvocation.
- 🌐 Website: alsyundawy.com
- 📧 Email: alsyundawy@gmail.com
- 💬 WhatsApp: +62 856-8515-1212
- 🐙 GitHub: github.com/alsyundawy
This project is licensed under the GNU General Public License. See the LICENSE file for details.