bitscanner
bitscanner findet die Geräte, die Ihr Inventar nicht enthält.
bitcollector liest den Host, auf dem er läuft. bitscanner blickt von diesem Host aus
nach außen auf das Segment um ihn herum — und die Antwort, auf die es ankommt, ist die,
die nichts auf Ihrer Asset-Liste erklärt.
| Release | 0.1.3-ga, Commit 7db3d4c, gebaut mit go1.25.12 |
| Plattformen | Nur Linux amd64/arm64 — macOS und Windows werden nicht veröffentlicht, und warum |
| Lieferkette | Reproduzierbarer Build (zweimal gebaut, verweigert, sofern nicht byte-identisch), CycloneDX-SBOM und cosign-Attestierung je Binary, Schwachstellen-Gate, cosign-Signatur je Binary und über SHA256SUMS |
| Eingehende Netzwerkfläche | Kein Dienst lauscht. Kein Health-, Metrics- oder Admin-Port und kein Schlüssel, der einen öffnet. Gemessen bei deaktiviertem Scanning: null lauschende Sockets. service_discovery nutzt im aktivierten Zustand kurzlebige, ungebundene UDP-Sockets; ein dort eintreffendes Datagramm wird nur dann zu einem Inventareintrag, wenn es die soeben gesendete Anfrage beantwortet und aus allowed_cidrs stammt — in 0.1.3-ga und früher nicht geprüft, siehe unten |
| Ausgehend | Ausschließlich https, an die Endpunkte, die Sie konfigurieren. Es wird niemals einem Redirect gefolgt |
| Schreibzugriffe auf den Host | Sein eigenes Datenverzeichnis (agent.data_dir), das den Enrolment-Schlüssel und das Agent-Token enthält, 0600 innerhalb eines Verzeichnisses, das auf 0700 gezwungen wird |
| Pakete im Netz in der Voreinstellung | Null. Beide Scharfstell-Schalter werden ausgeschaltet ausgeliefert |
Bevor Sie ihn ausführen, verifizieren Sie den Download — die bitscanner-spezifischen Schritte stehen weiter unten.
Zwei Dinge sind hier groß genug für eigene Seiten: das Scannen und das Zwei-Schalter-Modell zum Scharfstellen — die Sondenleiter, was jede Sonde ins Netz sendet, und der Guard, der jedes einzelne Paket freigibt — und was den Host verlässt, einschließlich Enrolment, ausgehendem Verkehr und den Grenzen, mit denen dieses Release ausgeliefert wird.
Die Frage, die bitcollector nicht beantworten kann
Ein aus Agenten zusammengesetztes Inventar kann immer nur die Maschinen enthalten, auf denen jemand einen Agenten installiert hat. Der Drucker, der Switch im Labor, der Laptop des externen Dienstleisters, die VM, die ein Team für eine Migration hochgezogen und nie jemandem gemeldet hat — keines dieser Geräte meldet sich von selbst, und keines fehlt wegen eines technischen Fehlers. Sie fehlen, weil niemand wusste, dass er nachsehen müsste.
Die beiden Binaries beantworten also zwei verschiedene Fragen, und die Grenze ist die Richtung, in die sie blicken:
bitcollector | bitscanner | |
|---|---|---|
| Blickt | Nach innen — auf den Host, auf dem er läuft | Nach außen — auf das Segment, an dem dieser Host hängt |
| Beantwortet | „Was ist diese Maschine, und in welchem Zustand ist sie?“ | „Was ist sonst noch an dieser Leitung, und ist davon etwas ungeklärt?“ |
| Sieht ein Gerät nur, wenn | darauf ein Agent installiert ist | es von einem Host aus sichtbar ist, auf dem einer läuft |
| Sendet Pakete | Nie — er liest den Host | Nur wenn Sie ihn scharfstellen, Sonde für Sonde |
Keiner ersetzt den anderen. Ein Gerät, das bitscanner entdeckt, ist eine Spur: eine Adresse, eine MAC, ein Hersteller, ein Zeitpunkt der Erstsichtung. Aus dieser Spur ein Asset mit einer verantwortlichen Person zu machen, ist Arbeit, die Sie im Asset Management erledigen — bitscanners Aufgabe ist es, dafür zu sorgen, dass die Spur überhaupt existiert.
Was er meldet, wenn alles ausgeschaltet ist
Die Voreinstellung stellt keine einzige Sonde scharf, und der Agent hat trotzdem etwas zu sagen, denn der Kernel des Hosts kennt seine Nachbarn bereits.
Gemessen auf einem gewöhnlichen Linux-Host mit vollständig deaktiviertem aktivem Scannen — der ausgelieferten Voreinstellung:
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"]}
Beides stammt aus Dateien, die der Host ohnehin hat — /proc/net/arp und die Routingtabelle
—, sodass dieser Zustand überhaupt keine Pakete erzeugt.
| Datensatz | Was er trägt | Benötigt |
|---|---|---|
network_state | Die Routingtabelle: Ziel, Gateway, Schnittstelle, Metrik, Flags | nichts |
neighbor_table | Den ARP/NDP-Cache des Kernels: Adresse, MAC, Schnittstelle, Zustand | nichts |
neighbor_discovery | Das angereicherte Nachbar-Inventar: Adresse, MAC, Hersteller, Gerätetyp, Erreichbarkeit, erste/letzte Sichtung — dazu die Subnetze, in denen sie gefunden wurden | scanning.probes.neighbor_discovery |
gateway_discovery | Die ersten Hops aus diesem Host heraus, mit MAC-Zuordnung | scanning.probes.gateway_discovery |
service_discovery | mDNS-/SSDP-Responder, dem Nachbarn zugeordnet, der geantwortet hat | scanning.probes.service_discovery |
Jeder Datensatz ist in denselben Umschlag verpackt — schema_version, type, agent_id,
timestamp, sequence, payload, checksum — und die Prüfsumme ist eine
SHA-256-Integritätsprüfung über Umschlag-Header und Nutzlast, keine Signatur. bitscanner
hat nicht bitcollectors signierte, per Hash verkettete
Nachweiskette; wenn Sie ein Artefakt brauchen, das ein Auditor
offline verifizieren kann, ist das die Aufgabe des Collectors, nicht die von bitscanner.
Ausführen
bitscanner ist ein einzelnes statisches Binary. Verifizieren Sie es zuerst, dann:
# 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 schreibt genau die kommentierte Datei, die diese Seite beschreibt: jeden
Scan-Schlüssel, was jede Sonde tatsächlich sendet, und warum die Voreinstellungen so sind, wie
sie sind. Sie ist zum Lesen gedacht.
--log-level und --log-format sind Flags, und nur FlagsEs gibt keinen logging:-Block. Früher gab es einen — level, format, output_path,
max_size, max_backups, max_age —, und kein einziger dieser Schlüssel wurde von
irgendeinem Code gelesen; der Logger wurde also vollständig über die Kommandozeile
konfiguriert, was auch immer in der Datei stand. Der Block ist verschwunden, und eine
Konfiguration, die ihn noch enthält, wird namentlich zurückgewiesen:
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 […]
Dieselbe Behandlung gilt für control_plane.retry_interval, control_plane.max_retries,
security.allow_root_only, security.secure_bootstrap, security.audit_log_path und
security.encrypt_local_data. Zwei davon standen voreingestellt auf true, sodass die
ausgelieferte Datei sich las wie ein abgesicherter Bootstrap und Verschlüsselung im
Ruhezustand — obwohl es beides nicht gab. Ein Schlüssel, der nichts tut, wird nicht
ausgeliefert, und seine Entfernung wird der Person angekündigt, deren Datei ihn enthält, statt
stillschweigend ignoriert zu werden.
Was er auf dem Host kostet
- Keine eingehende Fläche. An einem laufenden Agenten verifiziert: Der Prozess besitzt
null lauschende Sockets. Es gibt keinen Health-Port, keinen Metrics-Port und keinen
Konfigurationsschlüssel, der einen öffnet.
Eine ehrliche Einschränkung: Mit aktiviertem
service_discoveryöffnet der Agent kurzlebige, ungebundene UDP-Sockets, um mDNS- und SSDP-Anfragen zu senden und die Antworten zu lesen. Sie existieren nur für die Dauer einer Sonde — „null lauschende Sockets" gilt aber für die Standardkonfiguration, nicht für jede Konfiguration. - Günstig, solange es ruhig ist. Auf einem Host mit 118 ARP-Nachbarn in 27 angeschlossenen
Subnetzen dauerte ein vollständiger Durchlauf der Nachbarerkennung 71–189 ms pro Zyklus,
über vier aufeinanderfolgende Zyklen. Die Voreinstellung von
modules.network_intelligence.intervalist1m. - Ein Zyklus ist ein Scan-Zyklus. Das Host-Budget je Zyklus und die Echtzeit-Frist für den Scan werden zu Beginn einer Erfassung zurückgesetzt und sonst nirgends, sodass ein langsames oder mit einem Tarpit versehenes Segment das Sondieren eines Zyklus nicht in den nächsten hineinlaufen lassen kann.
- Kein Store-and-Forward und kein Retry. Ein Batch, der nicht zugestellt werden kann, wird als Fehler protokolliert und verworfen — er wird weder auf die Festplatte geschrieben noch erneut versucht. Ist das Ziel zehn Minuten lang nicht erreichbar, fehlen Ihnen zehn Minuten an Beobachtungen. In jedem Zyklus wird eine
queued_for_delivery-Zeile protokolliert, unabhängig davon, ob Scanning aktiv ist, damit ein Zustellfehler nicht mit einem stehenden Collector verwechselt wird — aber „eingereiht“ ist nicht „zugestellt“, und der Agent kann nicht mehr sagen, als das Ziel ihm geantwortet hat.
0.1.3-ga und früherAuf dieser Seite stand, die Discovery-Sockets „akzeptieren nichts, was Sie nicht angefordert
haben". Diese Prüfung war nie implementiert. Die Sockets sind an die Wildcard-Adresse
gebunden, der Kernel übergibt ihnen also jedes Datagramm, das den Port erreicht, und nichts
verglich Absender oder Inhalt mit der soeben gesendeten Anfrage — ein SSDP-Datagramm wurde
allein deshalb zu einem Gerät, weil es den Text ST: enthielt. Alles, was diesen Port erreichen
konnte, konnte Ihrem Inventar Hosts hinzufügen, die es nicht gibt, unter Adressen eigener Wahl,
verzeichnet als Beobachtungen dieses Agenten.
Die Prüfung existiert jetzt im Quellcode und stellt zwei Fragen. Von wem: Der Absender muss
innerhalb Ihrer scanning.allowed_cidrs liegen und jede weitere Regel erfüllen, die der Guard
auf ein Sondenziel anwendet. Was: Das Datagramm muss die soeben gesendete Anfrage
beantworten — bei mDNS von Port 5353, mit gesetztem Antwort-Bit und der unvorhersehbaren
Transaktions-ID, die dieser Agent erzeugt hat; bei SSDP eine HTTP-200-M-SEARCH-Antwort, die
sowohl ST als auch USN trägt, niemals ein unaufgefordertes NOTIFY.
In einem veröffentlichten Binary ist das noch nicht enthalten. Wenn Sie 0.1.3-ga oder
älter betreiben, behandeln Sie service_discovery-Ergebnisse als nicht authentifizierte
Hinweise: Sie sind demjenigen zuzurechnen, der das Paket gesendet hat, und das ist nicht
zwangsläufig das genannte Gerät. Alle anderen Sonden sind nicht betroffen — sie verzeichnen,
was eine von diesem Agenten geöffnete Verbindung zurückgab.
Anders als bitcollector hat bitscanner keinen Schlüssel
max_memory_mb / max_cpu_percent. Ein periodischer Health-Check protokolliert Allokations-
und Goroutine-Zahlen und warnt oberhalb von 50 MB und 1.000 Goroutinen — mehr ist es nicht.
Begrenzen Sie ihn mit den Mitteln Ihres eigenen Init-Systems (MemoryMax=, CPUQuota= in
einer systemd-Unit), wenn Sie auf einer Maschine, auf die es ankommt, eine harte Grenze
brauchen.
Dieses Release verifizieren
Das bitscanner-Release-Verzeichnis enthält die Binaries, SHA256SUMS, eine cosign-Signatur
über dieses Manifest und — je Binary — eine .sig, eine .att-Attestierung und eine
.sbom.json. Verifizieren Sie zuerst die Signatur über das Manifest, dann die Prüfsummen:
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
Beide Befehle oben wurden gegen die ausgelieferten 0.1.3-ga-Artefakte ausgeführt, und die
Negativkontrolle ebenso: Ändert man ein einziges Byte von SHA256SUMS, endet derselbe
verify-blob-Befehl mit einem Exit-Code ungleich null und der Meldung
invalid signature when validating ASN.1 encoded signature. Ein Verifizierungsschritt, den
Sie noch nie haben fehlschlagen sehen, ist kein Verifizierungsschritt.
bitscanner wird mit dem bits-Familienschlüssel signiert — dem, den bitcollector und bitenforcer verwenden, und dem, der unter cosign.pub veröffentlicht ist. Wenn Sie bereits ein bits-Release verifiziert haben, haben Sie den Vertrauensanker schon, und er sollte sich nicht geändert haben. Warum die Schlüsselprüfung der tragende Schritt ist, einschließlich des Fingerabdruck-Abgleichs, lohnt es sich einmal zu lesen.
Seit 0.1.3-ga liefert bitscanner denselben Artefaktsatz wie der Rest der Familie — eine
.sig, eine .att-Attestierung und eine .sbom.json neben jedem Binary sowie eine
SHA256SUMS.sig über dem Manifest —, sodass jeder Schritt jener Seite hier gilt,
einschließlich der Schritte 4 und 5. Frühere Releases lieferten nur das signierte Manifest;
wenn Sie 0.1.2-ga oder älter verifizieren, haben diese beiden Schritte nichts, wogegen sie
prüfen könnten.
Der vollständige öffentliche Schlüssel ist als TXT-Record veröffentlicht, was in einem Installationsskript nützlich ist:
dig +short TXT _cosign-key.cert-ix.com | tr -d '"' | sed 's/.*key=//' \
| base64 -d | openssl pkey -pubin -inform DER -out cosign.pub
DNS ist ein anderes System als der Webserver: Ein so bezogener Schlüssel und ein von der Website
heruntergeladener sind damit zwei unabhängige Quellen, die übereinstimmen müssen — und genau
diesen Abgleich verlangt Ihre Downloads verifizieren von Ihnen. Der
begleitende Record _cosign.cert-ix.com trägt nur den Fingerabdruck, falls Sie ausschließlich
diesen vergleichen wollen.
Plattformen
0.1.3-ga veröffentlicht zwei signierte Binaries, und die Lücke ist beabsichtigt:
| Plattform | Veröffentlicht | Warum |
|---|---|---|
Linux amd64 | Ja | |
Linux arm64 | Ja | |
macOS amd64/arm64 | Nein | Zurückgehalten — siehe unten |
Windows amd64 | Nein | Zurückgehalten — siehe unten |
bitscanner ist Linux-only, weil die darunterliegenden Leser Linux-Implementierungen sind.
Die beiden Datensätze, die er mit abgeschalteten Sonden erzeugt — neighbor_table und
network_state — stammen aus dem ARP/NDP-Cache des Kernels und der Routing-Tabelle, so wie
Linux sie bereitstellt. Genau das ermöglicht es der ausgelieferten Standardkonfiguration, etwas
Reales zu melden und dabei null Pakete ins Netz zu geben, und es ist die Eigenschaft, auf
der das gesamte Zwei-Schalter-Scharfstellungsmodell beruht.
macOS und Windows stellen dieselben Informationen bereit, über völlig andere Schnittstellen. Diese Leser zu portieren ist echte Arbeit mit eigenem Testaufwand, und sie ist nicht geschehen. Ein Build für diese Plattformen würde kompilieren und dann eine leere Nachbartabelle auf einem Host melden, der Nachbarn hat — für jeden, der die Ausgabe liest, nicht von einem ruhigen Segment zu unterscheiden. Ein leeres Ergebnis, das „hier nicht implementiert“ bedeutet, ist die gefährlichste Ausgabe, die dieser Agent erzeugen könnte, denn sein ganzer Zweck ist, Ihnen zu sagen, wenn etwas im Netz ist, das Ihr Inventar nicht erklärt.
Es gibt also keinen macOS- oder Windows-Build zum Herunterladen. Wenn Sie ein Segment beobachten müssen, an dem nur macOS- oder Windows-Hosts hängen, setzen Sie bitscanner auf einen beliebigen daran angeschlossenen Linux-Host: Er meldet über das Segment, nicht über sich selbst, ein einziger Linux-Host genügt also, um die Broadcast-Domäne abzudecken.
Nächste Schritte
- Scannen, und die beiden Schalter, die es scharfstellen — die Sondenleiter, was genau jede Sonde ins Netz sendet, warum die Bestätigungen nur in eine Datei geschrieben werden können, und der Guard, der in dem Moment entscheidet, in dem das Paket hinausgeht.
- Was den Host verlässt — ausgehender Verkehr, Enrolment, Geheimnisdateien und die ehrlichen Grenzen, mit denen dieses Release ausgeliefert wird.
- Ihre Downloads verifizieren — der Vertrauensanker, und warum er wichtiger ist als die Signatur.
- bitcollector — die nach innen gerichtete Hälfte der Antwort.
- Was ist bits? — wie die vier Aufgaben zusammenpassen.
War diese Seite hilfreich?