We layer on their OCI image as v0.7 base; we don't redistribute their source. Drop the AGPLv3-attribution prose — that becomes relevant only if/when we ship a verbatim chunk of their config/policy in our repo.
189 lines
9.1 KiB
Markdown
189 lines
9.1 KiB
Markdown
# veilor-os
|
|
|
|
> **Hardened minimal Fedora KDE spin. Black-on-black. Locked down by default.**
|
|
|
|
[](https://git.s8n.ru/veilor-org/veilor-os/actions?workflow=build-iso.yml)
|
|
[](LICENSE)
|
|
|
|
veilor-os is a Fedora 43 KDE Plasma remix for operators who want a clean,
|
|
fast, opinionated desktop with serious hardening already wired in. Boot the
|
|
ISO, set an admin password, work. No installer wizard. No initial-setup
|
|
screen. No telemetry. No "would you like to enable X" prompts.
|
|
|
|
The current install path is an Anaconda kickstart with a custom gum TUI
|
|
on top. v0.7+ ships a hybrid path: the kickstart ISO becomes the bootstrap
|
|
installer (Anaconda's LUKS UX is mature), but the root filesystem is
|
|
populated directly from a cosign-signed bootc OCI image built via BlueBuild
|
|
on top of [secureblue](https://github.com/secureblue/secureblue)'s
|
|
hardened Kinoite variant. Updates from there flow through `bootc upgrade`
|
|
— atomic A/B, instant rollback. v1.0 is bootc-only.
|
|
|
|
See [docs/STRATEGY.md](docs/STRATEGY.md) for the full trajectory.
|
|
|
|
---
|
|
|
|
## Status
|
|
|
|
Active development on the install path. Three bug classes have been
|
|
worked through (LUKS unlock cmdline, anaconda RPM-6.0 cmdline-mode
|
|
brittleness, bootloader install via `gen_grub_cfgstub`); current focus
|
|
is the v0.5.32 blocker list from the
|
|
[2026-05-05 9-agent research wave](docs/research/2026-05-05-agent-wave/README.md).
|
|
|
|
Primary git host: <https://git.s8n.ru/veilor-org/veilor-os>. The GitHub
|
|
mirror was disabled 2026-05-06; this repo is private-by-default on
|
|
Forgejo. ISO builds and CI artifacts are produced by the Forgejo runner
|
|
on nullstone — no GitHub Actions involvement.
|
|
|
|
What is **shipping**: hardening (SELinux, sysctl, USBGuard, fail2ban,
|
|
firewalld), KDE black theme, Fira Code system font, 3-mode power
|
|
management, single-prompt LUKS install, first-boot admin password flow,
|
|
reproducible CI build, EFI+BIOS bootable live ISO.
|
|
|
|
What is **planned** (see [docs/ROADMAP.md](docs/ROADMAP.md)): Plymouth
|
|
+ SDDM polish, signed ISOs (own MOK + GPG, sigstore/cosign on OCI),
|
|
AppArmor + nftables stack, `veilor-update` / `veilor-doctor` /
|
|
`veilor-postinstall` helpers, public docs site, **bootc OCI hybrid
|
|
spike at v0.7**, **bootc-only at v1.0**.
|
|
|
|
---
|
|
|
|
## Quick install
|
|
|
|
```bash
|
|
# 1. Download the ISO from the latest Forgejo release.
|
|
# https://git.s8n.ru/veilor-org/veilor-os/releases/tag/ci-latest
|
|
# (rolling tag; replaced on each successful build-iso.yml run)
|
|
sha256sum -c veilor-os-43-*.iso.sha256
|
|
|
|
# 2. Flash to USB. Replace /dev/sdX with your USB device — triple-check.
|
|
sudo dd if=veilor-os-43-*.iso of=/dev/sdX bs=4M status=progress conv=fsync
|
|
sync
|
|
|
|
# 3. Boot from USB, pick "Install veilor-os" from the menu.
|
|
# 4. Set a strong LUKS passphrase — the only prompt during install.
|
|
# 5. Reboot, remove USB.
|
|
# 6. On first boot: TTY prompts for an admin password (≥14 chars, mixed case,
|
|
# digit, symbol). Once accepted, SDDM starts. Log in as `admin`.
|
|
```
|
|
|
|
Full install + first-boot walkthrough: [docs/INSTALL.md](docs/INSTALL.md).
|
|
|
|
---
|
|
|
|
## What veilor-os ships
|
|
|
|
| Layer | Hardening |
|
|
|-------|-----------|
|
|
| Boot | Secure Boot, `lockdown=integrity`, `slab_nomerge`, `randomize_kstack_offset=on`, `vsyscall=none`. LUKS2 (aes-xts-plain64, argon2id, mem=1GB). zram swap (no disk swap, no cold-boot leak). |
|
|
| Kernel | Locked sysctls: ptrace=2, kptr_restrict=2, dmesg_restrict=1, perf_event_paranoid=3, BPF JIT hardening, full ASLR, no SUID core dumps. |
|
|
| MAC | SELinux **enforcing**, targeted policy + custom `veilor-systemd` module. |
|
|
| Network | firewalld zone = `drop`, ssh only inbound. systemd-resolved with DNS-over-TLS (Cloudflare/Quad9 fallback), LLMNR off. NTS-authenticated chrony time. |
|
|
| SSH | password auth off, root login off, single `admin` user, X11 forwarding off, MaxAuthTries 3. |
|
|
| Auth | root **locked**, single `admin` user with sudo. pwquality minlen=14, 4 character classes. First-boot password forced via `chage -d 0`. |
|
|
| Audit | `auditd` rules covering passwd/shadow/sudoers/ssh/cron/sysctl/kernel modules and all privileged binaries. |
|
|
| IDS | `fail2ban` with sshd + pam-generic jails, journal backend, firewalld rich-rule action. |
|
|
| USB | `USBGuard` daemon, **default-block**, empty allowlist on first boot. |
|
|
| Services off | `abrt*`, `cups`, `geoclue`, `avahi-daemon`, `bluetooth`, `ModemManager`, `gssproxy`, `atd`, `pcscd`, `kdeconnectd`, `PackageKit`. |
|
|
| UX | KDE Plasma minimal, `BreezeBlackPure` colour scheme, Fira Code system font, `veilor-power save \| mid \| perf` with udev AC/battery auto-switch. |
|
|
|
|
Full reference: [docs/HARDENING.md](docs/HARDENING.md).
|
|
|
|
---
|
|
|
|
## 60-second tour — what's different from stock Fedora KDE
|
|
|
|
- **No Anaconda Initial Setup** wizard after first boot. Single LUKS
|
|
passphrase prompt is the entire install interaction. Admin user is
|
|
pre-created; password is set once on TTY1, then SDDM starts.
|
|
- **Root is locked.** `passwd -S root` reports `L`. There is no `su -`
|
|
to root, ever. Use `sudo`.
|
|
- **No PackageKit, no Flatpak by default.** Updates happen with
|
|
`sudo dnf upgrade` on your terms, not in the background.
|
|
- **Default firewall zone is `drop`**, not `FedoraWorkstation`. The only
|
|
thing your machine answers is sshd on its assigned port.
|
|
- **USBGuard blocks every USB device by default.** First-boot procedure:
|
|
plug in everything you trust, run `usbguard generate-policy`,
|
|
done.
|
|
- **Black-on-black KDE.** Wallpaper, panel, Konsole all match. No "white
|
|
flash" anywhere in the session.
|
|
- **`veilor-power save | mid | perf`** swaps the full tuned profile,
|
|
CPU governor, EPP, battery threshold, and screen-dim policy in one
|
|
command. Wired to AC/battery udev events too — laptop drops to `save`
|
|
when unplugged automatically.
|
|
|
|
---
|
|
|
|
## How veilor-os compares
|
|
|
|
| Feature | veilor-os | Stock Fedora KDE | Kicksecure | secureblue |
|
|
|---|:-:|:-:|:-:|:-:|
|
|
| SELinux enforcing OOTB | yes | yes | yes | yes (custom policy) |
|
|
| AppArmor | deferred (post-v0.6 / v0.7 LSM stack) | no | yes | no |
|
|
| Secure Boot | yes (Fedora keys) | yes (Fedora keys) | configurable | yes (Fedora keys) |
|
|
| LUKS2 with argon2id | default | optional | default | default (Anaconda) |
|
|
| Single-prompt install (LUKS only) | yes | no | no | rebase via Anaconda |
|
|
| Root account locked by default | yes | no | yes | yes |
|
|
| firewalld default zone = drop | yes | no | n/a (nftables) | yes |
|
|
| USBGuard default-block | yes | no | yes | yes |
|
|
| fail2ban + auditd OOTB | yes | no | partial | partial (auditd) |
|
|
| DNS-over-TLS by default | yes | no | yes | yes |
|
|
| NTS-authenticated NTP | yes | no | yes | yes |
|
|
| `init_on_alloc/free` (post-install) | yes (planned re-enable) | no | yes | yes |
|
|
| Telemetry / phone-home | none | minimal | none | none |
|
|
| KDE Plasma branded theme | yes (black) | Breeze | n/a (XFCE) | upstream Kinoite |
|
|
| Power-profile CLI | yes (3-mode) | partial | no | no |
|
|
| Hardened browser (Trivalent / Mullvad) | yes (v0.6+) | no | no | yes (Trivalent shipped) |
|
|
| Atomic OCI image + signed base | v0.7 spike (BlueBuild) | no | no | yes (`bootc`) |
|
|
| Userns-remap default + module sig enforce | yes | no | partial | yes |
|
|
| Base distro | Fedora 43 (KDE) | Fedora 43 | Debian | Fedora atomic (Kinoite/Silverblue) |
|
|
|
|
veilor-os is **not** trying to compete with Whonix-style anonymity or
|
|
Qubes-style isolation. It is a **hardened daily-driver desktop** — fast,
|
|
clean, locked down, with no manual post-install hardening required.
|
|
|
|
### Relationship to secureblue
|
|
|
|
[secureblue](https://github.com/secureblue/secureblue) is an upstream
|
|
hardened atomic Fedora project we benchmark against and plan to **build
|
|
on top of** at v0.7. The v0.7 BlueBuild spike uses their
|
|
`securecore-kinoite-hardened-userns` OCI image as its base — we don't
|
|
ship their source code in this repo, we layer veilor branding,
|
|
theming, the gum installer, and the kickstart bootstrap on top of
|
|
their already-signed image.
|
|
|
|
Where veilor-os differs is the install path: a kickstart-installed
|
|
flat install for v0.5.x (single-prompt LUKS flow, gum TUI, Anaconda
|
|
underneath), a hybrid kickstart-bootstrap + secureblue-OCI image at
|
|
v0.7, and a fully OCI / `bootc upgrade` path at v1.0. Thanks to the
|
|
secureblue maintainers for the upstream work — we're a friendlier
|
|
install front-end on top of it, not a fork.
|
|
|
|
---
|
|
|
|
## Repo layout
|
|
|
|
```
|
|
kickstart/ veilor-os.ks full kickstart definition
|
|
build/ Containerfile + build-iso.sh reproducible ISO builder
|
|
overlay/ files dropped into installed root via %post
|
|
scripts/ hardening, SELinux policy, theme apply, firstboot
|
|
assets/ fonts, KDE colour scheme, branding, plymouth (planned)
|
|
docs/ BUILD / INSTALL / HARDENING / POWER / ROADMAP
|
|
test/ boot-checklist + KVM runner
|
|
.github/ CI workflows + PR template + CODEOWNERS
|
|
```
|
|
|
|
Build instructions: [docs/BUILD.md](docs/BUILD.md).
|
|
Roadmap: [docs/ROADMAP.md](docs/ROADMAP.md).
|
|
Contributing: [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
Changelog: [CHANGELOG.md](CHANGELOG.md).
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT — see [LICENSE](LICENSE). Fira Code ships from Fedora's
|
|
`fira-code-fonts` package under SIL OFL 1.1. Fedora packages remain
|
|
under their respective licences. Kickstart, overlay, scripts, and
|
|
docs in this repo are MIT.
|