Maschinelle Übersetzung, nicht von einem Muttersprachler geprüft. Englisch ist die maßgebliche Fassung.

Empfängervertrauen und SeefahrtAuf GitHub bearbeitenQuelle: docs/TRUST-TELEMETRY.md

GNSS-Vertrauen als Sicherheitstelemetrie

kshana trust-telemetry wandelt den GNSS-Vertrauensstrom pro Epoche (Wert 0-100, Band, Gründe) in Signale um, die ein Betriebs- oder Sicherheitszentrum bereits aufnimmt: Prometheus-Metriken, Syslog-Ereignisse in CEF oder LEEF für ein SIEM und optional OpenTelemetry. Es liest den Strom; es ändert nie die Vertrauensbewertung und sendet nichts außer Telemetrie.

Ein Vertrauensergebnis in drei Exportformaten, aus echten Läufen der Engine v0.40.0 (`kshana trust-telemetry`) auf examples/maritime-trust: Prometheus-Textdarstellung (der letzte Vertrauenswert ist 5,9 und das nicht vertrauenswürdige Band ist das gesetzte) sowie die letzten CEF- und LEEF-Nachrichten. Der Befehl veröffentlicht nichts, wenn kein Ziel angegeben ist, hält keine Zugangsdaten und sendet kein Funksignal. Beratende Software, keine typzugelassene Navigationsausrüstung (IEC 61108, IEC 61162): Der Betreiber bleibt für die Navigation des Schiffes verantwortlich.Ein Vertrauensergebnis in drei Exportformaten, aus echten Läufen der Engine v0.40.0 (`kshana trust-telemetry`) auf examples/maritime-trust: Prometheus-Textdarstellung (der letzte Vertrauenswert ist 5,9 und das nicht vertrauenswürdige Band ist das gesetzte) sowie die letzten CEF- und LEEF-Nachrichten. Der Befehl veröffentlicht nichts, wenn kein Ziel angegeben ist, hält keine Zugangsdaten und sendet kein Funksignal. Beratende Software, keine typzugelassene Navigationsausrüstung (IEC 61108, IEC 61162): Der Betreiber bleibt für die Navigation des Schiffes verantwortlich.

Ausführen#

# live stream on stdin -> /metrics on localhost:9464
kshana receiver-trust live <args> | kshana trust-telemetry

# replay a batch result (the score is the epoch's own for a vessel platform, absent otherwise)
kshana trust-telemetry --result session.result.json --print-metrics
kshana trust-telemetry --result session.result.json --print-syslog --format leef

# SIEM over UDP, one event per band change
kshana trust-telemetry --input stream.jsonl --syslog-udp siem.example:514 --format cef --host ops-gw1

Die Eingabe ist das in docs/MARITIME-TRUST.md dokumentierte Live-JSON-Lines-Schema v1.1. Gelesen werden: t_s; state (calibrating|nominal|degraded|untrusted, das Band); score (0-100 oder null); time (die Zeit der Epoche wie angegeben); gate (off|passed|withheld); position (lat_deg, lon_deg, height_m oder null); Gründe sind die Monitore in deductions, dann weitere in alarms; ab Schema 1,3 geometry (status, hdop, pdop, n_used) und die class jedes Abzugs. Andere Schlüssel werden ignoriert, da das Schema nur durch angehängte Schlüssel wächst. Eine Zeile, die sich nicht parsen lässt, wird in kshana_trust_input_errors_total gezählt und übersprungen; Werte außerhalb von 0-100 werden abgelehnt, nicht begrenzt, damit eine Formatänderung auffällt. Der einzige Code, der dieses Format kennt, ist src/telemetry/sample.rs.

/metrics wird ohne Authentifizierung bereitgestellt und verwendet standardmäßig 127.0.0.1:9464. Das Binden an eine andere Adresse gibt eine Warnung aus; stellen Sie es hinter Ihre eigene Zugriffskontrolle. Der Endpunkt bearbeitet jeweils eine Verbindung mit einem Leselimit von 2 s, sodass ein untätiger Client einen Abruf um bis zu diese Zeit verzögern kann; er ist für einen einzelnen Scraper gedacht, nicht für das offene Netz.

Home Assistant und NTP-Geräte (MQTT)#

--print-mqtt gibt ein JSON-Zustandsdokument und Home-Assistant-MQTT-Discovery-Nachrichten aus, --mqtt-tcp <host:port> veröffentlicht sie. Die Discovery (retained, unter homeassistant/...) erzeugt drei Entitäten: Vertrauenswert, Vertrauensband (mit den Gründen als Attribute) und einen Problemsensor untrusted. Das Zustandsdokument geht an <prefix>/state (Standard kshana/trust/state, retained): state, score (null, solange keiner vorliegt), untrusted, t_s, time, reasons, gate und den Hinweis zur beratenden Software; die Position wird nie aufgenommen. Optionen: --mqtt-prefix, --mqtt-node, --mqtt-discovery.

Der Publisher spricht MQTT 3.1.1 mit QoS 0 und liest nur das CONNACK des Brokers. Er hat keine Zugangsdaten und kein TLS, verwenden Sie daher einen Broker im lokalen Netz (oder ein lokales Relay, das sie ergänzt). Die Zustellung läuft in einem eigenen Thread hinter einer Warteschlange von 1024: Ein ausgefallener Broker lässt Nachrichten fallen, was gezählt und am Ende gemeldet wird, und blockiert nie den Strom. Ein NTP-Gerät oder jeder andere Verbraucher, der reines JSON will, kann dieselbe Zustandszeile lesen. Nichts wird an einen Empfänger oder eine Uhr geschrieben. Python, WebAssembly und MCP nehmen format = "mqtt" entgegen und liefern dieselben topic<TAB>payload-Zeilen zurück (dort wird nichts veröffentlicht).

Aus Python, WebAssembly und MCP#

Die Encoder stehen auch als Aufrufe mit Text als Ein- und Ausgabe zur Verfügung, ohne Prozess, Socket oder Uhr: Python kshana.trust_telemetry(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0), der WebAssembly-Export trust_telemetry(input, format, host, input_kind, options_json) und das MCP-Werkzeug trust_telemetry (Plugin-Befehl /kshana-trust-telemetry). format ist prometheus, cef, leef oder otlp; input_kind ist jsonl (der Strom) oder result (ein Stapelergebnis). Sie liefern denselben Text, den die Befehlszeile ausgibt (--print-metrics, --print-syslog), mit denselben Grenzen: Syslog-Zeilen tragen keinen Zeitstempel, host besteht aus höchstens 255 druckbaren ASCII-Zeichen ohne Leerzeichen (andernfalls abgelehnt, hier wie in der Befehlszeile), und eine Antwort, die größer als das Limit der Oberfläche ist (4 MiB bei MCP), wird abgelehnt, weil CEF und LEEF mit syslog_all ein Ereignis pro Epoche schreiben. Nichts wird gesendet, bereitgestellt oder geschrieben; die laufenden Exporter bleiben ein Prozess in der Befehlszeile.

Die Zustellung blockiert nie die Bewertung#

Syslog- und OpenTelemetry-Zustellung laufen in eigenen Threads. Die Eingangsschleife übergibt ihnen nur eine Nachricht oder einen Schnappschuss und wartet nie, sodass ein ausgefallener, langsamer oder nicht lesender Collector den Live-Strom nicht zurückstauen oder /metrics einfrieren kann:

  • jeder Verbindungsaufbau und jeder Schreibvorgang hat ein Limit von 2 s; eine fehlgeschlagene Verbindung wird verworfen und träge neu aufgebaut, mit exponentiellem Backoff von 1 s bis zu 60 s;
  • eine Nachricht, die nicht zugestellt werden kann (Collector ausgefallen, Schreibvorgang abgelaufen, Warteschlange von 1024 voll), wird verworfen und in kshana_trust_syslog_send_failures_total gezählt; alarmieren Sie auf deren Rate;
  • der OpenTelemetry-Exporter erhält eine Kopie des Registers, sodass während der Netzwerk-E/A keine Sperre gehalten wird; läuft ein Export noch, wird der neue Schnappschuss übersprungen (der nächste trägt dieselben kumulativen Summen).

Am Ende der Eingabe wird den Sender-Threads ihre verbleibende Zeit zum Abschluss gelassen.

Prometheus-Metriken#

Metrik Typ Kennzeichnungen Bedeutung
kshana_build_info gauge version konstant 1
kshana_trust_score gauge letzter Wert 0-100; fehlt, wenn die Quelle keinen liefert
kshana_trust_band gauge band 1 für das aktuelle Band, 0 für die übrigen
kshana_trust_gate gauge gate off, passed, withheld, unknown: 1 für den aktuellen Zustand, 0 für die übrigen; fehlt ohne Gate
kshana_trust_position_latitude_degrees, ..._longitude_degrees, ..._height_meters gauge vom Empfänger gemeldete Position; nur mit --expose-position (der Endpunkt ist nicht authentifiziert, und eine Position kann einen Standort oder ein Schiff identifizieren)
kshana_trust_reason_active gauge reason 1, wenn in der letzten Epoche vorhanden
kshana_trust_epochs_total counter band empfangene Epochen
kshana_trust_reason_epochs_total counter reason Epochen, in denen der Grund vorlag
kshana_trust_input_errors_total counter nicht parsbare Eingabezeilen
kshana_trust_reason_overflow_total counter Vorkommen von Gründen, die in reason="other" zusammengefasst wurden (siehe unten)
kshana_trust_syslog_send_failures_total counter nicht zugestellte Syslog-Ereignisse
kshana_trust_epoch_offset_seconds gauge Versatz der letzten Epoche vom Stromanfang
kshana_trust_last_sample_timestamp_seconds gauge Empfangszeit nach Wanduhr; alarmieren Sie auf deren Alter
kshana_trust_geometry gauge status Satellitengeometrie in der letzten Epoche, good, degraded, unknown: 1 für die aktuelle (Eingaben des Schemas 1,3)
kshana_trust_geometry_degraded gauge 1 verschlechtert, 0 gut; fehlt, wenn die Geometrie unbekannt ist (1.3)
kshana_trust_geometry_signal_loss gauge 1, wenn sichtbare Satelliten nicht verfolgt werden, obwohl ihre Geometrie gut ist (das Signal ging verloren, nicht der Himmel; geometry_degraded zeigt weiterhin 1), sonst 0; fehlt, wenn die Geometrie unbekannt ist oder die Eingabe es nicht angibt (1.3)
kshana_trust_geometry_hdop, ..._pdop, ..._used_satellites gauge HDOP, PDOP und verwendete Satelliten in der letzten Epoche; jeweils fehlend, wenn keiner vorliegt (1.3)
kshana_trust_geometry_epochs_total counter status Epochen nach Geometriestatus (1.3)
kshana_trust_geometry_label gauge label Geometrie-Label in der letzten Epoche, good, fair, poor, unknown: 1 für das aktuelle; wird nie bewertet (der Wert zieht nur bei poor ab); aus Eingaben, die das Label tragen (0,36)
kshana_trust_geometry_vdop gauge VDOP in der letzten Epoche; fehlt, wenn keiner vorliegt (0.36)

Das Geometrie-Label ist die wichtigste Größe. Stellen Sie kshana_trust_geometry_label grafisch dar und alarmieren Sie darauf (OTLP kshana.geometry.label, CEF das dritte Feld cs6, LEEF geoLabel): poor ist das einzige Label, bei dem der Wert abzieht. Der Geometriestatus ist beschreibend: degraded umfasst den informativen Fall sky-blocked, der mit gutem oder ausreichendem DOP auftreten kann, alarmieren Sie daher nicht allein auf kshana_trust_geometry_degraded.

Bei Eingaben des Schemas 1,3 trägt kshana_trust_reason_active außerdem ein Label class (geometry, environment, inconsistency) an jedem Grund, der eines mitbrachte: die Klasse des Abzugs in der letzten Epoche. Die Geometrie-Reihen kommen nach allen anderen und nur, sobald eine Eingabeepoche geometry trägt (Live-Schema 1,3, ein Ergebnis der Engine 0,36 oder später), sodass ein Strom oder Ergebnis von 0,35 byte-genau wie zuvor ausgegeben wird. Label-Werte sind feste Mengen (ein unbekannter Status lautet unknown; eine unbekannte Klasse wird verworfen). Alarmieren Sie auf kshana_trust_reason_active{class="inconsistency"} statt allein auf das Band, damit ein schlechter Himmel nicht als Angriff alarmiert; eine Klasse geometry ist eine Aussage über den Himmel, keine Feststellung, dass kein Angriff stattfand (siehe docs/RECEIVER-TRUST.md).

Das Label class gehört zur Identität einer Reihe: Wechselt die Klasse eines Grundes zwischen Epochen (loss-of-lock von environment zu geometry, wenn die verlorenen Satelliten niedrig standen, oder geometry zu inconsistency, wenn das angegebene HDOP dem angegebenen Himmel widerspricht), wird die alte Reihe nicht mehr exportiert und eine neue beginnt. Fragen Sie nach reason mit max by (reason) ab, wenn die Klasse keine Rolle spielt, und rechnen Sie damit, dass ein solcher Wechsel wie das Ende einer Reihe und der Beginn einer anderen aussieht. Die Reihen des Schemas 1,3, das Label class und die CEF/LEEF-Geometriefelder werden durch die eigenen Tests der Engine und durch die CEF-Referenzen (pycef, Logstash) geprüft; die externen Referenzen für Prometheus und OTLP haben noch keinen Strom nach 1,3.

Namen von Gründen werden auf 128 Zeichen gekürzt, und höchstens 64 verschiedene Gründe erhalten eine eigene Reihe; spätere werden unter reason="other" und in kshana_trust_reason_overflow_total gezählt, sodass eine feindliche oder fehlerhafte Eingabe keine unbegrenzte Label-Kardinalität erzeugen kann.

band ist eines von calibrating, nominal, degraded, untrusted, unknown. Namen von Gründen sind die Monitornamen des Stroms (kinematic, heading-course, ...; beim Stapelergebnis cn0-drop, agc, raim).

Ein Beispiel-Dashboard liegt in deploy/grafana/kshana-gnss-trust.json (importieren Sie es und wählen Sie Ihre Prometheus-Datenquelle).

Syslog: CEF und LEEF#

Ereignisse werden in einem RFC-5424-Umschlag (Facility local0, App kshana, Nachrichten-ID GNSSTRUST) über UDP (je ein Datagramm; IPv4 oder IPv6) oder TCP gesendet, standardmäßig durch Zeilenumbruch abgeschlossen oder, mit --syslog-octet-counting, als <length> <message> gerahmt wie in RFC 6587. Standardmäßig wird ein Ereignis pro Bandwechsel gesendet; --syslog-all sendet eines pro Epoche. Der Hersteller wird als Ashforde OU (ASCII) geschrieben, damit kein SIEM ihn falsch dekodiert.

Konzept Syslog-Schweregrad CEF-Schweregrad LEEF sev
calibrating 6 info 0 1
nominal 6 info 1 1
degraded 4 warning 5 5
untrusted 2 critical 9 9
unknown 5 notice 3 3

Feldzuordnung (die Ereignis-ID ist gnss-trust.<band>):

Bedeutung CEF LEEF 2,0 (Trennzeichen ^)
Kategorie cat=gnss-trust cat
sendender Host dvchost devHost
Band cs1 (Label band) band
Gründe, durch Komma getrennt cs2 (reasons) reasons
vorheriges Band cs3 (previousBand) previousBand
Wert cfp1 (trustScore), weggelassen, wenn keiner vorliegt trustScore
Epochenversatz, s cfp2 (epochOffsetSeconds) epochOffsetSeconds
Label der Protokollzeit cs4 (logTime) logTime
Gate-Zustand cs5 (gate) gate
Geometriestatus, dann ; und die Klassen der Abzüge der Epoche, durch Komma getrennt (zum Beispiel degraded;environment,geometry) (Eingaben 1,3); bei Eingaben, die das Label tragen (0,36), ein drittes Feld, ; und das Label, wobei das Klassenfeld dann stets vorhanden ist (zum Beispiel degraded;;poor, good;;fair) cs6 (geometry) geoStatus (nur Status), geoClass (Klassen) und geoLabel (Label)
HDOP (1.3) cfp3 (geometryHdop) geoHdop
PDOP (1.3) cfp4 (geometryPdop) geoPdop (0,36, mit dem Label)
VDOP (0,36, mit dem Label) nicht übernommen: die vier benutzerdefinierten Gleitkommafelder sind belegt geoVdop
verwendete Satelliten (0,36, mit dem Label) cn1 (geometryUsedSatellites), eine Ganzzahl geoUsed
Signalverlust: sichtbare Satelliten werden nicht verfolgt, obwohl ihre Geometrie gut ist (1.3) nicht als Feld übernommen (kein CEF-Wörterbuchschlüssel ist dafür frei): Der Status lautet degraded und die Klasse des Geometrieabzugs environment in cs6 geoSignalLoss=1, nur solange es gilt

In CEF verwendet die Geometrie nur benutzerdefinierte Felder aus dem Wörterbuch (keine erfundenen Schlüssel); das Label läuft in cs6 statt in flexString1, weil der Logstash-CEF-Codec die flexString-Felder nicht abbildet. Die Geometrieereignisse von 1,3, einschließlich der Label-Fälle, sind Teil der CEF-Zeile der Stufe VALIDATED: Beide Referenz-Parser lesen sie wie geschrieben zurück (tests/cef_reference.rs, Änderungen 4 und 5, jeweils registriert, bevor einer der Parser an seinen Fällen lief). Die Felder für Label, VDOP und Satellitenzahl werden nach jedem früheren Feld und jeder früheren Reihe angehängt, und nur für Eingaben, die das Label tragen, sodass eine Eingabe ohne Label genau wie zuvor ausgegeben wird.

Leere Felder werden weggelassen (kein cs2= ohne Gründe). Der Hostname wird auf 255 Zeichen gekürzt. Kopfwerte in CEF maskieren \ und |; Erweiterungswerte maskieren \, = und Zeilenumbrüche. In LEEF-Werten werden ^ und Zeilenumbrüche durch Leerzeichen ersetzt.

OpenTelemetry (standardmäßig aus)#

Bauen Sie mit --features otlp und übergeben Sie --otlp http://host:4318/v1/metrics. Der Exporter sendet per POST OTLP/HTTP-JSON (kshana.trust.score, kshana.trust.band, kshana.trust.epochs, kshana.trust.reason.epochs und bei Eingaben des Schemas 1,3 kshana.geometry.status, kshana.geometry.degraded, kshana.geometry.signal_loss, kshana.geometry.hdop, kshana.geometry.pdop, kshana.geometry.used_satellites und, bei Eingaben, die das Label tragen (0,36), kshana.geometry.label (Attribut label) und kshana.geometry.vdop; die kumulativen Summen tragen startTimeUnixNano) alle --otlp-every Epochen (Standard 10) und am Ende der Eingabe. Er fügt keine Abhängigkeit hinzu und hat kein TLS: Senden Sie an einen Collector auf demselben Host oder in einem vertrauenswürdigen Segment, der über TLS weiterleitet. Endpunkte mit https:// werden abgelehnt.