94 lines
5.7 KiB
Markdown
94 lines
5.7 KiB
Markdown
# Existing Railiance01 k3s service hardening — review addendum
|
|
|
|
Part of CUST73-CREDENTIAL-BOUNDARY-R1, next review revision; original revision-2
|
|
packet remains unchanged. No execution approval, mutation or restart occurred.
|
|
This is the existing-host mode change only, not Custodian assignment admission.
|
|
|
|
## Observed target and exact proposed change
|
|
|
|
Existing SSH configuration resolves railiance01 to 92.205.62.239 as tegwick,
|
|
without proxy/local commands. The read used that existing access, no certificate
|
|
issuance and no sudo. Warden ssh-cert-host-access route was checked first.
|
|
|
|
Sanitized observation refreshed at remote UTC 2026-10-19T12:00:53.721961+00:00,
|
|
with local transport start/finish timestamps separately retained. Strict SSH
|
|
host-key checking was required. The expected IPv4 is present on the host;
|
|
observation.json binds hostname and hashed machine-id. These are captured facts,
|
|
not timeless target assertions; rerun identity checks before any approval/execution.
|
|
|
|
k3s is loaded/active/running, main PID935, fragment
|
|
/etc/systemd/system/k3s.service, no drop-ins, no pending daemon reload. Its
|
|
loaded ExecStart and fragment each have exactly one mode644 flag. The fragment
|
|
is regular root:root0644, device2049/inode7875, SHA256:
|
|
`b5398c385430ce225faadc1f3724597fe4b05dd999a04b8abbca64d4b0d68c0e`.
|
|
The default config.yaml and config.yaml.d are absent.
|
|
Admin kubeconfig metadata is root:root0644, device2049/inode786464; its contents
|
|
were not read. The service.env file is root:root0600 and inaccessible without
|
|
privilege; only its metadata was read, not contents or a hash.
|
|
|
|
The exact proposed unit transformation changes the single mode argument from
|
|
644 to 600, preserving every other byte and total length. Two bytes change.
|
|
The privately computed candidate SHA256 is:
|
|
`866ea58bfab00215e5bd3352287ebb0230d4ddb7dd3ed4b1cd853e74c6698d7d`.
|
|
No candidate file was written on the host and raw unit content was never emitted.
|
|
`unit_transform.py` provides the pure guarded transform, with pinned original and
|
|
candidate hashes, root owner/mode/device/inode checks, O_NOFOLLOW, link-count and
|
|
concurrent-read checks. It has no write/reload/restart code. Five tests cover
|
|
exact change and refusal on drift, absent/duplicate flag or wrong candidate.
|
|
|
|
## Execution sequence to include in owner-reviewed privileged revision
|
|
|
|
Owner: railiance-cluster for unit/install config, railiance-infra for account
|
|
recovery. The narrow approved executor must:
|
|
|
|
1. Verify fresh host identity, service state, original fragment identity/hash,
|
|
no new drop-ins/config paths, and no pending reload. Refuse drift; do not
|
|
auto-rebase this proposal onto another service revision.
|
|
2. Retain private owner-only predecessor bytes and metadata outside agent reach.
|
|
Confirm separate attended console/admin recovery and single-node headroom.
|
|
3. After the protected-environment gate below, generate the candidate in private
|
|
root staging and require exact candidate digest, root ownership and mode0644.
|
|
Recheck the original object before atomic replacement. Converge only the
|
|
admin kubeconfig owner/group/mode to root:root0600 without reading its content.
|
|
4. Run systemctl daemon-reload; verify loaded mode600 and no unrelated fragment
|
|
or drop-in change. Restart only k3s in the approved interruption window.
|
|
No reinstall, package upgrade, generic bootstrap or kubeconfig export.
|
|
5. Verify active/running service, fresh mode600 ExecStart, kubeconfig root:root0600
|
|
after readiness, cluster API readiness through attended admin access and no
|
|
workload rollout regression. Receipts expose only booleans/state and pinned
|
|
hashes. Do not capture kubectl error dumps, unit/env/config text or credentials.
|
|
6. Keep future-installer source correction from the original packet coupled to
|
|
this change, so a future installer does not reintroduce644 or controller export.
|
|
|
|
## Explicit remaining gate
|
|
|
|
The protected /etc/systemd/system/k3s.service.env cannot be read by the current
|
|
non-sudo observation path. No privilege escalation or content retrieval is
|
|
requested here. The owner must independently return only nonsecret predicates:
|
|
whether alternate config selection or K3S_KUBECONFIG_MODE is defined, whether it
|
|
can conflict with the selected launch change, and whether additional config/drop-in
|
|
sources exist. Do not return values or raw environment. Unknown means refusal,
|
|
not an assumption that the default config absence covers every launch input.
|
|
Fresh exact action, execution identity, expected interruption bound, validation
|
|
and recovery must be bound into the supervisor-approved revision before use.
|
|
|
|
## Abort and recovery
|
|
|
|
Before any write: a failed predicate aborts with no effect. After fragment
|
|
replacement but before service restart: the owner can CAS-restore the private
|
|
preimage only if the candidate digest is still exact, then daemon-reload; retain
|
|
kubeconfig0600 and do not restart the old mode644 service. This rollback returns
|
|
the reviewed predecessor unit, not a claim that credential separation succeeded.
|
|
|
|
After restart: prefer attended diagnosis with mode600 retained. Do not
|
|
unconditionally restore644 or expose admin credentials to recover readiness.
|
|
If restoring the old launch is necessary, stop all agent admission and obtain
|
|
explicit supervisor disposition acknowledging mode644 regeneration; use retained
|
|
console access, exact candidate/preimage CAS and immediate post-start0600
|
|
convergence. This exceptional fallback is not authorized by this preparation.
|
|
Preserve failure evidence and re-establish persistent600 before agent admission.
|
|
|
|
No change to old SSH principals, workstation kubeconfigs, native provider
|
|
credentials or actual interactive assignment isolation is established here.
|
|
Estimated extra infrastructure allocation is zero; restart can interrupt the
|
|
single control plane. Monetary loss is unquantified; autopilot remains disabled.
|