Turris OS and Upstream OpenWrt Feeds: The Case for a Leaner Package Model
TOS 9.1 Already Moved This Direction
Turris OS 9.1, released June 2026, already took a step here: CZ.NIC unfroze the upstream OpenWrt feeds for non-NG devices. Packages that don’t have a Turris-specific override now pull updates directly from upstream. It’s not the full picture yet, but it’s real movement.
The underlying question — why rebuild packages that are byte-for-byte identical to OpenWrt upstream? — is completely valid. The answer is partly build-system inertia, partly the kernel module problem (more on that below), and partly the practical need for a coherent snapshot of packages that all work together at any given release.
How Turris OS Package Management Works Today
Turris OS is built on top of OpenWrt, currently tracking OpenWrt 24.10. CZ.NIC maintains a separate package feed — turris-cz/os-packages on GitHub — that contains two kinds of things: genuinely Turris-specific packages (reForis, Turris Sentinel, Schnapps, board support for MOX and Omnia) and backports of upstream packages that needed Turris-specific patches or weren’t yet in the OpenWrt stable feed.
The build pipeline treats almost everything as needing a rebuild. Even packages identical to upstream get compiled as part of the Turris OS build, costing CI time and creating lag between when OpenWrt ships a fix and when a Turris user gets it.
The Kernel Module Problem
Here’s where “just point at upstream feeds” hits a wall. OpenWrt’s opkg enforces a kernel hash dependency for every kmod package. That hash is derived from the exact kernel build — compiler flags, patches, config options, all of it. If your kernel was compiled differently from the upstream build, opkg refuses to install upstream kmod packages with an error like cannot find dependency kernel (= [hash]).
Turris carries its own kernel patches for hardware-specific support — MOX’s Marvell Armada platform, Omnia’s board config — so the Turris kernel hash differs from vanilla upstream. That means kmod-usb-storage, kmod-wireguard, kmod-nft-*, and similar modules cannot simply be pulled from upstream OpenWrt package mirrors.
Non-kmod packages don’t have this restriction. LuCI plugins, application-layer packages, most of what users actually install — those can point at upstream feeds without issue. That’s where the quick wins are.
What the Turris Feed Actually Needs to Contain
A Turris-specific package feed doesn’t need to be large. The packages that genuinely must stay maintained by CZ.NIC are relatively few:
- reForis — the Turris web interface, with no upstream equivalent
- Turris Sentinel — the threat detection and honeypot system
- Schnapps — snapshot and rollback for Btrfs on Omnia
- Board-specific packages — MOX module detection, Omnia LED control, and similar
- pkgupdate — the Turris auto-update daemon that manages feed policy
- Kernel and kmod packages — must match the Turris kernel build exactly
Most other packages — network tools, LuCI plugins, DNS utilities, Python packages — could come straight from OpenWrt feeds. Knot Resolver, developed by CZ.NIC, is already available in upstream OpenWrt feeds.
Feed Priority in opkg
opkg determines priority from the order of src/gz entries in /etc/opkg/distfeeds.conf. Feeds listed first win when the same package name appears in multiple feeds. In practice the model looks like: Turris feed at priority 1, upstream OpenWrt feeds at priority 2. When Turris ships a custom build of a package, it takes precedence. When it doesn’t, opkg falls through to upstream automatically.
The Turris updater (pkgupdate) already supports a more complex policy model than plain opkg — it can pin specific packages to specific feeds and enforce version constraints. That machinery is already there. The open question is whether to stop including upstream-identical packages in the Turris build entirely, or just stop serving them from Turris CDN and rely on the fall-through.
The Upstream-First Development Argument
The second part of the suggestion — fix things upstream so both OpenWrt and Turris users benefit immediately — may matter more than the feed plumbing. CZ.NIC does contribute upstream: Turris kernel changes go back to OpenWrt, and CZ.NIC develops Knot DNS and Knot Resolver, both used well beyond Turris hardware. But package-level fixes often travel the one-way path of Turris-ships-then-maybe-reaches-upstream. Flipping that to upstream-first is as much a process change as a technical one.
For users, both approaches lead to the same place: fixes arrive faster, and CZ.NIC spends less effort on packages that upstream OpenWrt already handles well.
Sources
