Skip to content
ClearedStack

Guides · L.2 Field guides

Working on disconnected networks

The checks you run by hand when nothing can phone home: checksums, transfer manifests, certificates, lockfiles and image digests.

L.2.77 min readLast revised November 2026

On this page
  1. Checksums
  2. A transfer manifest
  3. Reading a certificate
  4. Checking a chain
  5. Expiry and revocation
  6. Lockfiles
  7. Container images
  8. Keep a record
  9. Sources

On a network with no route to the internet, the things a connected machine does quietly in the background stop working. Package managers cannot fetch, certificate checks cannot reach a revocation server, and nothing updates itself. The work moves to people, and it comes down to answering three questions about every file that crosses the boundary: is it the file I meant to bring, is it intact, and what is inside it?

This guide covers the basic techniques. It is not a transfer policy. The rules for what may cross, and how, belong to the organization that owns the network.

Checksums#

A checksum, or hash, is a short fingerprint computed from the contents of a file. Change one byte and the fingerprint changes completely. Two files with the same SHA-256 checksum are, for practical purposes, the same file.

Compute one:

SystemCommand
Linuxsha256sum file.tar.gz
macOSshasum -a 256 file.tar.gz
Windows PowerShellGet-FileHash file.tar.gz -Algorithm SHA256

Save one alongside the file, and check it later:

sha256sum file.tar.gz > file.tar.gz.sha256
sha256sum -c file.tar.gz.sha256

The second command prints file.tar.gz: OK when the file is unchanged.

Use SHA-256 or stronger. MD5 and SHA-1 still appear on old download pages, but both can be deliberately fooled and should not be relied on to detect tampering.

A transfer manifest#

When you move a folder instead of one file, make a manifest: a list of every file with its checksum. On the sending side:

( cd payload && find . -type f -print0 | sort -z | xargs -0 sha256sum ) > payload.sha256

On the receiving side, with the folder and the manifest both carried across:

( cd payload && sha256sum -c ../payload.sha256 )

Every line should end in OK. A line ending in FAILED is a file that changed. A “No such file” message is a file that went missing.

The manifest catches changed and missing files. To catch extra files that were not in the original, count them on both sides:

find payload -type f | wc -l
wc -l < payload.sha256

The two numbers should match.

A useful manifest for a transfer record also notes who prepared it, when, from what source and for what purpose. Keep it with the approval paperwork.

  1. OutsideGenerate manifestCompute sorted list of SHA-256 checksums for all files in payload folder.
  2. OutsideCount source filesRecord total file count alongside payload.sha256 manifest.
  3. TransferCarry across boundaryMove payload and manifest across according to network transfer rules.
  4. InsideVerify checksumsRun sha256sum -c to ensure all files are unchanged (OK) with no FAILED lines.
  5. InsideVerify file countConfirm file count matches manifest lines to ensure no extra files were introduced.
Figure Transfer manifest verification across a network boundary

Reading a certificate#

A certificate binds a name to a public key and is signed by an authority that vouches for it. On a disconnected network you often have to inspect one by hand, because the browser’s usual machinery cannot reach outside.

Print the fields that matter:

openssl x509 -in server.pem -noout -subject -issuer -dates -ext subjectAltName
FieldWhat to check
SubjectWho the certificate was issued to
Subject alternative nameThe host names it is valid for. This is what a browser matches against the address
IssuerThe authority that signed it
Not before, not afterThe period it is valid for

Print everything, including key size, permitted uses and the signature algorithm:

openssl x509 -in server.pem -noout -text

See the certificates a running server presents:

openssl s_client -connect server.internal.example:443 -showcerts

Checking a chain#

A server certificate is trusted because of a chain: it is signed by an intermediate authority, which is signed by a root authority your machine already trusts. To verify a certificate against a file holding the authorities you trust:

openssl verify -CAfile ca-chain.pem server.pem

It prints server.pem: OK when the chain is complete and every signature checks. The usual failures are:

MessageMeaning
unable to get local issuer certificateAn intermediate or the root is missing from the file you supplied
certificate has expiredToday is past the “not after” date
certificate is not yet validThe machine’s clock is behind, or the certificate was issued for a later start
self-signed certificateThe certificate vouches for itself and is not in your trusted set

Two things are particular to closed networks:

  • Private authorities. Internal networks, including government ones, run their own certificate authorities. Their root certificates are not built into ordinary browsers and operating systems. They have to be installed, from a source you trust, before anything they signed will verify.
  • Clocks. A machine with no time source drifts. A wrong clock makes good certificates look expired or not yet valid. Check the date before you blame the certificate.
DecisionWhat result does openssl verify return?
  • server.pem: OK
    Certificate trustedChain is complete, signatures are valid, and dates are currently valid.
  • unable to get local issuer certificate
    Missing authorityAn intermediate or root CA certificate is missing from the CAfile.
  • certificate has expired / not yet valid
    Time error or driftCurrent date is outside validity window, or the disconnected machine’s clock drifted.
  • self-signed certificate
    Untrusted originThe certificate vouches for itself and has not been added to your trusted CA bundle.
Figure Common certificate verification outcomes

Expiry and revocation#

To find certificates about to expire, ask whether one will still be valid a set number of seconds from now. Thirty days is 2,592,000 seconds:

openssl x509 -in server.pem -noout -checkend 2592000

The command says whether the certificate will expire in that time, and sets its exit status to match, so it can be used in a script.

Revocation is harder. A certificate can be cancelled before it expires, and the normal ways of finding out need a network connection to the issuing authority. On a disconnected network the lists of revoked certificates have to be brought in on a schedule, like any other update. A certificate that verifies against a stale list may have been revoked since.

Lockfiles#

A lockfile records the exact version of every package a project depends on, usually with a checksum for each. For this site, that file is package-lock.json. An entry looks like this:

"node_modules/react": {
  "version": "19.3.0",
  "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz",
  "integrity": "sha512-..."
}
FieldWhat it tells you
versionThe exact version that will be installed
resolvedWhere it was downloaded from
integrityA checksum the installer verifies before using the package

On a closed network a lockfile is three things at once: the list of what to bring in, the means of checking each item, and a record of what a build contained. Install from it with a command that refuses to deviate, such as npm ci, so that the build inside matches the build that was reviewed outside.

Read the resolved lines. Every one that points at a public registry is a package that must be mirrored inside before the build can run.

Container images#

A container image is identified two ways. A tag, such as clearedstack:1, is a label that can be moved to point at different contents. A digest, a long string starting with sha256:, is computed from the contents and cannot.

When an image crosses a boundary as a file, compare its digest on both sides. On a host that runs containers with containerd, its own command-line tool, ctr, lists and exports images:

ctr -n k8s.io images ls | grep clearedstack
ctr -n k8s.io images export clearedstack.tar registry.example.com/clearedstack@sha256:<digest>

Check the exported file in transit with an ordinary sha256sum, then import it on the inside:

ctr -n k8s.io images import clearedstack.tar

Inside the network, refer to images by digest in anything that matters:

image: registry.internal.example/clearedstack@sha256:<digest>

A tag tells you what someone called an image. A digest tells you what it is.

  1. 1 · OutsideRecord image digestNote the exact sha256 digest shown by ctr images ls.
  2. 2 · OutsideExport OCI archiveExport with ctr images export and generate sha256sum.
  3. 3 · TransitMedia transferCarry file across network boundary per transfer rules.
  4. 4 · InsideVerify checksumCheck file integrity using sha256sum -c before importing.
  5. 5 · InsideImport & check digestctr images import and verify digest matches outside digest exactly.
Figure Moving and verifying a container image across a boundary

Keep a record#

For everything that crosses, write down enough to answer questions a year later:

  • what it is, and which version
  • where it came from: the address, the commit or the release
  • its checksum or digest
  • who reviewed it and what they checked
  • the date it was brought in
  • what it replaced

Then set a date to look again. Software on a closed network does not learn about its own vulnerabilities. Someone has to bring that news in.

Sources#

  • NIST, FIPS 180-4, “Secure Hash Standard”, for SHA-256, at csrc.nist.gov.
  • RFC 5280, “Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile”.
  • The OpenSSL manual pages for x509, verify and s_client.
  • The npm documentation for package-lock.json and npm ci.
  • The Open Container Initiative image specification, for image digests.

Found a mistake, or something that has gone out of date? Open an issue or write to [email protected]. This page is a text file you can read and correct: Source of this page.