Skip to content

fix(packer): clear epoch account-expiry on Kali service accounts so clones don't boot degraded - #1195

Merged
Gerrrt merged 1 commit into
mainfrom
gerrrt/kali-preseed-epoch-expiry
Oct 14, 2026
Merged

Gerrrt merged 1 commit into
mainfrom
gerrrt/kali-preseed-epoch-expiry

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Oct 14, 2026

Copy link
Copy Markdown
Owner

What

Add one late_command step to packer/kali/preseed.cfg.pkrtpl that clears a bogus account-expiry Kali's package postinsts leave on service accounts.

Why

Kali package postinsts create service accounts (lightdm, _gvm, inetsim, nm-openvpn, nm-openconnect, dnsmasq, tcpdump, mysql, pcscd, rtkit, Debian-snmp, systemd-network, systemd-timesync, _dhcpcd) with their shadow account-expiry pinned to the epoch (field 8 == 1, 1970-01-02). lightdm is the one that bites: systemd starts a user@<uid>.service manager for it (the greeter lingers a session), its PAM account step sees the expired account and fails 224/PAM, and the whole guest boots degraded.

Found on garuda during the #921 §9 pass; fixed live there, and tracked for the template in #1194. This is the template-side fix so fresh clones aren't born degraded.

Change

in-target sh -c 'while IFS=: read -r n pass lastchg min max warn inactive expire rest; do [ "$expire" = 1 ] && chage -E -1 "$n"; done < /etc/shadow'
  • Runs at the end of late_command, after package postinsts, so it's the last word before first boot; cloud-init on clones never touches expiry.
  • Touches only accounts actually at the epoch. Real users (packer, and a clone's operator) have an empty expiry field and are left alone.
  • A while IFS=: read loop (not awk) so there are no $1/$8 tokens for the shell or Packer's templatefile() to expand; the only interpolation token in the file remains ${ssh_public_key}. sh -n-clean.

Scope

  • Covers the shared Kali preseed → both 910 (tpl-kali-saruman) and 902 (ifrit's tpl-kali).
  • 903 (tpl-debian-13) has the same upstream quirk on two base accounts but is benign (no display manager → no user manager → not degraded), so it needs no change.

Verification

  • Local: interpolation tokens unchanged (only ${ssh_public_key}); embedded loop passes sh -n; commit passes scripts/check_close_keywords.py.
  • Owed (needs phoenix / ifrit): rebuild 910 + scripts/packer-smoke.sh 910, confirm a fresh first boot is running not degraded; check 902 on ifrit when next built.

Closes #1194

🤖 Generated with Claude Code

…lones do not boot degraded

Kali package postinsts leave service accounts (lightdm, _gvm, inetsim,
nm-*, dnsmasq, ...) with shadow account-expiry at the epoch. lightdm is
started a systemd user@<uid>.service for the greeter, whose PAM account
step then fails 224/PAM, so every clone of templates 910/902 boots
degraded (seen on garuda, #921). The preseed late_command now clears the
expiry on exactly the accounts at the epoch; real users are untouched.

Refs #1194, #921

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 13:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrowly scoped cleanup correctly targets only shadow expiry field 8 values equal to 1.

0 open findings

What changed in this PR

Clears erroneous epoch account-expiry values from Kali service accounts, preventing clones from booting degraded.

Changes:

  • Adds a late-install shadow-account cleanup.
  • Documents the underlying LightDM/PAM failure.
File Description
packer/​kali/​preseed.cfg.pkrtpl Clears epoch expiry values in shared Kali templates 902 and 910.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Gerrrt

Gerrrt commented Oct 14, 2026

Copy link
Copy Markdown
Owner Author

As-run verification (phoenix + Saruman, 2026-10-14)

Rebuilt template 910 from this branch and proved the fix end to end.

Build — packer build -force -only='kali.proxmox-iso.kali-saruman' packer/ on phoenix (packer 1.16.1, token from phoenix.env in-env, ufw inactive so no 8800 rule needed):

INIT_EXIT=0
==> found existing resource with ID 910 ... deleting it
==> Successfully deleted 910 / Creating VM / Starting VM ...
BUILD_EXIT=0   (template 910 re-created)

Smoke — scripts/packer-smoke.sh 910:

PASS cloned / PASS cloud-init (user smoke, DHCP) / PASS agent reports 10.0.30.102
PASS hostname smoke-910 / PASS phoenix's key opens smoke@10.0.30.102
template 910 is usable

Degraded-state acceptance — full-cloned the fresh 910 to a throwaway (930), booted it, checked, destroyed it:

system: running          <- was `degraded` before the fix
failed units: 0          <- user@968 no longer fails PAM
accounts still at epoch (field8==1): 0   <- late_command cleared them in the template

So fresh clones of 910 now inherit a clean /etc/shadow and boot running. garuda (162) was already fixed live; this makes the template itself correct for every future clone.

Still owed (not blocking this PR): the same check on 902 (ifrit's Kali, same preseed) when it's next built — it will carry the identical defect until a rebuild picks up this change.

@Gerrrt
Gerrrt merged commit a953afc into main Oct 14, 2026
9 checks passed
@Gerrrt
Gerrrt deleted the gerrrt/kali-preseed-epoch-expiry branch October 14, 2026 14:28
Gerrrt added a commit that referenced this pull request Oct 14, 2026
…review)

Address review on #1197: the late_command fix is only realised on a rebuilt
template, so limit the "not born degraded" claim to a rebuilt 910 and note 902
keeps the defect until rebuilt (#1196); phrase the grep-finds-nothing evidence
as a pre-fix observation, since PR #1195 added a chage to the preseed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Gerrrt added a commit that referenced this pull request Oct 14, 2026
…11 as-run (#1197)

* docs(lab): garuda's SOC enrolment as run, phase 2

Runbook section 11 records section 12 as run on 2026-10-10: staging on
odin, both packages verified on garuda, the Wazuh agent enrolled as 009
Active with the password on standard input, the Velociraptor client
connected (7 connections server-side), and WazuhAgentsNotConnected
expecting garuda and quiet. Changelog entry for the day.

Refs #921.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(runbook): record the Kali template epoch-expiry fix in analyst §11 as-run

Adds the degraded-state follow-up to §11: root cause (Kali's install layer
ships ~14 service accounts expired at the epoch; only lightdm surfaces via
user@<uid>.service), the live fix on garuda, the preseed late_command fix,
and the 910 rebuild + smoke + fresh-clone verification. Corrects the two
earlier notes that said user@968 still fails. The 902 sibling check is owed.

Refs #921, #1194, #1195, #1196

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(runbook): scope the 902 guarantee and mark the grep as pre-fix (review)

Address review on #1197: the late_command fix is only realised on a rebuilt
template, so limit the "not born degraded" claim to a rebuilt 910 and note 902
keeps the defect until rebuilt (#1196); phrase the grep-finds-nothing evidence
as a pre-fix observation, since PR #1195 added a chage to the preseed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kali template ships service accounts expired at the epoch → every clone boots 'degraded' (user@968/lightdm PAM)

2 participants