mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Give rootless qualification hosts unique identities
This commit is contained in:
@@ -7324,6 +7324,10 @@ or granting an outer default route is invalid qualification. The outer host
|
||||
uses a private cgroup namespace with no host cgroup bind mount. Each dedicated
|
||||
runtime identity must have an active delegated systemd user manager before its
|
||||
daemon starts, and cleanup must stop that manager and remove its linger state.
|
||||
Before each disposable host's first systemd boot, the wrapper installs a fresh
|
||||
valid machine ID into that stopped container. The combined receipt validator
|
||||
rejects a Docker and Podman pair that reports the same machine identity; a
|
||||
shared image fallback identity cannot stand in for two independent hosts.
|
||||
The in-container control-plane fixture must implement the same authenticated
|
||||
collector-uninstall response contract as the production lifecycle client. A
|
||||
teardown succeeds only after the fixture records the exact registered binding
|
||||
|
||||
@@ -259,6 +259,9 @@ the immutable schema-v7 systemd packet. The opt-in
|
||||
`scripts/run-secure-runtime-rootless-qualification.sh` wrapper creates fresh,
|
||||
network-isolated Ubuntu/systemd hosts for real rootless Docker and Podman,
|
||||
never mounts a host daemon socket, and records each host identity separately.
|
||||
It installs a fresh valid machine ID into each stopped container before first
|
||||
systemd boot, and the combined validator rejects duplicate Docker and Podman
|
||||
machine identities rather than accepting a shared image-derived fallback.
|
||||
The exact qualification packet remains outside the image layers; the image
|
||||
must pre-create its root-owned, mode-`0700` packet destination before the
|
||||
wrapper injects artifacts into each stopped disposable container. The image
|
||||
|
||||
@@ -1856,6 +1856,7 @@ func TestRootlessQualificationGuardAndWrapperInvariants(t *testing.T) {
|
||||
`docker cp "${container_id}:/opt/pulse/result/rootless-receipt.json"`,
|
||||
`capture_qualification_container_diagnostics`, `journalctl --no-pager -n 2000`,
|
||||
`302a300506032b6570032100`, `len(spki) != len(prefix) + 32`,
|
||||
`machine_id="$(openssl rand -hex 16)"`, `docker cp "${machine_id_file}" "${container_id}:/etc/machine-id"`,
|
||||
} {
|
||||
if !strings.Contains(script, required) {
|
||||
t.Fatalf("rootless qualification wrapper missing %q", required)
|
||||
@@ -1882,6 +1883,11 @@ func TestRootlessQualificationGuardAndWrapperInvariants(t *testing.T) {
|
||||
if packetDirectoryIndex < 0 || packetCopyIndex < 0 || packetCopyIndex < packetDirectoryIndex {
|
||||
t.Fatal("rootless wrapper must create the private packet destination in the image before artifact injection")
|
||||
}
|
||||
machineIDCopyIndex := strings.Index(script, `docker cp "${machine_id_file}" "${container_id}:/etc/machine-id"`)
|
||||
containerStartIndex := strings.Index(script, `docker start "${container_id}"`)
|
||||
if machineIDCopyIndex < 0 || containerStartIndex < 0 || machineIDCopyIndex > packetCopyIndex || machineIDCopyIndex > containerStartIndex {
|
||||
t.Fatal("rootless wrapper must install a per-host machine ID before packet injection and first systemd boot")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRootlessQualificationDockerCommandUsesSupportedNetworkDriver(t *testing.T) {
|
||||
|
||||
@@ -234,6 +234,16 @@ run_runtime() {
|
||||
local container_name="pulse-rootless-qual-${runtime_name}-${SOURCE_COMMIT:0:8}-$$"
|
||||
local container_id
|
||||
local local_receipt="${OUTPUT_DIR}/${runtime_name}-receipt.json"
|
||||
local machine_id_file="${PACKET_DIR}/.machine-id-${runtime_name}"
|
||||
local machine_id
|
||||
|
||||
machine_id="$(openssl rand -hex 16)"
|
||||
if [[ ! "${machine_id}" =~ ^[0-9a-f]{32}$ || "${machine_id}" == "00000000000000000000000000000000" ]]; then
|
||||
echo "ERROR: unable to generate a valid machine ID for ${runtime_name} qualification" >&2
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' "${machine_id}" >"${machine_id_file}"
|
||||
chmod 0444 "${machine_id_file}"
|
||||
|
||||
container_id="$(docker create --name "${container_name}" --hostname "pulse-rootless-${runtime_name}" \
|
||||
--label "${CONTAINER_RUN_LABEL}=${CONTAINER_RUN_NONCE}" \
|
||||
@@ -241,6 +251,8 @@ run_runtime() {
|
||||
--tmpfs /run:rw,nosuid,nodev,mode=755 --tmpfs /run/lock:rw,nosuid,nodev,mode=755 \
|
||||
"${IMAGE_TAG}")"
|
||||
CONTAINER_IDS+=("${container_id}")
|
||||
docker cp "${machine_id_file}" "${container_id}:/etc/machine-id"
|
||||
rm -f -- "${machine_id_file}"
|
||||
docker cp "${PACKET_DIR}/." "${container_id}:/opt/pulse/packet"
|
||||
docker start "${container_id}" >/dev/null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user