Installation
sha256 e2a0601c016f31eac794627cfeb99cc16bf6763e591d0004bf6b7f8234d15d21
Installation
krypt/sh ships as a UEFI-bootable disk image
disk.img. Write it to a USB drive and boot it — you get a
live shell with networking, package tools, and everything needed to install
the system. Type setup-help at any time for a quick reference.
/etc/fstab is correct.
Write the image
Download: dl.krypt.sh/disk.img. For help, join #krypt/sh on Libera.Chat.
# verify checksum $ sha256sum disk.img e2a0601c016f31eac794627cfeb99cc16bf6763e591d0004bf6b7f8234d15d21 disk.img # write to USB $ dd if=disk.img of=/dev/sdX bs=4M status=progress
Boot the USB drive from your UEFI firmware. You will land at a root shell.
Network
# Ethernet starts automatically # WiFi (built-in Ralink/Realtek) # wpa_passphrase "SSID" "password" > /tmp/wpa.conf # wpa_supplicant -B -i wlan0 -c /tmp/wpa.conf # dhcpcd wlan0
Partition and mount
# fdisk /dev/sdX # Create a GPT label, an EFI system partition, and a root partition # mkfs.fat -F32 /dev/sdX1 # mkfs.ext4 /dev/sdX2 # mount /dev/sdX2 /mnt # mkdir -p /mnt/boot/efi # mount /dev/sdX1 /mnt/boot/efi
Install packages
# Create the filesystem skeleton # setup-filesystem /mnt # Install core system + build toolchain # install --target /mnt core devel
The install script fetches pre-built binary packages from
rsync://krypt.sh/bulk and installs them with
addpkg.
core — the base system (~57 packages):
devel — LLVM toolchain and build tools:
Generate fstab and chroot
# genfstab /mnt > /mnt/etc/fstab # cat /mnt/etc/fstab # enter-chroot /mnt
Configure the system
# passwd root # echo myhostname > /etc/hostname # ln -sf /usr/share/zoneinfo/Region/City /etc/localtime
Boot with EFISTUB
krypt/sh boots the kernel directly via UEFI — no bootloader required. Copy the kernel to the EFI system partition and create a boot entry:
# cp /boot/vmlinuz-X.Y.Z /boot/efi/vmlinuz-X.Y.Z.efi
# efibootmgr -c -d /dev/sdX -p 1 \
-L 'krypt/sh X.Y.Z' \
-l '\vmlinuz-X.Y.Z.efi' \
-u 'root=/dev/sdXn rw quiet net.ifnames=0'
/etc/fstab is correct, grub-mkconfig or
os-prober from the host system can detect and boot it.
Kernel
The kernel is installed as part of the linux group during
installation. The kernel image lands at /boot/vmlinuz-X.Y.Z
and modules go into /lib/modules/X.Y.Z.
Updating the kernel
After building or installing a new kernel version, copy it to the EFI system partition and create a new boot entry:
# cp /boot/vmlinuz-X.Y.Z /boot/efi/vmlinuz-X.Y.Z.efi
# efibootmgr -c -d /dev/sdX -p 1 \
-L 'krypt/sh X.Y.Z' \
-l '\vmlinuz-X.Y.Z.efi' \
-u 'root=/dev/sdXn rw quiet net.ifnames=0'
# Optionally remove old entries
# efibootmgr
# efibootmgr -b XXXX -B
Since krypt/sh uses EFISTUB directly, each kernel version gets its own EFI boot entry. You can keep multiple versions and select between them from the UEFI firmware boot menu — no bootloader configuration needed.
Building a custom kernel
krypt/sh ships a default kernel via the linux port, but
building a custom kernel is straightforward. Download the sources,
copy the running config as a starting point, and build with LLVM:
# cd /usr/src # tar xf linux-X.Y.Z.tar.xz # cd linux-X.Y.Z # Start from the running config # zcat /proc/config.gz > .config # make LLVM=1 olddefconfig # Customize # make LLVM=1 menuconfig # Build # make LLVM=1 -j$(nproc) # make LLVM=1 modules_install # cp arch/x86/boot/bzImage /boot/vmlinuz-X.Y.Z
clang, lld, and LLVM tools for the entire
build. This is the only supported method on krypt/sh since GCC is
not available.
Loading modules
krypt/sh boots without an initramfs — there is no dracut,
mkinitramfs, or initial ramdisk of any kind. The kernel
mounts the root filesystem directly. This means any kernel modules
your hardware needs at boot must either be compiled into the kernel
(=y) or loaded early from
/etc/rc.modules.
The /etc/rc.modules script is executed at boot and is
the place to modprobe drivers that are built as
modules (=m) rather than built-in. A typical setup:
#!/bin/sh modprobe iwlmvm modprobe iwlwifi modprobe amdgpu
chmod +x /etc/rc.modules.
If you add new hardware or enable new module-only drivers, add the
corresponding modprobe line here.
Since there is no initramfs, drivers that are critical for reaching
the root filesystem — your storage controller, filesystem driver,
and root disk encryption if used — must be built
into the kernel with =y, not as modules. If they are
only modules, the kernel cannot mount root and will panic. A safe
rule of thumb:
| Driver type | Recommendation |
|---|---|
| NVMe / AHCI / SCSI | Built-in (=y) — needed to mount root |
| ext4 / XFS / btrfs | Built-in (=y) — your root filesystem |
| dm-crypt / LUKS | Built-in (=y) — if using encryption |
| GPU (amdgpu, i915) | Module (=m) — loaded via rc.modules |
| WiFi (iwlwifi, ath) | Module (=m) — loaded via rc.modules |
| Bluetooth | Module (=m) — loaded via rc.modules |
| Sound (snd-hda) | Module (=m) — loaded via rc.modules |
| USB HID / input | Built-in (=y) — keyboard/mouse at boot |
To check what modules are currently loaded on a running system, use
lsmod. To see which module handles a specific device,
use lspci -k or lsusb -t.
EFISTUB configuration
krypt/sh boots the kernel directly from UEFI firmware without a bootloader. The following options must be enabled for EFISTUB to work:
# Required for EFISTUB boot CONFIG_EFI=y CONFIG_EFI_STUB=y CONFIG_EFI_MIXED=y # EFI filesystem access CONFIG_EFIVAR_FS=y CONFIG_EFI_VARS=y # EFI framebuffer (console before GPU driver loads) CONFIG_FB_EFI=y CONFIG_FRAMEBUFFER_CONSOLE=y # GPT partition table support CONFIG_EFI_PARTITION=y
Without CONFIG_EFI_STUB=y, the kernel image cannot be
loaded directly by the UEFI firmware and you would need a bootloader
like GRUB or systemd-boot. The EFI_MIXED option allows
a 64-bit kernel to boot on 32-bit EFI firmware, which some older
machines have.
Security & sandboxing
These options enable the kernel features that sandboxing tools, browsers (Firefox, Chromium), and container runtimes depend on. They are strongly recommended for any system running untrusted code:
# Seccomp — syscall filtering (required by browsers, containers) CONFIG_SECCOMP=y CONFIG_SECCOMP_FILTER=y # User namespaces — unprivileged sandboxing (Flatpak, Chromium) CONFIG_USER_NS=y # PID, network, mount namespaces — process isolation CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y # Landlock — unprivileged filesystem sandboxing (kernel 5.13+) CONFIG_SECURITY_LANDLOCK=y # Yama — ptrace scope restrictions CONFIG_SECURITY_YAMA=y # Kernel hardening CONFIG_RANDOMIZE_BASE=y CONFIG_RANDOMIZE_MEMORY=y CONFIG_STACKPROTECTOR=y CONFIG_STACKPROTECTOR_STRONG=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y
CONFIG_SECCOMP_FILTER=y is missing. This is the single
most important security option on a desktop system.
Cgroups & containers
If you plan to run containers, lightweight VMs, or resource-limited services, enable cgroups v2 and the relevant controllers:
# Cgroups v2 (unified hierarchy) CONFIG_CGROUPS=y CONFIG_CGROUP_V2=y # Resource controllers CONFIG_MEMCG=y CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_BPF=y # Overlay filesystem (container image layers) CONFIG_OVERLAY_FS=y # Virtual ethernet pairs (container networking) CONFIG_VETH=y CONFIG_BRIDGE=y CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
To boot with cgroups v2 as default, add
cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1
to your kernel command line in the efibootmgr -u
parameters. Since krypt/sh uses runit (not systemd), only the
cgroup_no_v1=all part is strictly needed.
Recommended options
Additional options that are good to have on a general-purpose krypt/sh system:
# /proc/config.gz — always have the running config available CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # tmpfs — used for /tmp, /run, build directories CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_XATTR=y # Devtmpfs — automatic /dev population CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # inotify — file watchers (build tools, editors, browsers) CONFIG_INOTIFY_USER=y # Multiqueue block IO — better SSD performance CONFIG_BLK_MQ_VIRTIO=y CONFIG_BLK_DEV_NVME=y # Kernel module compression (saves /lib/modules space) CONFIG_MODULE_COMPRESS_ZSTD=y # Magic SysRq — emergency debugging keys CONFIG_MAGIC_SYSRQ=y
make LLVM=1 olddefconfig to resolve any dependency
issues — some options automatically enable prerequisites.
Use scripts/diffconfig to see changes between two
.config files.
Encryption (LUKS2)
krypt/sh uses LUKS2 via cryptsetup for
full disk encryption. The stack is: cryptsetup →
device-mapper → argon2 (key derivation).
No initramfs — the kernel must have dm-crypt built in.
Setting up LUKS2
# Format a partition with LUKS2 + argon2id KDF # cryptsetup luksFormat --type luks2 --pbkdf argon2id /dev/nvme0n1p7 # Open the container # cryptsetup open /dev/nvme0n1p7 cryptroot # Format the plaintext device # mkfs.ext4 /dev/mapper/cryptroot # Mount and install as usual # mount /dev/mapper/cryptroot /mnt
Opening at boot
Without an initramfs, LUKS volumes must be opened by a boot script before the root filesystem is mounted — or, for non-root volumes, by a runit service early in the boot sequence.
#!/bin/sh cryptsetup open /dev/nvme0n1p7 whonix-gw cryptsetup open /dev/nvme0n1p8 whonix-ws cryptsetup open /dev/nvme0n1p9 fedora
CONFIG_DM_CRYPT=y built in — not as a module.
If dm-crypt is a module (=m), the kernel cannot open
the LUKS container before mounting root and will panic.
The example above prompts for a passphrase for each volume
separately. For systems with many encrypted partitions there is a
cleaner pattern: dedicate one small partition as a
keys partition. Open it with a single passphrase,
mount it, then open every other volume using a keyfile read from
inside it. Once all volumes are open, unmount and close the keys
partition. By the time runit stage 2 starts, the keys partition is
gone from the device mapper — no keyfiles are reachable from a
running shell, even as root. You type one password at boot and all
volumes open automatically from that point. The implementation
belongs in /etc/boot.d/ as a stage 1 script alongside
an /etc/crypttab that maps each volume name to its
device and keyfile path. Adapt the logic to your own partition
layout — do not copy it verbatim from any example.
Kernel requirements
# Device mapper core CONFIG_BLK_DEV_DM=y # dm-crypt — LUKS encryption CONFIG_DM_CRYPT=y # Crypto algorithms CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ARGON2=y