Fedora Linux Enterprise Provisioning: SELinux Enforcing, Btrfs Subvolumes, Kickstart Automation & rpm-ostree
Executive Summary: Fedora Linux serves as the upstream engineering proving ground for Red Hat Enterprise Linux (RHEL), pioneering SELinux mandatory access control, systemd, PipeWire, Wayland, and immutable
rpm-ostree/ Bootable Containers (bootc). This architectural guide details the production installation of Fedora Server and Workstation, covering custom Anaconda Btrfs + LUKS2 storage layouts, automated zero-touch Kickstart (ks.cfg) deployments, DNF5 transaction rollbacks, and SELinux boolean/context verification.
-
SELinux Targeted Enforcing
Enforce kernel-level Mandatory Access Control (MAC) type enforcement (
system_u:object_r:httpd_sys_content_t:s0) from first boot. -
Zero-Touch Kickstart (
ks.cfg)
Automate bare-metal and KVM virtual machine provisioning with declarative partitioning, LUKS2 encryption, and post-install Ansible bootstrapping.
-
DNF5 & Transactional History
Leverage the C++-rewritten
dnf5package manager for ultra-fast dependency resolution and atomicdnf history rollbackrecovery. -
Btrfs & Atomic
bootcVariants
Deploy Copy-on-Write Btrfs filesystems with
zstd:1transparent compression or immutable OCI image-based Fedora Atomic hosts.
1. Architecture: Fedora Anaconda Storage & SELinux Security Model
Fedora distinguishes between two primary storage paradigms depending on the workload:
- Fedora Workstation / Cloud: Defaults to Btrfs with transparent
zstd:1compression (compress=zstd:1) and shared storage pools acrossrootandhomesubvolumes, eliminating wasted space from rigid partition boundaries. - Fedora Server: Defaults to XFS atop LVM, optimized for high-concurrency database I/O and online block-device expansion (
xfs_growfs).
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
subgraph BootChain["UEFI Secure Boot Chain"]
Shim["Signed Microsoft/Fedora shimx64.efi"]
GRUB["GRUB2 + BLS Entries<br/>(/boot/loader/entries/*.conf)"]
end
subgraph StorageLayer["LUKS2 Encrypted Storage Pool"]
Btrfs["Workstation: Btrfs Pool<br/>compress=zstd:1 (root + home)"]
LVMXFS["Server: LVM Volume Group<br/>XFS Logical Volumes + CockPit"]
end
subgraph SecurityLayer["Kernel Mandatory Access Control"]
SELinux["SELinux Enforcing Policy<br/>Type Enforcement + MCS Containers"]
Firewalld["firewalld (nftables Backend)<br/>Zone-Based Ingress Control"]
end
Shim --> GRUB
GRUB --> Btrfs
GRUB --> LVMXFS
Btrfs --> SELinux
LVMXFS --> SELinux
SELinux --> Firewalld
2. Media Verification & Boot Loader Specification (BLS)
Verify the downloaded Fedora ISO using sha256sum and Fedora's official GPG keys before writing it via Fedora Media Writer or dd:
curl -O https://fedoraproject.org/fedora.gpg
gpgv --keyring ./fedora.gpg Fedora-Server-41-1.4-x86_64-CHECKSUM
sha256sum --ignore-missing -c Fedora-Server-41-1.4-x86_64-CHECKSUM
3. Declarative Zero-Touch Provisioning via Anaconda Kickstart (ks.cfg)
Instead of clicking through the graphical Anaconda installer manually across multiple servers or KVM guests, host a declarative Kickstart file (inst.ks=https://pxe.lan.nejat-hakan.de/fedora-server.ks) that provisions UEFI, LUKS2, LVM/XFS, SELinux Enforcing, firewalld, and SSH keys automatically:
# Use text mode installation and reboot automatically upon completion
text
reboot
# Localization, Keyboard & Timezone
lang en_US.UTF-8
keyboard --vckeymap=de-nodeadkeys --xlayouts='de (nodeadkeys)'
timezone Europe/Berlin --utc
# Network & Firewall Configuration
network --bootproto=dhcp --device=link --activate --onboot=yes --hostname=fedora-node-01.lan.nejat-hakan.de
firewall --enabled --ssh --service=cockpit
# Enforce SELinux Mandatory Access Control
selinux --enforcing
# Disable root password login and provision unprivileged wheel administrator
rootpw --lock
user --name=nejat --groups=wheel --iscrypted --password=$6$rounds=656000$YourSHA512HashHere
sshkey --username=nejat "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... nejat@workstation"
# Disk Wiping, UEFI, and LUKS2 Encrypted LVM Layout
zerombr
clearpart --all --initlabel --disklabel=gpt
part /boot/efi --fstype="efi" --size=600 --fsoptions="umask=0077,shortname=winnt"
part /boot --fstype="xfs" --size=1024 --fsoptions="nodev,nosuid,noexec"
part pv.01 --fstype="lvmpv" --size=1 --grow --encrypted --luks-version=luks2 --pbkdf=argon2id --passphrase="InitialInstallPassphraseChangeViaTPM"
volgroup vg_fedora pv.01
logvol / --vgname=vg_fedora --name=lv_root --fstype="xfs" --size=30720
logvol /var --vgname=vg_fedora --name=lv_var --fstype="xfs" --size=40960 --fsoptions="nodev,nosuid"
logvol /var/log --vgname=vg_fedora --name=lv_log --fstype="xfs" --size=10240 --fsoptions="nodev,nosuid,noexec"
logvol /home --vgname=vg_fedora --name=lv_home --fstype="xfs" --size=10240 --fsoptions="nodev,nosuid"
%packages
@^server-product-environment
podman
cockpit-podman
cockpit-storaged
vim-enhanced
tmux
dnf-automatic
%end
%post --log=/root/ks-post.log
# Enable automatic security updates via dnf-automatic
sed -i 's/apply_updates = no/apply_updates = yes/' /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timer cockpit.socket
%end
4. Post-Install DNF5 Tuning, RPM Fusion & Firmware Updates (fwupd)
Fedora 41+ uses DNF5 natively—a complete C++ rewrite that eliminates Python runtime overhead and accelerates metadata synchronization. Configure DNF, enable LVFS hardware firmware updates (fwupdmgr), and inspect boot entries via grubby:
# 1. Perform full system upgrade with DNF5
sudo dnf upgrade --refresh -y
# 2. Check and apply UEFI BIOS / NVMe controller firmware updates via LVFS
sudo fwupdmgr refresh
sudo fwupdmgr get-updates
sudo fwupdmgr update
# 3. Inspect Boot Loader Specification (BLS) kernel entries via grubby
sudo grubby --info=ALL
# 4. Add a kernel parameter cleanly across all installed kernels via grubby
sudo grubby --update-kernel=ALL --args="iommu=pt"
5. Working with SELinux in Enforcing Mode (Never SELINUX=disabled)
Disabling SELinux in /etc/selinux/config removes Mandatory Access Control isolation between public-facing services (httpd_t, container_t) and host data. Instead, use semanage and setsebool to authorize custom ports, file paths, and service behaviors cleanly:
# 1. Verify SELinux is operating in Enforcing mode with the 'targeted' policy
sestatus
# 2. Allow Nginx/HTTPD reverse proxy to initiate outbound network connections to backend containers
sudo setsebool -P httpd_can_network_connect 1
# 3. Label a custom data directory (/srv/webapp) for read/write access by web servers and restore labels
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/srv/webapp(/.*)?"
sudo restorecon -Rv /srv/webapp
# 4. Diagnose any recent SELinux AVC denials in the systemd audit journal
sudo ausearch -m AVC,USER_AVC -ts recent