Zum Hauptinhalt springen
Version: 1.0.0

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.

Release0.1.3-ga, Commit 7db3d4c, gebaut mit go1.25.12
PlattformenNur Linux amd64/arm64 — macOS und Windows werden nicht veröffentlicht, und warum
LieferketteReproduzierbarer 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ächeKein 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
AusgehendAusschließlich https, an die Endpunkte, die Sie konfigurieren. Es wird niemals einem Redirect gefolgt
Schreibzugriffe auf den HostSein 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 VoreinstellungNull. 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:

bitcollectorbitscanner
BlicktNach innen — auf den Host, auf dem er läuftNach 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, wenndarauf ein Agent installiert istes von einem Host aus sichtbar ist, auf dem einer läuft
Sendet PaketeNie — er liest den HostNur 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.

DatensatzWas er trägtBenötigt
network_stateDie Routingtabelle: Ziel, Gateway, Schnittstelle, Metrik, Flagsnichts
neighbor_tableDen ARP/NDP-Cache des Kernels: Adresse, MAC, Schnittstelle, Zustandnichts
neighbor_discoveryDas angereicherte Nachbar-Inventar: Adresse, MAC, Hersteller, Gerätetyp, Erreichbarkeit, erste/letzte Sichtung — dazu die Subnetze, in denen sie gefunden wurdenscanning.probes.neighbor_discovery
gateway_discoveryDie ersten Hops aus diesem Host heraus, mit MAC-Zuordnungscanning.probes.gateway_discovery
service_discoverymDNS-/SSDP-Responder, dem Nachbarn zugeordnet, der geantwortet hatscanning.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 Flags

Es 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.interval ist 1m.
  • 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.
Diese Sockets akzeptierten alles, in 0.1.3-ga und früher

Auf 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.

Dieses Release hat keine konfigurierbare Speicher- oder CPU-Obergrenze

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.

Es ist derselbe Schlüssel wie beim Rest der Familie

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.

Sie können den Schlüssel statt über HTTPS auch über DNS beziehen

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:

PlattformVeröffentlichtWarum
Linux amd64Ja
Linux arm64Ja
macOS amd64/arm64NeinZurückgehalten — siehe unten
Windows amd64NeinZurü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​

War diese Seite hilfreich?