Машинний переклад, не перевірений носієм мови. Еталоном є англійська версія.

Довіра до приймача та морська галузьРедагувати на GitHubДжерело: docs/TRUST-TELEMETRY.md

Довіра до GNSS як телеметрія безпеки

kshana trust-telemetry перетворює потік довіри до GNSS для кожної епохи (оцінка 0–100, смуга, причини) на сигнали, які центр експлуатації чи безпеки вже приймає: метрики Prometheus, події syslog у CEF або LEEF для SIEM і, за бажання, OpenTelemetry. Вона читає потік; вона ніколи не змінює оцінку довіри і не передає нічого, крім телеметрії.

Один результат довіри у трьох форматах експорту, за реальними прогонами рушія v0.40.0 (`kshana trust-telemetry`) на examples/maritime-trust: текстова експозиція Prometheus (остання оцінка довіри — 5,9, а встановлено смугу недовіри), а також останні повідомлення CEF і LEEF. Команда нічого не публікує, якщо їй не вказано призначення, не зберігає облікових даних і не передає жодного радіосигналу. Консультативне програмне забезпечення, не навігаційне обладнання із затвердженням типу (IEC 61108, IEC 61162): відповідальність за навігацію судна залишається на операторі.Один результат довіри у трьох форматах експорту, за реальними прогонами рушія v0.40.0 (`kshana trust-telemetry`) на examples/maritime-trust: текстова експозиція Prometheus (остання оцінка довіри — 5,9, а встановлено смугу недовіри), а також останні повідомлення CEF і LEEF. Команда нічого не публікує, якщо їй не вказано призначення, не зберігає облікових даних і не передає жодного радіосигналу. Консультативне програмне забезпечення, не навігаційне обладнання із затвердженням типу (IEC 61108, IEC 61162): відповідальність за навігацію судна залишається на операторі.

Запуск#

# 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

Вхід — це живий формат JSON-рядків версії схеми 1.1, задокументований у docs/MARITIME-TRUST.md. Читаються: t_s; state (calibrating|nominal|degraded|untrusted, смуга); score (0–100 або null); time (час епохи, як заявлено); gate (off|passed|withheld); position (lat_deg, lon_deg, height_m або null); причини — це монітори в deductions, потім будь-які інші в alarms; зі схеми 1,3 — geometry (status, hdop, pdop, n_used) і class кожного відрахування. Інші ключі ігноруються, бо схема зростає лише додаванням ключів. Рядок, що не розбирається, зараховується в kshana_trust_input_errors_total і пропускається; оцінки поза 0–100 відхиляються, а не обрізаються, щоб зміну формату було помічено. Єдиний код, що знає цей формат, — src/telemetry/sample.rs.

/metrics віддається без автентифікації й типово прив'язаний до 127.0.0.1:9464. Прив'язка в іншому місці друкує попередження; поставте його за власним контролем доступу. Кінцева точка обробляє одне з'єднання за раз із обмеженням читання 2 s, тож неактивний клієнт може затримати скрейпінг на цей час; вона призначена для одного скрейпера, а не для відкритої мережі.

Home Assistant і пристрої NTP (MQTT)#

--print-mqtt друкує, а --mqtt-tcp <host:port> публікує документ стану JSON і повідомлення виявлення MQTT для Home Assistant. Виявлення (збережене, під homeassistant/...) створює три сутності: оцінку довіри, смугу довіри (з причинами як атрибутами) і датчик проблеми untrusted. Документ стану йде до <prefix>/state (типово kshana/trust/state, збережений): state, score (null, поки немає), untrusted, t_s, time, reasons, gate і консультативне твердження; позиція ніколи не включається. Параметри: --mqtt-prefix, --mqtt-node, --mqtt-discovery.

Публікатор говорить MQTT 3.1.1 із QoS 0 і читає лише CONNACK брокера. Він не має облікових даних і TLS, тож використовуйте брокера в локальній мережі (або локальний ретранслятор, що їх додає). Доставка працює у власному потоці за чергою 1024: мертвий брокер призводить до втрати повідомлень, які підраховуються і повідомляються наприкінці, і ніколи не зупиняє потік. Пристрій NTP або будь-який інший споживач, якому потрібен простий JSON, може читати той самий рядок стану. Нічого не записується в приймач чи годинник. Python, WebAssembly і MCP приймають format = "mqtt" і повертають ті самі рядки topic<TAB>payload (там нічого не публікується).

З Python, WebAssembly і MCP#

Кодувальники також доступні як виклики «текст на вході, текст на виході» без процесу, сокета чи годинника: Python kshana.trust_telemetry(input, format, host="", input_kind="jsonl", expose_position=False, syslog_all=False, unix_nano=0), експорт WebAssembly trust_telemetry(input, format, host, input_kind, options_json) та інструмент MCP trust_telemetry (команда плагіна /kshana-trust-telemetry). format — це prometheus, cef, leef або otlp; input_kind — це jsonl (потік) або result (пакетний результат). Вони повертають той самий текст, який друкує командний рядок (--print-metrics, --print-syslog), із тими самими обмеженнями: рядки syslog не мають мітки часу, host — щонайбільше 255 друкованих символів ASCII без пробілів (інакше відхиляється, тут і в командному рядку), а відповідь, більша за обмеження поверхні (4 MiB в MCP), відхиляється, бо CEF і LEEF з syslog_all записують одну подію на епоху. Нічого не надсилається, не віддається і не записується; запущені експортери залишаються процесом у командному рядку.

Доставка ніколи не зупиняє оцінювання#

Доставка syslog і OpenTelemetry працює у власних потоках. Цикл прийому лише передає їм повідомлення чи знімок і ніколи не чекає, тож мертвий, повільний або нечитаючий збирач не може чинити зворотного тиску на живий потік чи заморозити /metrics:

  • кожне з'єднання й запис мають обмеження 2 s; невдале з'єднання скидається й відновлюється відкладено, з експоненційною затримкою від 1 s до 60 s;
  • повідомлення, яке не можна доставити (збирач недоступний, час запису вичерпано, черга 1024 заповнена), відкидається і підраховується в kshana_trust_syslog_send_failures_total; налаштуйте сповіщення за його частотою;
  • експортеру OpenTelemetry передається копія реєстру, тож під час мережевого вводу-виводу жодне блокування не утримується; якщо експорт ще триває, новий знімок пропускається (наступний міститиме ті самі кумулятивні підсумки).

Наприкінці входу потокам відправників надається решта їхніх обмежень часу для завершення.

Метрики Prometheus#

Метрика Тип Мітки Значення
kshana_build_info gauge version стала 1
kshana_trust_score gauge остання оцінка 0–100; відсутня, якщо джерело її не дає
kshana_trust_band gauge band 1 для поточної смуги, 0 для інших
kshana_trust_gate gauge gate off, passed, withheld, unknown: 1 для поточного стану, 0 для інших; відсутня без шлюзу
kshana_trust_position_latitude_degrees, ..._longitude_degrees, ..._height_meters gauge позиція, повідомлена приймачем; лише з --expose-position (кінцева точка без автентифікації, а позиція може ідентифікувати об'єкт чи судно)
kshana_trust_reason_active gauge reason 1 якщо є в останній епосі
kshana_trust_epochs_total лічильник band отримані епохи
kshana_trust_reason_epochs_total лічильник reason епохи, у яких причина була присутня
kshana_trust_input_errors_total лічильник рядки входу, що не розбираються
kshana_trust_reason_overflow_total лічильник входження причин, згорнуті в reason="other" (див. нижче)
kshana_trust_syslog_send_failures_total лічильник події syslog, що не доставлені
kshana_trust_epoch_offset_seconds gauge зміщення останньої епохи від початку потоку
kshana_trust_last_sample_timestamp_seconds gauge час отримання за настінним годинником; налаштуйте сповіщення за його віком
kshana_trust_geometry gauge status геометрія супутників в останній епосі, good, degraded, unknown: 1 для поточної (входи схеми 1,3)
kshana_trust_geometry_degraded gauge 1 погіршено, 0 добре; відсутня, коли геометрія невідома (1.3)
kshana_trust_geometry_signal_loss gauge 1, коли супутники у видимості не відстежуються, хоча їхня геометрія добра (сигнал втрачено, а не небо; geometry_degraded усе ще дорівнює 1), інакше 0; відсутня, коли геометрія невідома або вхід цього не вказує (1.3)
kshana_trust_geometry_hdop, ..._pdop, ..._used_satellites gauge HDOP, PDOP і використані супутники в останній епосі; кожна відсутня, якщо немає (1.3)
kshana_trust_geometry_epochs_total лічильник status епохи за станом геометрії (1.3)
kshana_trust_geometry_label gauge label мітка геометрії в останній епосі, good, fair, poor, unknown: 1 для поточної; ніколи не оцінюється (оцінка зменшується лише за poor); із входів, що несуть мітку (0,36)
kshana_trust_geometry_vdop gauge VDOP в останній епосі; відсутня, якщо немає (0.36)

Мітка геометрії — головна. Будуйте графіки й налаштовуйте сповіщення за kshana_trust_geometry_label (OTLP kshana.geometry.label, CEF третє поле cs6, LEEF geoLabel): poor — єдина мітка, за якою оцінка зменшується. Стан геометрії описовий: degraded включає інформаційний випадок sky-blocked, який може супроводжуватися добрим або задовільним DOP, тож не надсилайте виклик лише за kshana_trust_geometry_degraded.

Для входів схеми 1,3 kshana_trust_reason_active також несе мітку class (geometry, environment, inconsistency) на кожній причині, що мала її: клас відрахування в останній епосі. Ряди геометрії йдуть після всіх інших і лише тоді, коли епоха входу несе geometry (жива схема 1,3, результат рушія 0,36 або новішого), тож потік чи результат 0,35 відображається байт у байт як раніше. Значення міток — фіксовані набори (невідомий стан читається як unknown; невідомий клас відкидається). Налаштовуйте сповіщення за kshana_trust_reason_active{class="inconsistency"}, а не лише за смугою, щоб поганий небозвід не сприймався як атака; клас geometry — це твердження про небо, а не висновок, що атаки не було (див. docs/RECEIVER-TRUST.md).

Мітка class входить до ідентичності ряду: коли клас причини змінюється між епохами (loss-of-lock з environment на geometry, коли втрачені супутники були низькими, або geometry на inconsistency, коли заявлений HDOP суперечить заявленому небу), старий ряд більше не експортується, а починається новий. Запитуйте за reason із max by (reason), коли клас не має значення, і очікуйте, що такий перехід виглядатиме як завершення одного ряду та початок іншого. Ряди схеми 1,3, мітка class і поля геометрії CEF/LEEF перевіряються власними тестами рушія та оракулами CEF (pycef, Logstash); зовнішні оракули Prometheus і OTLP ще не мають потоку 1,3.

Назви причин обрізаються до 128 символів, і щонайбільше 64 різних причин дістають власні ряди; пізніші підраховуються під reason="other" і в kshana_trust_reason_overflow_total, тож ворожий або помилковий вхід не може створити необмежену кардинальність міток.

band — одне з таких значень: calibrating, nominal, degraded, untrusted, unknown. Назви причин — це назви моніторів потоку (kinematic, heading-course, ...; для пакетного результату — cn0-drop, agc, raim).

Приклад панелі моніторингу міститься в deploy/grafana/kshana-gnss-trust.json (імпортуйте його й оберіть своє джерело даних Prometheus).

Syslog: CEF і LEEF#

Події надсилаються в оболонці RFC 5424 (facility local0, застосунок kshana, ідентифікатор повідомлення GNSSTRUST) через UDP (по одній датаграмі на подію; IPv4 або IPv6) або TCP: за замовчуванням із завершенням символом нового рядка, а з --syslog-octet-counting — із кадруванням <length> <message> за RFC 6587. За замовчуванням надсилається одна подія на кожну зміну band; --syslog-all надсилає по одній на кожну епоху. Постачальник записується як Ashforde OU (ASCII), щоб жодна система SIEM не декодувала його неправильно.

Поняття Серйозність у Syslog Серйозність у CEF LEEF sev
calibrating 6 info 0 1
номінальний 6 info 1 1
деградовані 4 warning 5 5
untrusted 2 critical 9 9
unknown 5 notice 3 3

Відповідність полів (ідентифікатор події — gnss-trust.<band>):

Значення CEF LEEF 2,0 (роздільник ^)
категорія cat=gnss-trust cat
хост-відправник dvchost devHost
band cs1 (мітка band) band
причини, через кому cs2 (reasons) reasons
попередній band cs3 (previousBand) previousBand
оцінка cfp1 (trustScore), пропускається, якщо значення немає trustScore
зсув епохи, с cfp2 (epochOffsetSeconds) epochOffsetSeconds
мітка часу журналу cs4 (logTime) logTime
стан шлюзу cs5 (gate) gate
стан геометрії, далі ; і класи вирахувань епохи, через кому (наприклад, degraded;environment,geometry) (вхідні дані 1,3); для вхідних даних із міткою (0,36) — третє поле, ; і мітка; тоді поле класів завжди присутнє (наприклад, degraded;;poor, good;;fair) cs6 (geometry) geoStatus (лише стан), geoClass (класи) і geoLabel (мітка)
HDOP (1.3) cfp3 (geometryHdop) geoHdop
PDOP (1.3) cfp4 (geometryPdop) geoPdop (0,36, з міткою)
VDOP (0,36, з міткою) не передається: використано чотири власні поля з рухомою комою geoVdop
використані супутники (0,36, з міткою) cn1 (geometryUsedSatellites), ціле число geoUsed
втрата сигналу: супутники в зоні видимості не відстежуються, хоча їхня геометрія хороша (1.3) не передається як поле (для нього немає вільного ключа словника CEF): стан має значення degraded, а клас вирахування геометрії — environment у cs6 geoSignalLoss=1, лише поки умова виконується

У CEF геометрія використовує лише користувацькі поля зі словника (без вигаданих ключів); мітка передається в cs6, а не в flexString1, бо кодек Logstash CEF не зіставляє поля flexString. Події геометрії 1,3, зокрема випадки з міткою, належать до рядка CEF з рівнем VALIDATED: обидва оракульні розбирачі зчитують їх назад так, як їх записано (tests/cef_reference.rs, поправки 4 і 5, кожну зареєстровано до того, як будь-який із розбирачів було запущено на їхніх випадках). Поля мітки, VDOP і кількості супутників додаються після всіх попередніх полів і рядів, і лише для вхідних даних із міткою, тож вхідні дані без неї відтворюються точно так, як раніше.

Порожні поля пропускаються (немає cs2= без причин). Ім'я хоста обрізається до 255 символів. Значення в заголовку CEF екранують \ і |; значення в розширенні екранують \, = і розриви рядків. У значеннях LEEF ^ і розриви рядків замінюються пробілами.

OpenTelemetry (типово вимкнено)#

Зберіть із --features otlp і передайте --otlp http://host:4318/v1/metrics. Експортер надсилає OTLP/HTTP JSON (kshana.trust.score, kshana.trust.band, kshana.trust.epochs, kshana.trust.reason.epochs, а для вхідних даних зі схемою 1,3 — kshana.geometry.status, kshana.geometry.degraded, kshana.geometry.signal_loss, kshana.geometry.hdop, kshana.geometry.pdop, kshana.geometry.used_satellites і, для вхідних даних із міткою (0,36), — kshana.geometry.label (атрибут label) та kshana.geometry.vdop; кумулятивні суми містять startTimeUnixNano) кожні --otlp-every епох (типово 10) і наприкінці вхідних даних. Він не додає жодних залежностей і не підтримує TLS: надсилайте на колектор на тому самому хості або в довіреному сегменті, який пересилатиме далі через TLS. Кінцеві точки https:// відхиляються.