Security
Malware cannot modify system files or persist across reboots
Comprehensive guide to the immutable Linux OS with atomic updates
Welcome to the ShaniOS technical documentation. This wiki provides comprehensive information about ShaniOS's architecture, installation, configuration, and daily use.
New to ShaniOS? Visit shani.dev for an introduction. This wiki focuses on technical implementation and usage details.
ShaniOS is an immutable Linux distribution that brings enterprise DevOps practices to desktop computing. Built on Arch Linux with Btrfs filesystem, it provides atomic updates, instant rollback, and system integrity by design.
Immutable systems protect core files from modification, ensuring reliability and security
ShaniOS comes fully equipped with a comprehensive software stack, carefully curated for desktop computing, development, gaming, and professional workloads. Everything works out of the box—no configuration required.
The primary user is automatically configured with appropriate permissions during installation.
ShaniOS includes extensive performance, gaming, and reliability optimizations out of the box, eliminating the need for manual tweaking. These enterprise-grade optimizations are pre-configured and active from first boot.
ShaniOS is optimized for gaming performance with multiple layers of system tuning:
Gaming Hardware Support:
Kernel-Level Gaming Optimizations:
madvise for selective large page usage, improving performance for games that explicitly request itShaniOS enables several system services for intelligent resource management:
realtime group receives permission to access HPET and RTC devices directly. This is essential for professional audio production, real-time multimedia applications, and low-latency gaming. Users in the realtime group can run applications with real-time scheduling priorities.ShaniOS enables comprehensive hardware support services by default:
ShaniOS provides a modern, feature-rich shell environment that rivals the best developer setups:
chsh while maintaining consistent functionality across all options.ShaniOS performs regular background maintenance to keep your system healthy without manual intervention. These systemd timers and services are enabled by default:
All maintenance operations are scheduled during low-usage periods and use minimal system resources to avoid impacting active work.
Note: All these optimizations are pre-configured and active from first boot. No manual configuration, tweaking, or performance tuning required. ShaniOS provides enterprise-grade optimization out of the box.
The root filesystem (/) is mounted read-only, preventing any modifications to system files. This ensures:
ShaniOS maintains two complete system images (@blue and @green). While one is active, updates are applied to the inactive one. On next boot, you switch to the updated system. If it fails, automatic rollback occurs.
Updates either succeed completely or fail safely—no partial updates that leave your system in a broken state. This is achieved through:
While the system is immutable, user data and configurations persist:
ShaniOS's immutability fundamentally changes how you interact with the system. Understanding this concept is key to using ShaniOS effectively.
Malware cannot modify system files or persist across reboots
Updates are atomic - they either work completely or fail safely
Instant recovery from failed updates or system issues
System state is always predictable and reproducible
ShaniOS implements blue-green deployment using Btrfs subvolumes—a strategy adapted from DevOps for desktop Linux.
Two complete system images with only one active at a time
ShaniOS uses an intelligent multi-layered update system with automatic checking, user notifications, and the shani-deploy tool for atomic system updates.
Zero-downtime update process with automatic rollback capability
ShaniOS selectively persists data across immutable system updates through bind mounts and dedicated subvolumes.
ShaniOS intelligently separates immutable system files from persistent user data
| Location | Type | Behavior |
|---|---|---|
| / | Read-only | Immutable system files |
| /etc | Overlay | Writable, persists in @data |
| /var | tmpfs | Volatile, cleared on reboot |
| /var/log | Btrfs @log | Persistent logs |
| /var/lib/* | Bind mount | Selective persistence from @data/varlib |
| /var/spool/* | Bind mount | Selective persistence from @data/varspool |
| /home | Btrfs @home | Persistent user data |
Critical service data is bind-mounted from @data subvolume:
# Example bind mounts from fstab
# Network configuration
/data/varlib/NetworkManager /var/lib/NetworkManager none bind,nofail 0 0
# Bluetooth pairings
/data/varlib/bluetooth /var/lib/bluetooth none bind,nofail 0 0
# systemd state
/data/varlib/systemd /var/lib/systemd none bind,nofail 0 0
ShaniOS intelligently handles bind mounts during configuration:
In addition to /var/lib, some /var/spool directories are also persisted:
| Component | Minimum | Recommended |
|---|---|---|
| Processor | x86_64 dual-core with VT-x/AMD-V | x86_64 quad-core or better |
| Memory | 4 GB RAM | 8 GB RAM or more |
| Storage | 32 GB (dual-image architecture) | 64 GB or more |
| Firmware | UEFI (required) | UEFI with TPM 2.0 |
| Installation Media | 8 GB USB drive | 16 GB USB 3.0 drive |
Why 32GB minimum? ShaniOS maintains two complete system images (@blue and @green) for atomic updates. However, Btrfs Copy-on-Write shares unchanged data between them, resulting in only ~18% overhead compared to traditional systems.
Configure your firmware before installation (typically accessed via F2, F10, Del, or Esc during startup):
Disable legacy/CSM mode. ShaniOS requires UEFI
Fast Boot can interfere with USB boot and Linux installation
Required for installation. Can be re-enabled after enrolling ShaniOS MOK keys
Ensures optimal disk performance and compatibility
Enable Intel VT-x or AMD-V for container support
Download the ShaniOS ISO from shani.dev and write it to USB:
Do Not Use Ventoy: Ventoy has known compatibility issues with ShaniOS's immutable architecture and will cause installation failures.
Installation takes approximately 10-15 minutes:
Press F12, F2, or Del during startup. Select your USB drive from the boot menu.
Choose the installation option from the boot menu
Select language, timezone, and keyboard layout
Choose target disk and partitioning scheme (automatic recommended)
Enable LUKS2 full-disk encryption. Recommended for laptops and portable systems.
The installer creates Btrfs subvolumes, installs the base system, and configures the bootloader
Remove USB drive when prompted and reboot into ShaniOS
On first boot, the Initial Setup wizard guides you through:
This approach keeps installation fast while personalizing the system on first use.
ShaniOS leverages advanced Btrfs features for immutability and efficiency.
Btrfs CoW minimizes storage duplication:
# Default mount options
compress=zstd,space_cache=v2,autodefrag
Specific subvolumes use nodatacow:
| Subvolume | Mount Options | Reason |
|---|---|---|
| @blue / @green | ro,noatime,compress=zstd,space_cache=v2,autodefrag | Read-only root with compression |
| @home, @data, @cache, @log | rw,noatime,compress=zstd,autodefrag,space_cache=v2 | Read-write with compression |
| @flatpak, @waydroid, @containers | rw,noatime,compress=zstd,autodefrag,space_cache=v2 | Application storage with compression |
| @machines, @lxc | rw,noatime,compress=zstd,autodefrag,space_cache=v2 | Container storage |
| @libvirt | rw,noatime,nodatacow,nospace_cache | VM performance (no CoW, no compression) |
| @swap | rw,noatime,nodatacow,nospace_cache | Swap file requirement (no CoW) |
All subvolumes use noatime to improve performance:
ShaniOS uses Btrfs with a sophisticated subvolume layout:
Organized subvolume layout separating system, user data, and services
| Subvolume | Mount Point | Purpose |
|---|---|---|
| @blue / @green | / | Root filesystems for blue-green deployment |
| @home | /home | User data and personal configurations |
| @data | /data | Overlay storage and persistent service data |
| @log | /var/log | System logs across reboots |
| @cache | /var/cache | Package manager cache |
| @flatpak | /var/lib/flatpak | Flatpak applications and runtimes |
| @waydroid | /var/lib/waydroid | Android system images and data |
| @containers | /var/lib/containers | Podman/Docker container storage |
| @machines | /var/lib/machines | systemd-nspawn containers |
| @lxc | /var/lib/lxc | LXC containers |
| @libvirt | /var/lib/libvirt | Virtual machine disk images (nodatacow) |
| @swap | /swap | Swap file container (nodatacow) |
OverlayFS enables writable /etc on read-only root.
# /etc overlay mount
overlay /etc overlay rw,lowerdir=/etc,upperdir=/data/overlay/etc/upper,workdir=/data/overlay/etc/work 0 0
Both /etc use overlay filesystems with this structure:
@data/overlay/etc/
├── lower/ # (unused, just structure)
├── upper/ # Your changes stored here
└── work/ # Overlay working directory
# List all overlay modifications
ls -la /data/overlay/etc/upper
# Compare with base system
diff -r /etc /data/overlay/etc/upper
Understanding how ShaniOS boots:
Six-stage boot process from firmware to desktop
Important Notes:
ShaniOS uses systemd-boot with Unified Kernel Images (UKI):
Boot menu entries clearly show system state:
After an update, the labels switch automatically.
ShaniOS creates a UEFI boot entry during installation:
The boot chain when Secure Boot is enabled:
UEFI Firmware
↓
shimx64.efi (signed by Microsoft, validates next stage)
↓
grubx64.efi (actually systemd-boot, signed by MOK)
↓
Unified Kernel Image (signed by MOK)
↓
Linux Kernel + Initramfs
ShaniOS uses these boot parameters:
quiet splash systemd.volatile=state ro
lsm=landlock,lockdown,yama,integrity,apparmor,bpf
rootfstype=btrfs
rootflags=subvol=@blue,ro,noatime,compress=zstd,space_cache=v2,autodefrag
root=/dev/mapper/shani_root # If encrypted
rd.luks.uuid=... rd.luks.name=... rd.luks.options=tpm2-device=auto # If TPM enrolled
resume=UUID=... resume_offset=... # If swapfile exists
Security-focused kernel parameters are enabled by default:
lsm=landlock,lockdown,yama,integrity,apparmor,bpf
This enables multiple Linux Security Modules for layered protection:
The systemd.volatile=state kernel parameter creates a tmpfs (RAM-based) overlay for /var, making it volatile by default:
# From kernel command line
systemd.volatile=state
# Result: /var is tmpfs, cleared on every reboot
# Only explicitly mounted subdirectories persist
ShaniOS automatically configures hibernation if a swapfile is created:
btrfs inspect-internal map-swapfileDisk Space for Swapfile: If available disk space is less than RAM size, swapfile creation is skipped and the system uses zram for swap instead. Hibernation will not be available in this case.
ShaniOS implements defense-in-depth security:
Read-only filesystem prevents malware from modifying system files
LUKS2 with argon2id protects data at rest
Flatpak provides application isolation and permission control
Mandatory access control confines system services
firewalld denies inbound connections by default
ShaniOS supports UEFI Secure Boot via Machine Owner Keys (MOK).
If you enabled Secure Boot during installation:
shaniosMOK (Machine Owner Key): This allows ShaniOS's signed bootloader and kernel to boot with Secure Boot enabled. The password "shanios" is only used during the one-time enrollment process and is not stored.
To enable Secure Boot after installation:
sudo mokutil --import /etc/secureboot/keys/MOK.der
Set a one-time password when prompted
MOK Manager appears on reboot. Select "Enroll MOK" and enter your password
Enter BIOS/UEFI settings and enable Secure Boot if still disabled
sudo mokutil --list-enrolled
Note: If MOK Manager doesn't appear, repeat step 1 and reboot. It only triggers when a key is pending enrollment.
Enroll your LUKS encryption key to TPM 2.0 for automatic unlocking.
Security Warning: Without Secure Boot, attackers with physical access can replace your bootloader to steal the encryption key. With Secure Boot, TPM refuses to unlock if the system is tampered with.
systemd-cryptenroll --tpm2-device=list
mokutil --sb-state
If disabled, consider enabling Secure Boot first
ShaniOS uses /dev/mapper/shani_root as the unlocked LUKS mapping. To find the underlying encrypted device:
# Get the physical encrypted device
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep 'device:' | awk '{print $2}')
echo "Your encrypted device is: $LUKS_DEVICE"
# Example output: /dev/sda2 or /dev/nvme0n1p2
With Secure Boot (recommended):
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep 'device:' | awk '{print $2}')
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 "$LUKS_DEVICE"
Without Secure Boot:
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep 'device:' | awk '{print $2}')
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0 "$LUKS_DEVICE"
Enter your LUKS password when prompted
Both @blue and @green must be updated:
sudo gen-efi configure blue
sudo gen-efi configure green
Reboot. System should unlock automatically.
# Verify enrollment
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep 'device:' | awk '{print $2}')
sudo cryptsetup luksDump "$LUKS_DEVICE" | grep systemd-tpm2
To restore password-only unlocking:
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep 'device:' | awk '{print $2}')
sudo systemd-cryptenroll --wipe-slot=tpm2 "$LUKS_DEVICE"
sudo gen-efi configure blue
sudo gen-efi configure green
If you enable Secure Boot after TPM enrollment:
# Get the device
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep 'device:' | awk '{print $2}')
# Remove old enrollment
sudo systemd-cryptenroll --wipe-slot=tpm2 "$LUKS_DEVICE"
# Re-enroll with Secure Boot protection
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 "$LUKS_DEVICE"
# Update boot images
sudo gen-efi configure blue
sudo gen-efi configure green
Important:
ShaniOS includes a background service that automatically checks for updates:
sudo shani-deploy
The update process includes:
Automatic Rollback: If the updated system fails to boot, ShaniOS automatically reverts to the previous working state on next startup. The boot-success marker system tracks successful boots.
ShaniOS supports multiple update channels:
Set your preferred channel:
# Choose channel
sudo shani-deploy -t latest
# Or set permanently
echo "latest" | sudo tee /etc/shani-channel
# Show help
sudo shani-deploy --help
# Force rollback to previous version
sudo shani-deploy --rollback
# Manual cleanup of old backups and downloads
sudo shani-deploy --cleanup
# Storage analysis with deduplication
sudo shani-deploy --storage-info
# Dry run (simulate without changes)
sudo shani-deploy --dry-run
# Verbose output for troubleshooting
sudo shani-deploy --verbose
# Update Flatpak applications
flatpak update
# Update firmware via LVFS
fwupdmgr refresh
fwupdmgr update
ShaniOS uses Flatpak as the primary application delivery method, with containers for development tools and system-level software.
Choose the right installation method for your needs
No pacman: Traditional package management via pacman is not supported. The base system is immutable. Use Flatpak, containers, or AppImages for applications.
# Search for applications
flatpak search keyword
# Install from Flathub
flatpak install flathub org.application.Name
# List installed apps
flatpak list
# Remove an app
flatpak uninstall org.application.Name
Game Launchers:
flatpak install flathub com.valvesoftware.Steam
flatpak install flathub com.heroicgameslauncher.hgl
flatpak install flathub net.lutris.Lutris
flatpak install flathub org.libretro.RetroArch
Gaming Peripherals:
flatpak install flathub io.github.antimicrox.antimicrox # Gamepad mapper
flatpak install flathub org.freedesktop.Piper # Mouse configuration
flatpak install flathub org.openrgb.OpenRGB # RGB lighting
Performance Tools:
flatpak install flathub io.github.benjamimgois.goverlay # Overlay manager
flatpak install flathub org.freedesktop.Platform.VulkanLayer.MangoHud
flatpak install flathub org.freedesktop.Platform.VulkanLayer.gamescope
Run Windows apps using Wine via Bottles:
flatpak install flathub com.usebottles.bottles
Distrobox (Recommended for CLI tools):
# Create Ubuntu environment
distrobox create --name ubuntu --image ubuntu:22.04
# Enter environment
distrobox enter ubuntu
# Inside container, install anything with apt
sudo apt update && sudo apt install build-essential nodejs python3
Podman (Docker-compatible):
# Run container
podman run -it --rm ubuntu:22.04 bash
# Docker Compose style
podman compose up -d
LXC System Containers:
lxc launch images:ubuntu/22.04 my-container
Waydroid is pre-installed. Launch from Applications menu and complete setup wizard.
The /etc directory uses overlay filesystem, allowing modifications:
# Edit system configuration
sudo nano /etc/some-config-file
# Changes are stored in /data/overlay/etc/upper
# and persist across system updates
ShaniOS lets you host websites and services directly from your desktop or laptop—even on home internet connections without a static IP. All tools listed here are installed for convenience and are not enabled or running by default.
Security First: These services are disabled by default. Only enable what you need, and always configure firewall rules appropriately. Never expose services publicly without understanding the security implications.
Two secure paths: 🌐 Public access via Cloudflared tunnel, 🔐 Private access via Tailscale VPN
Modern, lightweight web server with automatic HTTPS for hosting sites from your desktop. Caddy makes it easy to host personal websites, dashboards, or file servers. It is not active by default and runs only when you start and configure it.
Start Caddy:
sudo systemctl start caddy
sudo systemctl enable caddy # Auto-start on boot
Ideal for web-hosting directly from your desktop without needing a dedicated server.
Cloudflared creates an encrypted tunnel to Cloudflare, allowing public HTTPS access to services running on your desktop. It is disabled by default and requires manual setup.
Setup:
# Login to Cloudflare
cloudflared tunnel login
# Create tunnel
cloudflared tunnel create my-tunnel
# Configure tunnel (edit config file)
sudo nano ~/.cloudflared/config.yml
# Example config:
# tunnel: YOUR-TUNNEL-ID
# credentials-file: /home/USER/.cloudflared/YOUR-TUNNEL-ID.json
#
# ingress:
# - hostname: mysite.example.com
# service: http://localhost:8080
# - service: http_status:404
# Start tunnel
cloudflared tunnel run my-tunnel
# Enable as service
sudo cloudflared service install
sudo systemctl start cloudflared
sudo systemctl enable cloudflared
Firewall Configuration:
# Cloudflared creates OUTBOUND connections only
# No inbound ports need to be opened in firewall
# This is the security advantage of tunnels!
# Verify outbound connections are allowed (default)
sudo firewall-cmd --list-all
# If you have strict outbound rules, allow HTTPS
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload
Perfect for hosting websites on home connections or behind NAT/CGNAT, without exposing your real IP address or opening inbound firewall ports.
Security Advantage: Cloudflared tunnels are outbound-only connections, meaning you don't need to open any inbound ports in your firewall. This significantly reduces attack surface while still providing public HTTPS access.
Tailscale creates a private encrypted network between your devices using WireGuard. It is not active unless you sign in and enable it.
Setup:
# Start Tailscale
sudo systemctl start tailscaled
sudo systemctl enable tailscaled
# Login and connect
sudo tailscale up
# Check status
tailscale status
# Allow Tailscale in firewall (UDP 41641)
sudo firewall-cmd --add-port=41641/udp --permanent
sudo firewall-cmd --reload
Use it to access your hosted websites and services privately, without making them public on the internet.
Firewall Note: Tailscale works even without opening ports (NAT traversal), but opening UDP 41641 improves direct peer-to-peer connectivity.
OpenSSH provides industry-standard encrypted remote access and file transfer (SSH, SCP, SFTP). The SSH server is not enabled by default.
Enable SSH Server:
sudo systemctl start sshd
sudo systemctl enable sshd
# Configure (optional)
sudo nano /etc/ssh/sshd_config
# Restart after changes
sudo systemctl restart sshd
# Allow SSH through firewall (for local/Tailscale access)
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
Useful for managing your desktop-hosted websites locally, over Tailscale, or through secure tunnels.
Security Warning: Never expose SSH directly to the public internet. Use SSH over Tailscale, or tunnel it through Cloudflared. If you must expose SSH publicly, always use key-based authentication, disable password auth, change the default port, and enable Fail2ban.
Fail2ban monitors authentication logs and temporarily blocks abusive IP addresses using firewall rules. It is not enabled by default.
Enable Fail2ban:
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# Check status
sudo fail2ban-client status
# View SSH jail status
sudo fail2ban-client status sshd
Firewall Integration:
# Fail2ban automatically integrates with firewalld
# No manual firewall rules needed
# Verify Fail2ban can control firewall
sudo firewall-cmd --get-active-zones
sudo fail2ban-client status
# Check banned IPs
sudo firewall-cmd --direct --get-all-rules
Recommended when exposing services such as SSH or web applications to the public, adding an extra layer of protection against brute-force attacks.
How it works: Fail2ban monitors logs for failed login attempts and automatically adds temporary firewall rules to block attacking IP addresses. It integrates directly with firewalld—no manual configuration needed.
firewalld provides a dynamic firewall with zones and services to control inbound and outbound network traffic. It is active by default with restrictive rules.
Common Commands:
# Check status
sudo firewall-cmd --state
# List active rules
sudo firewall-cmd --list-all
# Open HTTP/HTTPS
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload
# Open custom port
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
Use it to restrict access to your hosted websites, SSH, and other services, ensuring that only allowed connections reach your desktop.
Security Best Practices:
sudo shani-deploysudo journalctl -u sshd and sudo journalctl -u caddyShaniOS should automatically rollback. If not:
TPM enrollment adds a new unlock method but preserves your password. If experiencing issues:
Check network connectivity:
# Test connectivity
ping -c 3 shani.dev
# Check NetworkManager
systemctl status NetworkManager
# Retry update
sudo shani-deploy
Try these steps:
# Update Flatpak
flatpak update
# Repair installation
flatpak repair
# Check permissions
flatpak override --show org.app.Name
# Reset all overrides for the app
flatpak override --reset org.app.Name
# Run from terminal to see errors
flatpak run org.app.Name
# Check GPU / graphics issues (common for Electron & games)
flatpak run --env=LIBGL_DEBUG=verbose org.app.Name
# Method 1: Check for active LUKS mapping
sudo cryptsetup status shani_root
# If encrypted, shows: "is active" with device info
# Method 2: Check for crypto_LUKS partitions
sudo blkid | grep crypto_LUKS
# Shows all LUKS encrypted partitions
# Method 3: Check mounted devices
mount | grep mapper
# If encrypted, shows: /dev/mapper/shani_root
# Method 4: List block devices with filesystem types
lsblk -f
# Look for TYPE="crypto_LUKS"
# If none of these show encryption, your system is NOT encrypted
# and you cannot use TPM enrollment
# Get your LUKS device
LUKS_DEVICE=$(sudo cryptsetup status shani_root | grep device: | awk '{print $2}')
# Remove TPM enrollment
sudo systemd-cryptenroll --wipe-slot=tpm2 "$LUKS_DEVICE"
# Regenerate boot images
sudo gen-efi configure blue
sudo gen-efi configure green
# Done - system will now require password on boot
No. The root filesystem is read-only and immutable by design. This is a core security and stability feature, not a limitation. Use Flatpak for GUI applications, and containers (Distrobox, Podman) for development tools and CLI utilities.
ShaniOS includes automatic boot failure detection. If the system fails to boot after an update, it automatically reverts to the previous working image on the next boot attempt. No manual intervention required.
Yes. ShaniOS uses a dedicated @swap subvolume with Copy-on-Write disabled, providing reliable hibernation on Btrfs. This approach solves the traditional Btrfs hibernation challenges.
The /etc directory uses overlay filesystem, making it writable despite the read-only root. Simply edit files in /etc normally—changes are stored in /data/overlay/etc/upper and persist across updates and blue-green switches.
ShaniOS maintains two complete system images (@blue and @green) for atomic updates. However, Btrfs Copy-on-Write shares unchanged data between them, resulting in only ~18% overhead. The benefit is zero-downtime updates and instant rollback capability.
No. ShaniOS requires UEFI firmware for features like Unified Kernel Images (UKIs), Secure Boot support, and the systemd-boot bootloader. Legacy BIOS is not supported.
Not recommended. Other operating systems may modify the bootloader or ESP partition, potentially breaking ShaniOS boot entries. For running other systems, use virtual machines (QEMU/KVM) or containers instead.
At the systemd-boot menu during startup, select the alternative boot entry. Both @blue and @green entries are always available, allowing instant rollback or testing.
ShaniOS is open-source and welcomes community contributions.