Verificare i tuoi download
I binari bits girano sui tuoi host con visibilità privilegiata, e bitcollector produce le
evidenze su cui contate tu e il tuo auditor. Un'evidenza vale sempre e solo quanto lo
strumento che l'ha prodotta.
Quindi, prima di installare qualsiasi cosa, devi essere in grado di dimostrare esattamente quali byte stai per eseguire. Questa pagina ti mostra come, usando solo strumenti pubblicati, offline.
Non installare il binario. Non "riprovare a scaricarlo e sperare". Conserva i file e scrivi a [email protected] indicando la versione della release e l'output del comando fallito.
Cosa accompagna ogni release
| File | Cos'è |
|---|---|
bitcollector-<os>-<arch> | Il binario stesso |
bitcollector-<os>-<arch>.sbom.json | SBOM CycloneDX — tutto ciò che c'è dentro quel binario |
bitcollector-<os>-<arch>.sig | Bundle di firma cosign su quegli esatti byte |
bitcollector-<os>-<arch>.att | Attestazione cosign che lega l'SBOM a quegli esatti byte |
SHA256SUMS | Checksum di ogni file qui sopra |
SHA256SUMS.sig | Firma cosign su SHA256SUMS |
release-provenance.json | Commit, toolchain Go e piattaforme da cui la release è stata compilata |
Le release di bitscanner, bitenforcer e bitmapper hanno la stessa struttura, con il proprio
nome al posto di bitcollector. Tutti e quattro i prodotti sono firmati con la stessa chiave
di release, quindi una sola verifica della chiave copre l'intera famiglia — e una chiave che
cambiasse fra due di essi sarebbe un motivo per fermarsi, non per aggiornare la tua copia.
Passo 0 — procurati gli strumenti
Ti servono cosign v3 o successivo e
sha256sum (parte di coreutils; su macOS, shasum -a 256 oppure brew install coreutils).
cosign version
Passo 1 — ottieni la chiave pubblica, e verifica che sia la chiave giusta
Scarica la chiave di firma della release accanto alla directory della release, non al suo interno:
# dalla directory che CONTIENE la tua directory di release
# DNS route — works from a CLI and inside CI. The HTTPS copy of this key is
# currently behind a bot challenge, so `curl` cannot fetch it; see the note below.
dig +short TXT _cosign-key.cert-ix.com | tr -d '"' | sed 's/.*key=//' \
| base64 -d | openssl pkey -pubin -inform DER -out cosign.pub
verify-release.sh considera ogni file presente in una directory di release come
qualcosa che dovrebbe essere firmato. Lasciarci dentro cosign.pub gli fa segnalare un
file non giustificato — cosa che si legge esattamente come una release manomessa, ma non
lo è. Tieni la chiave un livello più su. Per lo stesso motivo, passala con un
percorso assoluto: lo script si sposta nella directory della release, quindi un
--key cosign.pub relativo smette di risolversi e l'errore che stampa è indistinguibile
da una firma errata.
Un attaccante in grado di sostituire un binario sul nostro sito può sostituire anche la chiave pubblica che gli sta accanto. La verifica passerebbe — contro la loro chiave. Eseguiresti il loro binario ottenendo un segno di spunta verde.
Una verifica di firma vale solo quanto l'ancora di fiducia che le sta dietro. Conferma l'impronta della chiave da una seconda fonte indipendente prima di fidartene. È tutto il senso delle righe che seguono, ed è il passo che la maggior parte delle istruzioni di verifica omette.
L'impronta
Calcola l'impronta della chiave che hai scaricato:
# The robust form: SHA-256 of the DER-encoded public key.
# Independent of PEM whitespace, so copy-paste through a browser cannot change it.
openssl pkey -pubin -in cosign.pub -outform DER | sha256sum
Deve essere esattamente:
552839f6b1b1eb0934557e1886326c7270584fa602fbf56f84754a98be3de822
Se preferisci calcolare l'hash del file così com'è:
sha256sum cosign.pub
# 150eacccc1bc26a83c746a1e441b0b0bdc8104c3ef07efd75c62deb5b069f914
Quel secondo valore copre gli esatti byte del file pubblicato, newline inclusa, quindi corrisponde solo se hai scaricato il file anziché incollarne il contenuto.
La chiave stessa è abbastanza corta da poterla leggere. È tutta qui:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPA6gi66NIBXbSwYS3CL16Ien3sho
wCNOR8dRivdd07SQWto107QMDelUKMeebJQHSlOchNO4PJSWjCcrsUYb5w==
-----END PUBLIC KEY-----
È una chiave pubblica ECDSA P-256 (prime256v1). Puoi verificarlo tu stesso:
openssl pkey -pubin -in cosign.pub -text -noout | head -2
# Public-Key: (256 bit)
Seconde fonti per l'impronta
Non prendere l'impronta dalla stessa pagina che ti ha servito la chiave, se puoi evitarlo. Confrontala con almeno una di queste:
- Un record DNS, servito da un'infrastruttura diversa da questo sito web. La stessa
impronta è pubblicata in un record TXT su
_cosign.cert-ix.com, e basta un comando per verificarlo:dig +short TXT _cosign.cert-ix.com. È il riscontro che vale la pena fare: un attaccante che avesse preso il controllo di questo server web dovrebbe prendere anche il nostro DNS perché i due coincidano — sistemi diversi, con credenziali diverse. Se non coincidono, fermati: non eseguire i binari e scrivi a [email protected]. - Il tuo contatto Cert-IX, fuori banda. Chiedi al tuo referente commerciale o di sicurezza di rileggerti l'impronta su un canale che non sia questo sito web — una telefonata, una email firmata da [email protected], o il tuo canale di supporto abituale.
- Una chiave che hai già. Se hai verificato una release bits precedente, confronta con la chiave che hai conservato. Una chiave di release che cambia senza un annuncio è un motivo per fermarsi e chiedere, non per aggiornare la tua copia.
Una volta confermata l'impronta, conserva la tua copia della chiave e riutilizzala. Il valore di un'ancora di fiducia deriva dal fatto che non cambia.
Passo 2 — verifica prima il manifest dei checksum
L'ordine conta. Verifica la firma su SHA256SUMS prima di fidarti di qualsiasi checksum
al suo interno — un file di checksum non firmato non dimostra nulla, perché chi può sostituire
un binario può sostituire con la stessa facilità un semplice elenco di checksum.
cosign verify-blob --key cosign.pub --bundle SHA256SUMS.sig \
--insecure-ignore-tlog=true SHA256SUMS
Output atteso:
WARNING: Skipping tlog verification is an insecure practice that lacks transparency and
auditability verification for the blob.
Verified OK
Cert-IX è una piattaforma sovrana UE e non gestisce alcun transparency log Sigstore
pubblico. Le firme sono basate su chiave. Senza --insecure-ignore-tlog=true, cosign v3
cerca una voce nel transparency log che intenzionalmente non esiste e riporta "no signatures
found".
Il flag non indebolisce la verifica della firma in sé. Ciò che comporta è che non ottieni alcun registro indipendente e append-only del fatto che questa firma sia mai esistita — quindi il confronto incrociato dell'impronta al Passo 1 svolge un lavoro che altrimenti farebbe per te un transparency log. Questo è il compromesso, dichiarato apertamente.
Passo 3 — verifica che ogni file corrisponda al suo checksum
sha256sum -c SHA256SUMS
Passo 4 — verifica il binario che stai per installare
cosign verify-blob --key cosign.pub --bundle bitcollector-linux-amd64.sig \
--insecure-ignore-tlog=true bitcollector-linux-amd64
Passo 5 — verifica che l'SBOM descriva davvero questi byte
cosign verify-blob-attestation --key cosign.pub --bundle bitcollector-linux-amd64.att \
--type cyclonedx --insecure-ignore-tlog=true bitcollector-linux-amd64
L'SBOM è il modo in cui sai cosa c'è dentro il collector che produrrà le tue evidenze. Un binario la cui attestazione non corrisponde ai suoi byte è un binario di cui non puoi enumerare il contenuto.
Tutto quanto in un solo comando
Cert-IX distribuisce lo stesso script di verifica che esegue sulle proprie release prima di
pubblicarle, in ci/verify-release.sh nel repository:
./verify-release.sh "$PWD/bitcollector-release" "$PWD/cosign.pub"
[verify-release] verifying the signature over SHA256SUMS
[verify-release] SHA256SUMS signature OK
[verify-release] verifying checksums of every artefact
[verify-release] all checksums OK
[verify-release] bitcollector-darwin-amd64 signature OK
[verify-release] bitcollector-darwin-amd64 SBOM attestation OK
[verify-release] bitcollector-darwin-arm64 signature OK
[verify-release] bitcollector-darwin-arm64 SBOM attestation OK
[verify-release] bitcollector-linux-amd64 signature OK
[verify-release] bitcollector-linux-amd64 SBOM attestation OK
[verify-release] bitcollector-linux-arm64 signature OK
[verify-release] bitcollector-linux-arm64 SBOM attestation OK
[verify-release] bitcollector-windows-amd64.exe signature OK
[verify-release] bitcollector-windows-amd64.exe SBOM attestation OK
[verify-release] VERIFIED: 5 binary/binaries, checksums, and signatures all valid
[verify-release] built from commit 8819759 with go1.25.12
OK: 5 verified
Codice di uscita 0 e una riga che riporta OK: <n> verified significano che ogni binario è
autentico e integro. Qualsiasi altra cosa significa non installare.
Lo script entra nella directory della release prima di iniziare il lavoro, quindi un percorso relativo alla chiave pubblica smette di risolversi e ogni verifica di firma fallisce con:
[verify-release] REFUSED: the signature over SHA256SUMS is NOT valid for this key.
Quel rifiuto è identico a quello di una release manomessa. Se lo vedi, riesegui con percorsi
assoluti ("$PWD/cosign.pub") prima di trarre qualsiasi conclusione — e se continua a fallire
con un percorso assoluto, allora trattalo come reale e contatta
[email protected].
Due dettagli che vale la pena notare, perché sono la differenza tra una verifica e un rito:
- Riporta un conteggio. Una verifica che non trova nulla da verificare non deve riportare successo, quindi lo script rifiuta quando la directory non contiene binari, e stampa quanti ne ha effettivamente verificati.
- Rifiuta in caso di firma mancante. Un binario non firmato dentro una release firmata è esattamente l'aspetto di un attacco alla supply chain, quindi lo script fallisce anziché saltarlo.
Cosa dimostra oggi la firma
Su questo bisogna essere precisi, perché "firmato" viene spesso inteso come qualcosa di più di quello che è.
Cosa dimostra: che questi esatti byte sono stati prodotti dalla pipeline di release
Cert-IX e firmati da chi detiene la chiave la cui impronta hai verificato al Passo 1, e che non
sono cambiati da allora. Insieme a SHA256SUMS e all'attestazione dell'SBOM, puoi enumerare
cosa c'è dentro il binario ed essere certo che l'enumerazione corrisponda ai byte.
Cosa non dimostra, detto onestamente:
- La chiave di firma risiede attualmente sull'host di build, protetta come file con una passphrase custodita fuori dal controllo di versione. Non si trova in un modulo di sicurezza hardware (HSM). Quindi la firma dimostra "questo è il binario prodotto da quella build" — non dimostra che l'host di build stesso non fosse compromesso al momento della firma.
- Non esiste un transparency log. Non puoi consultare un registro indipendente e append-only per vedere se sotto questa chiave sia mai stata emessa una firma per un altro binario.
Entrambe queste cose sono il motivo per cui la build riproducibile qui sotto conta, e per cui il confronto incrociato dell'impronta al Passo 1 non è opzionale.
Ricompilare il binario da solo
Non devi credere sulla parola a ciò che diciamo esserci dentro il binario — puoi ricompilarlo e confrontare. Le release bits sono riproducibili: lo stesso commit, compilato con la stessa toolchain Go, produce un output identico a livello di byte.
Parti da release-provenance.json, che registra esattamente da cosa è stata compilata la
release:
{
"service": "bitcollector",
"version": "0.1.0-ga",
"commit": "8819759",
"go_toolchain": "go1.25.12",
"source_date_epoch": 1786277293,
"build_time": "2026-08-09T12:08:13Z",
"platforms": ["linux/amd64", "linux/arm64", "darwin/amd64", "darwin/arm64", "windows/amd64"],
"reproducible": true,
"signed": true
}
Con il sorgente e la toolchain lì indicati:
git checkout <commit from release-provenance.json>
SOURCE_DATE_EPOCH=<source_date_epoch from release-provenance.json>
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath \
-ldflags="-s -w -buildid= \
-X main.version=<version> \
-X main.buildTime=$(date -u -d @$SOURCE_DATE_EPOCH +%Y-%m-%dT%H:%M:%SZ) \
-X main.gitCommit=<commit>" \
-o bitcollector-linux-amd64 ./cmd/bitcollector
sha256sum bitcollector-linux-amd64 # must equal the value in SHA256SUMS
Un hash corrispondente significa che il binario pubblicato non contiene nulla che non sia nel sorgente che hai appena letto.
Release attuali
Tutti e quattro i bits sono pubblicati, e tutti e quattro sono firmati con la stessa chiave — quella di cui hai verificato l'impronta al Passo 1. Una sola verifica della chiave copre la famiglia.
| Prodotto | Versione | Commit | Toolchain | Piattaforme |
|---|---|---|---|---|
bitcollector | 0.1.0-ga | 8819759 | go1.25.12 | linux amd64/arm64, macOS amd64/arm64, Windows amd64 |
bitscanner | 0.1.3-ga | 7db3d4c | go1.25.12 | linux amd64/arm64 |
bitenforcer | 0.1.0-ga | 4c6ce93 | go1.25.12 | linux amd64/arm64 |
bitmapper | 0.1.0-ga | 64ebc64 | go1.25.12 | linux amd64 |
Le colonne delle piattaforme non sono tutte uguali, e le differenze sono deliberate. Dove manca una piattaforma è perché l'agente non vi svolgerebbe il proprio lavoro, non perché la build sia stata dimenticata. Ogni pagina di prodotto ne dà la ragione:
| Prodotto | Cosa viene trattenuto, e perché |
|---|---|
bitcollector | Nulla. È distribuito su tutte e cinque — piattaforme |
bitscanner | Niente macOS/Windows: i suoi lettori dei vicini e delle rotte sono implementazioni Linux, e una tabella dei vicini vuota si leggerebbe come un segmento tranquillo — piattaforme |
bitenforcer | Niente macOS/Windows: tutta la sua superficie è iptables/sysctl/systemd/SELinux, quindi una build lì riporterebbe ogni modulo come NOT EXAMINED — piattaforme |
bitmapper | Solo linux amd64: la cattura richiede una libpcap compilata dentro il binario, quindi non può essere compilata in modo incrociato. Windows compila ma non vi è mai stato eseguito, perciò è trattenuto come lacuna di test — piattaforme |
I commit qui sopra sono quelli da cui sono state compilate le release attuali.
release-provenance.json, dentro la tua directory di release, è il registro autorevole per
quella directory — confrontalo con la tabella anziché dare per scontato, e il binario stesso
stampa gli stessi valori a partire dai byte che stai per eseguire. Se i tre non coincidono,
fermati e scrivi a [email protected].
Il comando non è lo stesso su tutti e quattro i binari. Usa quello del binario che hai:
| Binario | Comando che stampa la sua versione |
|---|---|
bitcollector | bitcollector --version |
bitscanner | bitscanner version |
bitenforcer | bitenforcer version |
bitmapper | bitmapper version |
Usa esattamente queste grafie, perché quella sbagliata non si limita a stampare un errore:
- Su
bitcollectorfino alla versione0.1.0-gainclusa,bitcollector versionnon è un comando di versione. L'argomento viene ignorato e il binario AVVIA L'AGENTE: crea la propria chiave di identità nella directory dei dati e inizia a raccogliere. Se lo hai eseguito, ferma il processo ed elimina la directory dei dati (/var/lib/bitcollector, se non l'hai cambiata) prima di arruolare davvero l'host.bitcollector --versionstampa ed esce, e lo ha sempre fatto. - Su
bitscanner,bitenforcerebitmapper,--versionnon è un'opzione che hanno; il comando fallisce conunknown flag: --version. Quello è innocuo, solo inutile.
I binari e la loro chiave di firma sono nella pagina dei download. I passi qui sopra funzionano offline su qualsiasi directory di release tu abbia, quindi puoi verificare su una macchina che non tocca mai il nostro sito web.
Passi successivi
- bitcollector — cosa raccoglie, e come viene verificata la sua catena delle evidenze (una chiave diversa, e una verifica separata).
- bitenforcer — cosa fa e cosa non fa la v1.
- Panoramica di bits — parti da qui se sei arrivato prima su questa pagina.
Questa pagina ti è stata utile?