Category: Linux Administration

Linux configuration, troubleshooting and day-to-day operations.

  • Stop a deployment when artifact checksums fail

    A release copied to another server can be incomplete or differ from the files you intended to deploy. A checksum gate lets your deployment process stop rather than proceed with that bundle. This short exercise demonstrates the gate and checks its failure paths without deploying anything.

    Prerequisites: Bash and GNU coreutils already installed. Use a regular, unprivileged account. Run every block below in order in the same Bash session. Everything happens inside a new demo directory; no installation or network access is needed.

    1. Create a disposable artifact bundle

    Start with two tiny files, including a filename containing a space. The temporary directory is created under TMPDIR when set, otherwise under your home directory. Quoting keeps the filename intact.

    set -euo pipefail
    DEMO_DIR=$(mktemp -d "${TMPDIR:-$HOME}/dav3-demo.XXXXXX")
    cd "$DEMO_DIR"
    printf '%s\n' 'app config' > 'app config.txt'
    printf '%s\n' 'secondary file' > 'secondary.txt'
    

    2. Generate the manifest from known-good files

    Name each artifact explicitly. This avoids accidentally hashing the manifest itself or including unrelated files through a wildcard. In a real pipeline, generate this manifest at the trusted build stage—not after receiving files you suspect are damaged.

    sha256sum -- 'app config.txt' 'secondary.txt' > SHA256SUMS
    

    3. Make successful verification a prerequisite

    Run verification from the bundle directory because the manifest contains relative paths. A mismatch or unreadable listed file produces a nonzero exit status; strict mode also rejects malformed checksum lines.[1]

    if ! sha256sum --check --strict SHA256SUMS; then
        printf '%s\n' 'Verification failed: deployment aborted' >&2
        exit 1
    fi
    printf '%s\n' 'PASS: original artifacts verified'
    

    In your deployment script, place the equivalent check immediately before the deployment operation. Do not suppress errors or enable ignore-missing behavior. This demo deliberately does not include a deployment command.

    4. Prove that changed content is rejected

    The following check expects failure. An unexpected success is itself a test failure and terminates the demo with exit status 1.

    printf '%s\n' 'modified content' > 'app config.txt'
    if sha256sum --check --strict SHA256SUMS; then
        printf '%s\n' 'ERROR: changed content was accepted' >&2
        exit 1
    else
        printf '%s\n' 'PASS: changed content rejected'
    fi
    

    5. Prove that a missing artifact is rejected

    Restore the first file exactly, then remove the second demo file. Do not regenerate the manifest: doing so would change the baseline you are checking against.

    printf '%s\n' 'app config' > 'app config.txt'
    rm -- 'secondary.txt'
    if sha256sum --check --strict SHA256SUMS; then
        printf '%s\n' 'ERROR: missing artifact was accepted' >&2
        exit 1
    else
        printf '%s\n' 'PASS: missing artifact rejected'
    fi
    printf 'Demo directory retained: %s\n' "$DEMO_DIR"
    

    Checksum failure messages during steps 4 and 5 are expected. The complete demo exits successfully only when those expected failures are handled correctly; it is a test, not a script that deploys the intentionally damaged bundle. Your real deployment gate is step 3.

    Limitations

    Checksums compare content, not provenance. An attacker able to replace both payload and manifest can bypass this check. Unlisted files and file permissions are not verified, and verification does not prevent changes afterwards. Protect the manifest and keep the verified release immutable through deployment. This userspace exercise is not a full server, kernel, or deployment-pipeline test.

    Sources

    [1] GNU coreutils checksum options

    Technical validation record

    AI-assisted draft: the initial text came from a local Qwen3 4B Instruct model. An AI assistant corrected the commands and edited the explanation. This is not an unedited local-model result.

    Six execution and fault-injection runs passed on the two pinned container images listed below. Tests ran without network access, as a non-root user, with a read-only root filesystem and CPU/memory limits. Exit code 1 is the expected result for the deliberately broken verification cases, not a failing test.

    Environment Case Actual exit Expected exit Result
    ubuntu Normal run: valid, changed and missing files 0 0 PASS
    ubuntu Fault injection: missed tampering must stop the demo 1 1 PASS
    ubuntu Fault injection: missed missing-file check must stop the demo 1 1 PASS
    almalinux Normal run: valid, changed and missing files 0 0 PASS
    almalinux Fault injection: missed tampering must stop the demo 1 1 PASS
    almalinux Fault injection: missed missing-file check must stop the demo 1 1 PASS

    Test execution time (UTC): 2026-09-27T12:28:51.399277+00:00. Source Markdown SHA-256: aca155c66921f0faec843f6f6f78e1fcda4259a72bd80ea14ce886daacaaa406. Executed script SHA-256: b34fc790415db245b0ef6207e8bf49ae21c831857bc3009be9293bb59e027292.

    Container image: almalinux@sha256:3a3fa7f043b142bc8008c8b308d39b47d2c84008addcd52f9f9a7a82d2a90474

    Container image: ubuntu@sha256:008173c23f95b170204355c12626cb5a965d779a7e1283b09e9cffbb1bf33ca3

    Scope: container userspace only, not a full server, kernel or deployment-pipeline validation. No CentOS or CloudLinux testing is claimed. These results apply to the exact source version and commands recorded above; changes to the commands require new tests.