Passa al contenuto principale
Versione: 1.0.0

bitscanner

bitscanner trova i dispositivi che il tuo inventario non contiene.

bitcollector legge l'host su cui gira. bitscanner guarda verso l'esterno, da quell'host verso il segmento che lo circonda — e la risposta che conta è quella che nulla nel tuo elenco di asset spiega.

Release0.1.3-ga, commit 7db3d4c, compilato con go1.25.12
PiattaformeSolo Linux amd64/arm64 — macOS e Windows non sono pubblicati, ed ecco perché
Supply chainBuild riproducibile (compilata due volte, rifiutata se non identica byte per byte), SBOM CycloneDX e attestazione cosign per singolo binario, gate sulle vulnerabilità, firma cosign per singolo binario e su SHA256SUMS
Superficie di rete in ingressoNessun servizio in ascolto. Nessuna porta di health, metriche o amministrazione, e nessuna chiave che ne apra una. Misurato con lo scanning disattivato: zero socket in ascolto. service_discovery, una volta armato, usa socket UDP effimeri e non vincolati; un datagramma che vi arriva diventa un record di inventario solo se risponde alla query appena inviata e proviene da allowed_cidrs — non verificato in 0.1.3-ga e versioni precedenti, vedi sotto
Traffico in uscitaSolo https, verso gli endpoint che configuri. Nessun redirect viene mai seguito
Scritture sull'hostLa propria directory dati (agent.data_dir), che contiene la chiave di enrolment e il token dell'agente, 0600 dentro una directory forzata a 0700
Pacchetti sulla rete per impostazione predefinitaZero. Entrambi gli interruttori di armamento sono forniti disattivati

Prima di eseguirlo, verifica il download — i passi specifici per bitscanner sono qui sotto.

Due cose qui sono abbastanza rilevanti da meritare una pagina a sé: la scansione e il modello di armamento a due interruttori — la scala delle sonde, cosa mette sulla rete ciascuna sonda e la guardia che autorizza ogni pacchetto — e cosa lascia l'host, compresi l'enrolment, il traffico in uscita e i limiti con cui questa release viene fornita.

La domanda a cui bitcollector non può rispondere​

Un inventario costruito a partire dagli agenti può contenere soltanto le macchine su cui qualcuno ha installato un agente. La stampante, lo switch di laboratorio, il portatile del consulente esterno, la VM che un team ha creato per una migrazione senza dirlo a nessuno — nessuno di questi si annuncerà da solo, e nessuno di questi manca a causa di un guasto tecnico. Mancano perché nessuno sapeva di doverli cercare.

Quindi i due binari rispondono a due domande diverse, e il confine è la direzione in cui guardano:

bitcollectorbitscanner
GuardaVerso l'interno — l'host su cui giraVerso l'esterno — il segmento su cui si trova quell'host
Risponde a"Cos'è questa macchina, e in che stato si trova?""Cos'altro c'è su questa rete, e ce n'è qualcosa di non censito?"
Vede un dispositivo solo sevi è installato un agenteè visibile da un host che ne ha uno
Invia pacchettiMai — legge l'hostSolo se lo armi, sonda per sonda

Nessuno dei due sostituisce l'altro. Un dispositivo scoperto da bitscanner è una pista: un indirizzo, un MAC, un produttore, un istante di primo avvistamento. Trasformare quella pista in un asset con un proprietario è un lavoro che fai in Asset Management — il compito di bitscanner è assicurarsi che la pista esista.

Cosa riporta con tutto disattivato​

La configurazione predefinita non arma alcuna sonda, e l'agente ha comunque qualcosa da dire, perché il kernel dell'host conosce già i propri vicini.

Misurato su un normale host Linux con la scansione attiva completamente disabilitata — l'impostazione predefinita fornita:

INFO scanguard active scanning is disabled; every probe will be denied
INFO network_collector network intelligence collector starting {"interval": "20s"}
INFO network_collector collection cycle complete
{"queued_for_delivery": ["network_state", "neighbor_table"]}

Entrambi provengono da file che l'host già possiede — /proc/net/arp e la tabella di routing — quindi in questo stato non viene emesso alcun pacchetto.

RecordCosa trasportaRichiede
network_stateLa tabella di routing: destinazione, gateway, interfaccia, metrica, flagnulla
neighbor_tableLa cache ARP/NDP del kernel: indirizzo, MAC, interfaccia, statonulla
neighbor_discoveryL'inventario arricchito dei vicini: indirizzo, MAC, produttore, tipo di dispositivo, raggiungibilità, primo/ultimo avvistamento — più le subnet su cui sono stati trovatiscanning.probes.neighbor_discovery
gateway_discoveryI primi hop in uscita da questo host, con attribuzione del MACscanning.probes.gateway_discovery
service_discoveryResponder mDNS/SSDP, attribuiti al vicino che ha rispostoscanning.probes.service_discovery

Ogni record viaggia nello stesso envelope — schema_version, type, agent_id, timestamp, sequence, payload, checksum — e il checksum è un controllo di integrità SHA-256 sull'intestazione e sul payload dell'envelope, non una firma. bitscanner non dispone della catena delle evidenze firmata e concatenata tramite hash di bitcollector; se ti serve un artefatto che un auditor possa verificare offline, quello è compito del collector, non di questo agente.

Come eseguirlo​

bitscanner è un singolo binario statico. Verificalo prima, poi:

# What you have
bitscanner version
# BitScanner 0.1.3-ga (commit: 7db3d4c, built: 2026-08-09T09:54:40Z, go1.25.12, linux/amd64)

# Write a fully commented starting configuration
bitscanner config init --config /etc/bitscanner/config.yaml

# Check it BEFORE you start anything
bitscanner config validate --config /etc/bitscanner/config.yaml
# Configuration is valid.

# Run in the foreground
bitscanner run --config /etc/bitscanner/config.yaml

# Turn up the detail while you are setting it up
bitscanner run --config /etc/bitscanner/config.yaml --log-level debug --log-format console

config init scrive lo stesso file annotato che questa pagina sta descrivendo: ogni chiave di scansione, cosa invia davvero ciascuna sonda e perché le impostazioni predefinite sono quelle che sono. È fatto per essere letto.

--log-level e --log-format sono flag, e soltanto flag

Non esiste alcun blocco logging:. C'era — level, format, output_path, max_size, max_backups, max_age — e nessuna di quelle chiavi veniva letta da alcun codice, quindi il logger era configurato interamente dalla riga di comando, qualunque cosa dicesse il file. Il blocco è stato rimosso, e una configurazione che lo contiene ancora viene rifiutata per nome:

Error: configuration validation failed: failed to load config: logging is set but no
longer exists: the whole `logging` block was parsed and read by nobody […] Use the
flags, which do work: `--log-level` (debug|info|warn|error) and `--log-format`
(json|console). There is no replacement for output_path or for the rotation keys — log
rotation was never implemented […]

Lo stesso trattamento vale per control_plane.retry_interval, control_plane.max_retries, security.allow_root_only, security.secure_bootstrap, security.audit_log_path e security.encrypt_local_data. Due di queste avevano true come valore predefinito, quindi il file fornito si leggeva come un bootstrap protetto e una cifratura a riposo, mentre né l'uno né l'altra esistevano. Una chiave che non fa nulla non viene fornita, e la sua rimozione viene annunciata alla persona il cui file la contiene anziché essere ignorata in silenzio.

Quanto costa sull'host​

  • Nessuna superficie in ingresso. Verificato su un agente in esecuzione: il processo possiede zero socket in ascolto. Non c'è una porta di salute, non c'è una porta per le metriche e non esiste alcuna chiave di configurazione che ne apra una. Una riserva onesta: con service_discovery armato, l'agente apre socket UDP effimeri e non vincolati per inviare le query mDNS e SSDP e leggerne le risposte. Esistono solo per la durata di un sondaggio — ma «zero socket in ascolto» vale per la configurazione predefinita, non per ogni configurazione.
  • Costa poco quando è silenzioso. Su un host con 118 vicini ARP distribuiti su 27 subnet collegate, un passaggio completo di scoperta dei vicini ha richiesto 71–189 ms per ciclo su quattro cicli consecutivi. Il valore predefinito di modules.network_intelligence.interval è 1m.
  • Un ciclo è un ciclo di scansione. Il budget di host per ciclo e la scadenza di scansione misurata sul tempo reale si azzerano all'inizio di una raccolta e in nessun altro punto, così un segmento lento o intrappolato in un tarpit non può far sconfinare il sondaggio di un ciclo in quello successivo.
  • Niente store-and-forward e nessun tentativo ripetuto. Un batch che non può essere consegnato viene registrato come errore e scartato: non viene salvato su disco né ritentato. Se la destinazione è irraggiungibile per dieci minuti, sono dieci minuti di osservazioni che non avete. Una riga queued_for_delivery viene registrata a ogni ciclo, con o senza scanning attivo, così un errore di consegna non può essere scambiato per un collector fermo — ma «in coda» non significa «consegnato», e l'agente non può affermare più di quanto la destinazione gli abbia risposto.
Questi socket accettavano qualsiasi cosa, in 0.1.3-ga e versioni precedenti

Questa pagina affermava che i socket di scoperta «non accettano nulla che non abbiate sollecitato». Quel controllo non è mai stato implementato. I socket usano un binding jolly, quindi il kernel consegna loro qualsiasi datagramma raggiunga la porta, e nulla confrontava il mittente o il contenuto con la query appena inviata: un datagramma SSDP diventava un dispositivo per il solo fatto di contenere il testo ST:. Qualsiasi cosa in grado di raggiungere quella porta poteva aggiungere al vostro inventario host che non esistono, agli indirizzi che preferiva, registrati come osservazioni compiute da questo agente.

Il controllo ora esiste nel codice sorgente e pone due domande. Da chi: il mittente deve trovarsi all'interno dei vostri scanning.allowed_cidrs e superare ogni altra regola che la guardia applica a un bersaglio di sondaggio. Che cosa: il datagramma deve rispondere alla query appena inviata — per mDNS, dalla porta 5353, con il bit di risposta impostato e l'identificativo di transazione imprevedibile generato da questo agente; per SSDP, una risposta M-SEARCH HTTP 200 che porti sia ST sia USN, mai un NOTIFY non sollecitato.

Non è ancora in un binario pubblicato. Se state eseguendo 0.1.3-ga o una versione precedente, trattate i risultati di service_discovery come indizi non autenticati: sono attribuibili a chi ha inviato il pacchetto, che non è necessariamente il dispositivo indicato. Tutte le altre sonde non sono interessate — registrano ciò che ha restituito una connessione aperta da questo agente.

Questa release non ha alcun tetto configurabile di memoria o CPU

A differenza di bitcollector, bitscanner non ha alcuna chiave max_memory_mb / max_cpu_percent. Un controllo di salute periodico registra i conteggi di allocazione e di goroutine e avvisa oltre i 50 MB e le 1.000 goroutine, e questo è tutto. Limitalo con i controlli del tuo sistema di init (MemoryMax=, CPUQuota= in un'unità systemd) se ti serve un limite rigido su un host che conta.

Verificare questa release​

La directory della release di bitscanner contiene i binari, SHA256SUMS, una firma cosign su quel manifest e — per ogni binario — un .sig, un'attestazione .att e un .sbom.json. Verifica per prima la firma sul manifest, poi i checksum:

cosign verify-blob --key cosign.pub --bundle SHA256SUMS.sig \
--insecure-ignore-tlog=true SHA256SUMS
# WARNING: Skipping tlog verification is an insecure practice […]
# Verified OK

sha256sum -c SHA256SUMS
# bitscanner-linux-amd64: OK
# bitscanner-linux-arm64: OK

Entrambi i comandi qui sopra sono stati eseguiti sugli artefatti 0.1.3-ga forniti, e così anche il controllo negativo: alterare un byte di SHA256SUMS fa uscire lo stesso comando verify-blob con codice non zero e invalid signature when validating ASN.1 encoded signature. Un passo di verifica che non hai mai visto fallire non è un passo di verifica.

È la stessa chiave del resto della famiglia

bitscanner è firmato con la chiave della famiglia bits — quella che usano bitcollector e bitenforcer, e quella pubblicata su cosign.pub. Se hai già verificato una release bits, hai già l'ancora di fiducia, e non dovrebbe essere cambiata. Vale la pena leggere una volta perché la verifica della chiave è il passo portante, compreso il confronto incrociato dell'impronta.

A partire da 0.1.3-ga, bitscanner include lo stesso insieme di artefatti del resto della famiglia — un .sig, un'attestazione .att e un .sbom.json accanto a ogni binario, più un SHA256SUMS.sig sul manifest — quindi ogni passo di quella pagina le si applica, compresi i passi 4 e 5. Le release precedenti includevano solo il manifest firmato; se stai verificando 0.1.2-ga o una versione più vecchia, quei due passi non hanno nulla su cui fare il confronto.

Puoi recuperare la chiave via DNS anziché via HTTPS

La chiave pubblica completa è pubblicata come record TXT, il che è utile in uno script di installazione:

dig +short TXT _cosign-key.cert-ix.com | tr -d '"' | sed 's/.*key=//' \
| base64 -d | openssl pkey -pubin -inform DER -out cosign.pub

Il DNS è un sistema diverso dal server web, quindi una chiave ottenuta in questo modo e una scaricata dal sito sono due fonti indipendenti che devono coincidere — che è esattamente il confronto incrociato che verificare i tuoi download ti chiede di fare. Il record complementare _cosign.cert-ix.com porta solo l'impronta, se vuoi confrontare soltanto quella.

Piattaforme​

0.1.3-ga pubblica due binari firmati, e il vuoto è deliberato:

PiattaformaPubblicataPerché
Linux amd64Sì
Linux arm64Sì
macOS amd64/arm64NoTrattenuta — vedi sotto
Windows amd64NoTrattenuta — vedi sotto

bitscanner è solo per Linux perché i lettori che gli stanno sotto sono implementazioni Linux. I due record che produce con tutte le sonde disattivate — neighbor_table e network_state — provengono dalla cache ARP/NDP del kernel e dalla tabella di routing così come Linux le espone. È questo che consente alla configurazione predefinita distribuita di riportare qualcosa di reale mettendo zero pacchetti in rete, ed è la proprietà su cui si regge l'intero modello di armamento a due interruttori.

macOS e Windows espongono le stesse informazioni, attraverso interfacce completamente diverse. Portare quei lettori è un lavoro vero, con il suo carico di test, e non è stato fatto. Una build per quelle piattaforme compilerebbe e poi riporterebbe una tabella dei vicini vuota su un host che ha vicini — indistinguibile, per chi legge l'output, da un segmento tranquillo. Un risultato vuoto che significa «non implementato qui» è l'output più pericoloso che questo agente possa produrre, perché tutta la sua ragion d'essere è dirti quando c'è qualcosa in rete che il tuo inventario non spiega.

Quindi non c'è alcuna build macOS o Windows da scaricare. Se devi osservare un segmento su cui ci sono solo host macOS o Windows, metti bitscanner su un qualsiasi host Linux collegato a esso: riporta sul segmento, non su se stesso, quindi un solo host Linux basta a coprire il dominio di broadcast.

Passi successivi​

  • La scansione, e i due interruttori che la armano — la scala delle sonde, esattamente cosa mette sulla rete ciascuna sonda, perché le dichiarazioni di accettazione possono essere scritte solo in un file, e la guardia che decide nel momento in cui il pacchetto parte.
  • Cosa lascia l'host — il traffico in uscita, l'enrolment, i file dei segreti e i limiti dichiarati con onestà con cui questa release viene fornita.
  • Verificare i tuoi download — l'ancora di fiducia, e perché conta più della firma.
  • bitcollector — la metà della risposta che guarda verso l'interno.
  • Cos'è bits? — come si incastrano i quattro compiti.

Questa pagina ti è stata utile?