Name Keel in apt and dpkg, and stop leaking the appliance identity #8
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Keel-Linux/common!8
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/keel-apt-identity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three of the four ways a Keel appliance still reported to TurnKey. The
fourth, the apt suites themselves, is measured here and deliberately not
touched: see "What this does not do".
Closes #6.
The dpkg vendor
/etc/dpkg/origins/defaultresolved to aTurnKeyfile, sodpkg-vendoranswered TurnKey and every bug reporting tool on the appliance addressed
turnkeylinux/tracker. The overlay now ships aKeelfile and no TurnKeyone, and
conf/turnkey.d/dpkg-vendorpointsdefaultat it.Parent: Debianis kept. That matters: there is noDpkg::Vendor::Keelperl module, so
dpkg-parsechangeloganddpkg-buildpackagefall back tothe parent's vendor object, which is the same
Dpkg::Vendor::Debiantheygot through TurnKey before. Package building is unaffected.
How it is asserted. Not by reading back the symlink the script wrote.
tests/dpkg-vendor.batsarranges the origins tree the overlay ships, runsthe conf script, and then asks the real
dpkg-vendorwhat it makes ofit, through dpkg's own
DPKG_ORIGINS_DIR(Dpkg::Vendorhonours it):--query VendoranswersKeel,--query Bugsanswers our tracker,--is TurnKeyfails,--is Keelsucceeds,--derives-from Debiansucceeds and
--derives-from Ubuntufails. The upgrade path is coveredtoo: a
defaultinherited as a symlink to TurnKey, as a regular file, andas a directory are each replaced, and the vendor query is what says so.
The apt User-Agent
mk/turnkey.mkandmk/turnkey-desktop.mkeach wrote a per-appliance/etc/apt/apt.conf.d/01turnkey:so
deb.debian.org,security.debian.org, every mirror in between andanyone watching the connection were told which appliance this machine is
and which version it runs, on every apt run it ever made.
It is now a fixed file the overlay ships,
01keel, naming the distributionand nothing else. Measured: apt's https method reads the same
Acquire::http::User-Agent, so one line covers both schemes.conf/turnkey.d/apt-identityexists for a reason worth stating. apt readsapt.conf.din lexical order and the last assignment of a scalar wins, soa
01turnkeyinherited from a parent layer built before this changesilently beats the
01keelbeside it:The script removes it, and refuses if
01keelis not there.How it is asserted. Off the wire.
tests/ua-recorder.pyis a localserver that records the
User-Agentheader of every request; a realapt-get updateis pointed at it and the test reads what apt actuallysent, over http and over TLS. So the verdict is apt's behaviour, not the
file's content. One test drives the stale-
01turnkeyhazard both ways: itmeasures TurnKey's header going out, runs the conf script, and measures
Keel's.
The strings the old header leaked each have their own refutation: the
sent header contains no
(, noTurnKey, noturnkey, nowordpress,no
trixie, noamd64and no19.0.https on the TurnKey archive
It is available. Measured 2026-09-28:
ssl_verify=0is a certificate that verifies against the system truststore.
trixie-securityandtrixie-testinganswer 200 over https aswell. So all six places
conf/bootstrap_aptwrotehttp://archive.turnkeylinux.org(the three deb822 stanzas and the threelegacy
sources.listlines still written for pre-Trixie releases) move tohttps.
The Debian sources beside them stay on http in this change, for one reason: that is Debian's own default and the payload is signed either way. (An earlier version of this description also said the build host's caching proxy only feeds http; it does not, squid there bumps https too, so that is not a reason.) The request stream over http still tells the path which packages at which versions an appliance fetches, the same confidentiality question the User-Agent change answers, so flipping the Debian URIs is worth its own change and is recorded in #7.
How it is asserted. The test extracts the heredoc bodies from
conf/bootstrap_aptitself, renders them with a build's variables, so thebytes under test are the generator's own output, not a copy in the test;
writes them into a scratch apt tree and asks apt with
apt-get indextargetswhich URIs it would fetch. No network. The verdictis apt's resolution of our sources: nothing under
http://archive.turnkeylinux.org, and all three suites present underhttps://. The Debian URIs are asserted unchanged so the scope of thechange is visible in the suite.
What this does not do
It does not remove the TurnKey apt suites. The measurement #6 asked
for is done and it says the suites are load bearing:
webminalone is 103 of them). Measured on thewordpress-democontainer (which never went through the container patch): 39 installed packages have their apt candidate in the TurnKey archive (41 of the 141 names are installed;confconsoleandinithooksare the other two, served byarchive.keellinux.orgat 1001). The count is per appliance: onforumit is 32. None is available from Debian at all.apt-cache policyover every installed package finds 0 where theTurnKey archive overrides Debian today.
trixie-testingisEnabled: noon a built appliance, so two suites areenabled, not three.
trixie-securityfrom TurnKey carries exactly one package,tklbam,at the version already installed.
/etc/apt/preferencespinningo=turnkeylinuxat 999,above Debian's 500, from
overlays/bootstrap_apt/etc/apt/preferences.It shadows nothing today; it would the day a name collides. Removing it is a change to how every appliance resolves packages, so by BRIEF section 12 (preserve upstream behaviour when in doubt) it goes with the migration in #7 rather than riding here.
Of the 39: 7 are appliance infrastructure that must move to our pool,
7 are TurnKey Hub clients that should be dropped, 1
(
turnkey-keys) goes with the sources it exists to verify, and 24 arewebminand its modules, which is a product decision before it is apackaging one. Full table and plan per package: #7.
Removing a source the build still needs is worse than leaving it, so that
is a separate change.
Overlap with #5, and how to resolve it
This touches lines #5 also touches. #5 was read before these edits.
Trial-merged locally; three files conflict and every resolution is
mechanical. I have run the merged tree.
mk/turnkey.mk: the real one. #5 replaces the version-string lineswith a
keel-version-filescall; this removes the twoturnkey_aptconflines beside them. Take #5's call and drop the User-Agent lines:
#5's
turnkey_version=$$(cat .../etc/turnkey_version)goes too; it onlyexisted to build the header this deletes.
tests/coverage.sh: both branches replace the single-target scriptwith the same per-target loop. This branch deliberately uses #5's exact
loop so the resolution is a union of the
targetsarrays, fiveentries, nothing else.
COVERAGE.md: both add a table and prose; keep both.Merged tree measured, all five files at 100 percent:
postfix-local17/17,dpkg-vendor6/6,apt-identity4/4,version-files.sh15/15,keel-version-files36/36.Whichever merges first, the other rebases. Happy either way.
One thing #5 does not do and this does:
mk/turnkey-desktop.mkis asecond copy of the same
root.patched/postblock. #5 changes onlymk/turnkey.mk, so desktop appliances would keep writing the old headerand would not get
/etc/keel_version. This fixes the header in both; thekeel_versiongap in the desktop makefile is #5's to close and is nottouched here.
Tests
33 bats, all three measured files at 100 percent under kcov 43 with
bats 1.11, the threshold the gate is set to:
Both refusals of each new conf script are covered, which is every non-zero
exit either can produce.
Each assertion was mutation-checked rather than assumed: reverting one
deb822 URI to http fails tests 8 and 9; reverting the legacy line fails
test 11; setting
Vendor: TurnKeyfails 9 of the vendor tests; restoringthe leaking User-Agent fails 4 of the apt tests.
A defect this uncovered
A bare
! cmdin a bats test body asserts nothing. Bash does not applyerrexit to a negated command, so the test passes whatever happens and
execution continues. Measured:
Both new suites use
run ! cmdwithbats_require_minimum_version 1.5.0.tests/postfix-local.batshas three bare ones (lines 66, 96, 97), of which only line 96 is inert (the other two are last in their tests, and bats takes the last status as the verdict); they are left alone here so this diff stays on itsown subject, and are recorded in
COVERAGE.md. It is the same family asthe
docs/traps.mdentry "A bats suite cannot see a library that kills itscaller".
Test plan
COVERAGE_THRESHOLD=100 tests/coverage.sh: three files, all 100 percentshellcheck -S warningclean on every file this adds or changesarchive.turnkeylinux.orgmeasured before the scheme was changedapt-get update, http and TLSdpkg-vendor01keelin the image,no
01turnkey, anddpkg-vendor --query Vendoranswering Keel on abooted appliance. Not run: the build host's
core.tar.zstis in aknown-inconsistent state and a repair is pending, so the build lock
was deliberately not taken.
appliance / build-and-bootboots the layer the mirror already serves, notthis branch, so it cannot prove a change to the core layer either way
(Keel-Linux/.github#11).
Related
boot page, and with it the only reader of the
01turnkeythis deletes(
29tagidparsed the build tag out of that User-Agent).bin/secalerts.shreads the same file but is guarded and falls back toturnkey-version; measured that it survives the file's removal.Org-wide context: Keel-Linux/tracker#15.
Review of
fix/keel-apt-identity. Findings ordered by severity, each says whether I got it by running something or by reading. No CRITICAL and no HIGH.The measurement, re-derived rather than accepted
Run read-only with
lxc-attachon the build host, on two containers, because the numbers decide how urgent the rest of the migration is.turnkey-testing.sourcesisEnabled: noon both containersPackage:across trixiebinary-amd64+binary-allandtrixie-securitybinary-amd64deck) exists in Debian trixie, and it is not installedapt-cache policyover every installed package finds 0 where TurnKey overrides Debianwordpress-demo, 0 of 814 onforumtrixie-securitycarries exactly one package,tklbam, at the installed version1.5.3+2+g31134d3, candidate the same, fromtrixie-securitySo the conclusion stands: the suites are load bearing and removing them today would remove packages nothing replaces. Three corrections to how it is stated are below.
MEDIUM —
overlays/bootstrap_apt/etc/apt/preferences:1-3: the 999 pin should go with this change, not wait for #7Verified in the overlay and on both live containers:
999 is above Debian's 500 and below the 1000 that would permit a downgrade. Its entire effect is: for any package name both archives offer, apt takes TurnKey's version even when Debian's is newer, including when Debian's newer version is the security fix. There is no log line for that and nothing in
keel verifythat would notice.The scenario: TurnKey publishes a binary whose name collides with a Debian one — a patched
nginx, acurl, anything — and from the nextapt-get updateevery Keel appliance silently prefers it, on a signature the project does not control, for as long as the source stays.This PR's own measurement is what makes removing it free: 0 installed packages depend on the override, and only
deckof the 141 collides with a Debian name at all. Dropping the file, or lowering it under 500, changes nothing measurable today and removes the mechanism entirely./etc/apt/preferences.d/keelat 1001 is unaffected either way. Leaving it is the one place in this diff where the remaining migration is made to carry something that does not need to wait for it.MEDIUM — the stated reason for leaving the Debian sources on http is not true of this build host
The body says the Debian mirrors stay on http because "the build host reaches them through a caching proxy (
squid_proxyCA.crt...) that http is what feeds". Measured, read-only,/etc/squid/squid.confon the build host:The proxy bumps and caches https as well as http — that is what
squid_proxyCA.crtis for, andconf/bootstrap_apt:134-136already runsupdate-ca-certificatesso the bootstrap trusts it. Flipping the Debian URIs would cost no caching on this host. The remaining reason, "that is Debian's own default", is a real reason; the proxy one is not, and a justification that is wrong in a merged body is the reason nobody revisits the decision.Worth weighing while it is open, because it is the same leak this PR is closing: the old header told every mirror
turnkey-wordpress-19.0-trixie-amd64. Over plain http the request stream says the same thing —wordpress,apache2,php8.4,webmin, at exact versions — to anyone on the path, andfirstboot.d/95secupdatesplus cron-apt make that happen on every appliance with no operator present. Signature verification is unaffected either way; this is confidentiality, which is precisely what the User-Agent change was about. I would either flip Debian here or record the decision indocs/decisions/with the reason that survives.I checked the obvious way this could have broken the build and it does not:
/turnkey/fab/bootstraps/trixie-amd64hasca-certificates,openssland a populated/etc/ssl/certs/ca-certificates.crt, so the firstapt-get updateof a build can verify https before anything is installed.MEDIUM — "39 installed" needs its definition and its container written next to it
Both are load bearing and neither is in the body.
Definition. On
wordpress-demo, 41 of the 141 names are installed. 39 is the count whose apt candidate comes fromarchive.turnkeylinux.org;confconsoleandinithooksare the other two, and they are excluded only becausearchive.keellinux.orgalready serves them at priority 1001. Both numbers are defensible, they answer different questions, and #7 will plan from whichever is written down.Container. The measurement was taken on
wordpress-demo, which never went through the container patch —/sbin/modprobeis the real one (-> ../bin/kmod),/etc/fstabis present, and/etc/default/inithookshasREDIRECT_OUTPUT=false. That isdocs/traps.mdentry 1, and it makes the container atypical of a shipped appliance.It does not move any conclusion here, which I checked rather than assumed: on
forum, which did go through the patch (modprobe -> /bin/true, no/etc/fstab,REDIRECT_OUTPUT=true), the count is 32 — a different appliance, so a different set — and every other line of the table is identical, including the 0 overrides and the singletrixie-securitypackage. So: the count is per appliance, not a property of the distribution, and the sentence should say which appliance and which container it came from.MEDIUM —
COVERAGE.md:48-52and the body: the recorded bats defect is wrong in two of its three casesThe rule as written — "bash does not apply errexit to a negated command, so a bare one passes whatever happens" — is missing its exception. bats takes the last command's status as the test's verdict, so a bare
! cmdin final position does assert. Measured with bats 1.11.1:Applied to
tests/postfix-local.bats, only line 96 is inert. Line 66 is the last command of "fails when port 25 is in use on IPv6 only" and line 97 is the last command of "stops at the first failing postconf"; both decide their tests. shellcheck agrees and grades them differently — SC2314 is an error on 96 and only a note on 66 and 97:So the sentence should read "one of them (line 96)".
run !everywhere is still the right convention — it asserts wherever it stands — but an over-broad rule inCOVERAGE.mdis the kind of thing that gets applied as written later.The sweep the record implies is worth doing, and it is much larger than this repository:
inithookshas 20 inert bare negations, 17 of them intests/test-ipconfig.bats, where 11 of the 13 rejection cases ofipconfig_ip6_syntaxassert nothing. Full list handed over separately; it wants its own issue rather than either of these branches.LOW —
conf/turnkey.d/dpkg-vendor:26-27leaves an inheritedTurnKeyorigin file on the imageThe script replaces
defaultand never removes the file it used to point at.fab-apply-overlayonly adds, so on any layer built on a parent produced before this change,/etc/dpkg/origins/TurnKeystays on disk — I see it on both containers, one of them dated Nov 2023. It is inert for a vendor query, which is why this is LOW, but it is asymmetric with the sibling script:conf/turnkey.d/apt-identity:22removes the stale01turnkeyfor exactly this reason, andremovelists-final/turnkey:2already removes/etc/apt/apt.conf.d/01proxythe same way. One line in either place closes it, andtests/dpkg-vendor.bats:113currently asserts the file is not shipped, which is not the same as not present.LOW — the removal is a property of a build, not of an installed machine
01keelarrives by overlay and01turnkeyis deleted by a conf script, so both happen only while a layer is being built. An appliance already deployed and upgraded through apt keeps its01turnkeyand keeps announcing itself for the life of the machine. That is a reasonable scope for an image-based project, but "upgrade path" in the body means "a build on a stale parent layer", and it is worth saying so — the lexical-order hazard itself I confirmed independently:On
forumthe stale header also carries the build type —... -amd64 proxmox)— so the leak is one field wider than the body shows.LOW — the unit the remaining migration should be measured in
141 is a count of binaries. They come from 35 source packages, and
webmin(103 binaries) pluswebmin-tklbam(1) are 104 of the 141. Every other source but three produces one binary. The body already says the webmin block is one product decision; saying it in sources rather than binaries would stop #7 from reading as roughly four times the work it is.LOW — https adds an availability dependency the payload did not have
archive.turnkeylinux.organswersHTTP/2 200with a verifying certificate on theReleaseof all three suites — confirmed,ssl_verify=0, CN=turnkeylinux.org from Google Trust Services, valid to 2026-12-17, fronted by Cloudflare. The gain is real and worth having. The cost, which is not in the body: the archive is signed either way, so https buys confidentiality and nothing for integrity, while an expired certificate, a broken chain or a wrong clock now turnsapt-get updateinto a hard failure where http would have carried on.95secupdatesruns that on every first boot. Not a reason to revert — a reason for the first-boot hook's failure mode to be worth a look.Checked and found right
Parent: Debianis not a convenience, it is required. ReadDpkg/Vendor.pm:get_vendor_objecttriesDpkg::Vendor::Keel, therequirefails, and lines 197-202 fall back to the parent's object —Dpkg::Vendor::Debian, the same one TurnKey resolved to. DropParent:and it falls toDpkg::Vendor::Defaultinstead, which loses Debian'supdate-buildflagshook, its hardening defaults and its changelog handling. The comment should probably say that outright, because the field looks droppable and is not.tests/dpkg-vendor.bats15/15 andtests/apt-identity.bats11/11 pass here, on dpkg 1.22.22, apt from trixie, bats 1.11.1, and the TLS test does exercise the https path —/usr/lib/apt/methods/httpsis a symlink tohttp, so the singleAcquire::http::User-Agentgenuinely covers both.product.mk'sroot.patched/bodyapplies everyoverlays/turnkey.d/*first and then runs everyconf/turnkey.d/*, on every product build, so01keelis in place beforeapt-identitylooks for it and the inherited01turnkeyis gone beforeroot.patched/post.mk/turnkey-desktop.mkreally is a second copy that #5 misses.shellcheck -S warningclean onconf/turnkey.d/apt-identity,conf/turnkey.d/dpkg-vendor,conf/bootstrap_aptandtests/coverage.sh.archive.turnkeylinux.orgoccurrences inconf/bootstrap_aptmoved (208, 225, 251, 261, 268, 279); theNO_TURNKEY_APT_REPOcomment-out at line 291 still matches, since its pattern carries no scheme.One security matter outside both diffs came out of reading the first-boot path. It is not introduced here and these repositories are public, so I have raised it separately rather than in this thread.
Approve. The change is correct, the assertions are taken from behaviour rather than from the files under test, and the measurement's conclusions survive being re-derived. Everything above is MEDIUM or below; the pin is the one I would fold in before merge, and the two inaccurate sentences (the proxy justification and the three bats line numbers) are worth fixing in place, because both will be read later as settled fact.
b10ae1eremoves an inherited/etc/dpkg/origins/TurnKey(asserted through the realdpkg-vendor) and corrects the bats-negation record: only line 96 ofpostfix-local.batsis inert. The proxy sentence and the definition of "39" are corrected in the description. The 999 pin stays for #7: it changes package resolution on every appliance, and BRIEF section 12 says preserve and record.