Python • AIS NMEA 0183

AISMixer

Платформа за обработка и маршрутизиране на AIS потоци

Нормализира · Дедуплицира · Маркира · Маршрутизира · Препраща

Обединявайте AIS източници от стационарни, брегови, пристанищни и мобилни приемници в един контролиран логически поток и го доставяйте до UDP изходите, които се нуждаят от него.

Изходният код на AISMixer е публично достъпен при условията на CC BY-NC 4.0; лицензът не разрешава търговска употреба.

Обработка на AIS потоци

От трафика на приемниците до чист поток с ясни източници

AISMixer обединява транспорта, NMEA сглобяването, метаданните, дедупликацията и доставката в един път за обработка в почти реално време. Компонентите му по време на работа са aismixer — mixer, router и UDPSEC сървър; aismixerctl за локално управление на маршрутизацията и runtime статистика; и nmea_sproxy — проксито при станцията от един локален UDP или сериен/USB източник към една UDPSEC или изрично конфигурирана plain-UDP дестинация.

Гъвкав входящ трафик

Приема некриптиран UDP през IPv4 или IPv6, както и автентикиран и криптиран UDPSEC трафик от станции.

Извличане на AIS изречения

Извлича !AIVDM и !AIVDO от реален изход на приемници и приложения.

Multipart сглобяване

Сглобява фрагменти, пристигнали в напълно произволен ред, в завършени логически съобщения и ги извежда по реда на позициите.

Дедупликация в почти реално време

Взема едно атомарно за групата решение за всяко завършено multipart съобщение — глобално в broadcast режим или отделно за всяка цел при маршрутизиране.

Контролирани TAG метаданни

Управлява NMEA TAG s, c и g през жизнения цикъл на multipart съобщението, като държи метаданните отделени от идентичността за маршрутизиране.

Избрано препращане

Препраща приетите изречения към всеки конфигуриран UDP изход в broadcast режим или към именуваните цели, избрани от логическото маршрутизиране.

Кратък визуален преглед

Как работи AISMixer

Кратка визуална разходка от множество AIS източници през сглобяване, дедупликация, управление на TAG метаданните и логическо маршрутизиране до избрани изходи, включително nmea_sproxy и UDPSEC. Видеото е на английски.

Основа на data plane, подготвена за нативна реализация

Изрична обработка, етапи с ограничен капацитет и унифициран egress

Неизменяемият ingress на ниво байтове преминава през изрично определени етапи с ограничен капацитет в рамките на един процес. След като стане наличен споделен капацитет за обработка, всеки допуснат кадър се свързва с една ProcessingSnapshot и се обработва от PythonDataPlaneProcessor, който притежава състоянието на инстанцията и остава единственият текущ продукционен и референтен процесор. Той връща един подреден неизменяем OutputBatch, чиито стойности ProcessorOutput пренасят точните байтове и числовите идентификатори на целите през egress предаването с ограничен капацитет.

UDP / UDPSEC производители Отделна ограничена опашка с IngressFrame за всеки вход
Ограничено допускане до обработка Backpressure, след което се свързва една ProcessingSnapshot
PythonDataPlaneProcessor със собствено състояние Сканиране на байтове, сглобяване, TAG политика и дедупликация
Ограничено предаване на подреден OutputBatch Точни байтове и изрични числови цели
Унифициран UDP egress Последователно локално изпращане чрез send_to_ids()

Неизменяема ingress граница

Вградените UDP и UDPSEC производители създават неизменяеми IngressFrame обекти на ниво байтове. Bytes-native сканирането и еднократно анализираните метаданни ParsedSentence пренасят информацията за фрагментите и TAG метаданните към обработката без повторно извличане.

Обвързване на snapshot след осигурен капацитет

Капацитетът за обработка се осигурява, преди една неизменяема ProcessingSnapshot да бъде свързана с кадъра. Допуснатата работа запазва тази снимка; кадрите, които още чакат за капацитет, може да видят по-късна локална за процеса подмяна на маршрутизацията.

Python процесор със собствено състояние

Една дългосрочно работеща инстанция на PythonDataPlaneProcessor притежава изменяемото състояние на сглобяването, дедупликацията, източниците, multipart метаданните и процесорните метрики. Днес не съществуват нативен процесор или bindings.

Точни байтове в подредени резултати

Всяко изведено NMEA изречение се кодира като UTF-8 веднъж и се превръща в един точен неизменяем payload в подреден OutputBatch. Всеки ProcessorOutput носи изрични числови идентификатори на целите; multipart фрагментите остават отделни payload-и.

Backpressure и подредено завършване

Когато отделна ingress граница, споделена processing граница или egress граница достигне капацитета си, изпълнението изчаква, вместо да отхвърли елемента в опашката. Непразният пакет спира обработката на следващ кадър до завършването на последователното локално изпращане. Това не осигурява трайност или потвърждение за отдалечена доставка, а UDP остава транспорт със загуби.

Локален за процеса fail-fast жизнен цикъл

Съществените asyncio етапи споделят един жизнен цикъл под fail-fast надзор в рамките на процеса. Неуспех или неочаквано завършване отменя останалите задачи и изчаква тяхното приключване; няма автоматичен рестарт, повторен опит, връщане назад, потвърждение за мрежова доставка или повторно изпращане.

Нужни са точните правила за граничните случаи? Прочетете договора за поведение.

Изрична отговорност за жизнения цикъл

Детерминирано състояние под натоварване

Референтната реализация определя изрично задържаното състояние, напредъка на времето на живот, допускането според капацитета, почистването и наблюдението, вместо да разчита на случайното поведение на контейнерите от данни.

Състояние на дедупликацията

Идентичността е точното изречение или подреденият multipart кортеж в глобален обхват или в обхвата на конкретна цел. TTL е детерминиран, дубликатите не подновяват задържането, а изтеклите записи се премахват, преди да бъде премахнат най-старият активен запис.

Конструкторът на Python обекта приема незадължителен max_entries; текущото свързване в услугата го оставя със стойност None, затова този размер е неограничен в текущата услуга.

Състояние на multipart сглобяването

Фрагментите заемат поредни позиции. Уникалният напредък подновява времето на живот на групата, а точното повторение — не. Конфликтът, изтичането, премахването поради капацитет, завършването и нулирането остават отделни резултати от жизнения цикъл и почистват свързания TAG контекст.

Конструкторът на Python обекта приема незадължителни max_fragments_per_group и max_pending_groups; текущото свързване в услугата оставя и двата със стойност None.

Защита от повторения и сесии

Записите за защита от повторение при handshake, чакащите и активните сесии, както и регистърът на DATA nonce стойностите за всяка ключова епоха имат твърди ограничения на капацитета; по време на опресняване на ключовата епоха в сесията една сесия има най-много три активни епохи. Времето на живот на handshake записите и сесиите се определя от монотонни TTL. Всеки приет DATA nonce обаче се запазва за целия използваем живот на своята епоха, няма собствен TTL и не се изхвърля. Изчерпването на регистъра за текущата епоха води до fail-closed отказ и край на сесията, а възстановяването използва нов автентикиран handshake; изчерпването на чакаща или оттегляща се епоха премахва само нея. Състоянието за миграция на пътя е ограничено до един кандидат и един оттеглен път за сесия.

Чакащ кандидат заменя само по-стар кандидат за същата връзка между физическия слушател и peer-а и запазва активната сесия, докато автентикираното криптирано потвърждение не успее. Сесиите за един и същ peer на отделни физически UDPSEC слушатели са изолирани една от друга; общите ограничения на капацитета остават на ниво процес. Цялото защитено състояние е в паметта, локално за процеса и се губи при рестарт.

Наблюдаемо компонентно и runtime състояние

Собствениците на състоянието за дедупликация, сглобяване и сигурност предоставят неизменяеми вътрешни снимки на жизнения цикъл. Runtime-ът отделно предлага свежи pull-based изгледи към опашките, активността на процесора и egress етапа, както и входния и изходния трафик. Прочитането на който и да е вид снимка не променя състоянието на обработката.

Тези изгледи са локални за процеса и нетрайни; те не са разпределени метрики или система за изнасяне към Prometheus/time-series.

Локално по замисъл. Това състояние не се запазва трайно и не се споделя между процеси. Текущият runtime упражнява надзор над съществените asyncio задачи в рамките на един процес; coordinator/worker процеси, IPC и междупроцесна синхронизация на състоянието все още не съществуват.

Готовност за worker архитектура — реализирана

Граници, подготвени за worker архитектура в един процес

Текущият Python runtime има ограничени и наблюдаеми граници около етапите на обработка. Изменяемото състояние на обработката има изричен собственик на ниво инстанция, работата се допуска само при наличен капацитет, а свежата pull-based статистика прави активността на етапите видима, без да я променя.

Отделен ограничен ingress

Всеки конфигуриран UDP или UDPSEC вход има собствена ограничена опашка, така че натрупаните елементи от един вход да не заемат отделния капацитет на друг.

Допускане само при наличен капацитет

Споделеното допускане до обработка е ограничено. Кадърът получава своята неизменяема ProcessingSnapshot едва след осигуряване на капацитет, а при достигане на капацитета изпълнението изчаква с backpressure.

Собственост на процесорната инстанция

Една процесорна инстанция притежава изменяемото състояние на сглобяването, дедупликацията, източниците, multipart метаданните и процесорните метрики зад изрична граница на жизнения цикъл.

Ограничен подреден egress

Ограничено предаване пренася всеки непразен OutputBatch към последователно локално изпращане. Бариерата за завършване запазва реда на обработка, но не е потвърждение за отдалечено получаване.

Pull-based runtime наблюдаемост

Свежите неизменяеми снимки обхващат състоянието на опашките и backpressure, активността на процесора и egress етапа, както и суровия и допуснатия входен трафик и съобщенията и байтовете за всяка цел.

Готовността за worker архитектура е реализирана; worker процесите не са. Текущата услуга все още използва един процес с наблюдавани asyncio етапи. Няма coordinator процес, отделни ingress или egress worker процеси, multiprocessing, IPC, междупроцесна маршрутизация или агрегиране на метрики, нито автоматичен рестарт и възстановяване на worker процеси. Днес няма нативен процесор или bindings.

Маршрутизиране и логически зони

Опишете политиката на потока чрез идентичности на източници

Статичното логическо маршрутизиране свързва именувани входни източници с именувани UDP изходни цели чрез многократно използваеми множества от източници и подредени маршрути. Имената остават интерфейсът за конфигурация и управление; продукционното съпоставяне използва предварително компилиран план само с числови цели.

Именуван входUDP и UDPSEC източници
Логически зониМножества от идентичности на източници
Подредени маршрутиДекларативен избор на цели
Именуван изходИзбрани UDP цели

Съставни множества от източници

Дефинирайте зони чрез include, union, intersection и difference.

Логически, не географски

Зоните са множества от вътрешни идентичности на източници, а не райони върху карта, MMSI филтри, филтри за плавателни съдове или правила по съдържанието.

Запазен ред и качество за всяка цел

Компилираният план запазва декларирания ред на целите. Режимът с маршрутизация прилага дедупликацията за всяка логическа цел поотделно, така че един път за изпращане да не потиска друг.

Имената остават операторският интерфейс. Локалните за процеса числови идентификатори на цели не са конфигурационни стойности. Идентичността source_id остава отделна от стойността на NMEA TAG s, която се изпраща надолу по потока.

Локално управление и runtime наблюдаемост

Управлявайте маршрутизацията и наблюдавайте runtime активността

Незадължителният локален управляващ слой през POSIX Unix-domain сокет предоставя операции по маршрутизиране и read-only агрегирана runtime статистика и статистика по входове и изходи чрез глобално инсталираната команда aismixerctl.

Състояние и атомарни промени на маршрутизацията

Проверявайте активното поколение, зоните, маршрутите и целите; заменете валидирана моментна снимка или изключете маршрутизацията, за да се върнете към наследения broadcast режим. Незадължителните проверки на поколението отхвърлят остарели промени.

Агрегирана runtime статистика

runtime.statistics отчита състоянието на ограничените опашки и backpressure, активността на процесора и активността на egress при едно свежо локално за процеса извличане.

Входен и изходен трафик

runtime.statistics.inputs разграничава транспортния трафик от приетите кадри. runtime.statistics.outputs отчита локалните изпращания, съобщенията и байтовете за всяка цел.

Локален операторски интерфейс

Използвайте aismixerctl за локални промени на маршрутизацията и read-only наблюдение на runtime състоянието, с четим за операторите изход и JSON за еднократна автоматизация.

Граница на read-only статистиката. Статистиката е в паметта, локална за процеса, нетрайна и се нулира при рестарт. Тя не е постоянна история, разпределени метрики или система за Prometheus/time-series. Успешното локално UDP изпращане не е потвърждение за доставка от отсрещната страна.

Умишлено локално управление. Runtime маршрутите не се запазват след рестарт, конфигурационните файлове не се пренаписват, а адаптери не се създават динамично. Правата върху Unix сокета са текущата граница за оторизация; няма управляващ token на ниво приложение.

Контрол на мрежовите крайни точки

Ограничете разрешените източници и изходните адреси

Малки механизми за контрол на ниво приложение улесняват включването на IPv4 и IPv6 крайни точки в по-широките правила на оператора за защитна стена и маршрутизиране.

Входен allow_from

Ограничете UDP и UDPSEC слушателите до конкретно зададени IP адреси или CIDR мрежи, включително с възможност за изрична пълна забрана.

Изходен source_ip

Обвържете изходящия сокет с конкретно зададен IPv4 или IPv6 адрес на източника и ограничете преобразуването на адреса на целта до същото адресно семейство.

Част от многослойна граница

Тези политики допълват правилата на операционната система за защитна стена и маршрутизиране; те не ги заменят.

source_ip задава обвързване с адрес на източника, а не избор на мрежов интерфейс, таблица за маршрутизиране, маркиране на сокет или SDN.

Защитен транспорт UDPSECv2

Автентикиран транспорт с ограничено локално състояние

UDPSEC е специфичният за проекта AISMixer автентикиран и криптиран UDP транспорт между станции с nmea_sproxy и услугата aismixer. Текущият изходен код реализира UDPSECv2: конфигурирани дългосрочни P-256 ECDSA идентичности, подписано установяване с ефемерен P-256 ECDHE и криптирано потвърждение с пореден номер нула за притежание на ключовете, AES-256-GCM защита на DATA, защита от повторения, автентикирана проверка за активност, опресняване на ключовата епоха в рамките на сесията и автентикирана миграция на пътя. UDPSECv2, включително функциите за непрекъснатост на сесиите, е част от подписаното издание v0.3.0 на изходния код и е включен в подписаните OpenWrt пакети 0.3.0-r1.

Автентикиран ClientHello Подпис с ключ за идентичност и нов ефемерен P-256 ключ
Ефемерен P-256 ECDHE Нова споделена тайна за този handshake
HKDF-SHA256 Независими C2S и S2C ключове
Криптирано потвърждение с пореден номер нула C2S ping, следван от S2C pong
Активна сесия Автентикираният ping повишава сесията; автентикираният pong завършва установяването

Автентикиран ефемерен обмен на ключове

При всеки handshake всяка крайна точка създава нова ефемерна ключова двойка P-256 за ECDHE. Дългосрочните P-256 ключове за идентичност служат единствено за взаимна автентикация чрез ECDSA подписи върху канонични SHA-256 хешове на транскрипта, разделени според ролята; те не участват в ECDHE договарянето на ключове.

HKDF-SHA256 извежда независими C2S и S2C ключове от споделената тайна и автентикирания транскрипт. AES-256-GCM защитава криптираните данни и управляващия трафик.

Криптирано взаимно потвърждение

Клиентът потвърждава чакащата сесия с криптиран ping по C2S с пореден номер нула. Сървърът я повишава в активна само след като удостовери ping, след което връща криптиран pong с пореден номер нула чрез S2C ключа на вече активната сесия; клиентът приема сесията за установена едва след като удостовери този pong.

Несвързани и неправилно форматирани дейтаграми, както и такива с остарял ключ, грешен пореден номер или грешен източник, нито потвърждават чакащата сесия, нито удължават фиксирания срок за потвърждение.

Сесии, ключови епохи и липса на fallback

Сесията е обвързана с автентикираната станция и се идентифицира чрез издаден от mixer-а локатор на сесията, никога чрез IP адреса и порта на източника. След потвърждението NMEA DATA, keepalive ping/pong, управлението в сесията и затварянето без гаранция за доставка са автентикирани и криптирани, а всеки пакет е обвързан със своята сесия и ключова епоха. Получателите пазят всеки приет nonce за живота на неговата епоха и отхвърлят повторенията.

При session_refresh_interval над нула станцията обновява ключовете за трафик в рамките на същата сесия чрез нов подписан ECDHE обмен; това не е нито нова сесия, нито смяна на пътя. UDPSEC няма plaintext reset, NOSESSION възстановяване, downgrade управление или автоматичен fallback към plain UDP и не буферира и не препраща повторно NMEA данни. Защитеното състояние за сесии и повторения е в паметта, локално за процеса, нетрайно и се губи при рестарт.

Обновявайте двете крайни точки заедно: UDPSECv2 в издание v0.3.0 и в текущите OpenWrt пакети 0.3.0-r1 не е съвместим с по-ранни версии, включително с v0.2.1 и с предишните OpenWrt пакети 0.2.1-r4.

Граница на защитата на миналите сесии (forward secrecy): по-късното компрометиране на дългосрочен ключ за идентичност само по себе си не възстановява ключовете на вече приключили сесии, ако старите ефемерни частни ключове и споделените ECDHE тайни вече не са налични и никоя крайна точка не е била компрометирана, докато те са били в паметта. Компрометиран в момента ключ за идентичност позволява представяне за съответната страна в бъдещи сесии. Това реализирано свойство е подкрепено от инженерна проверка, а не от формална криптографска верификация.

Граница на транспорта: UDPSEC автентикира и криптира пакетите с данни и управляващия трафик в своя обхват, но не доказва идентичността или позицията на плавателния съд, физическия произход или липсата на AIS подправяне, не гарантира доставка или ред на UDP дейтаграмите, не защитава компрометирани крайни точки и не осигурява пълна устойчивост срещу отказ на услуга. Той не скрива IP адресите на страните, моментите или размерите на пакетите, нито идентификатора на станцията, предаван като открит текст в ClientHello.

Прочетете политиката за сигурност, договора за поведение, ръководството за nmea_sproxy и Wiki за подробните граници.

Мобилна непрекъснатост

Запазване на сесията на станцията при обичайни мобилни загуби

UDPSEC работи през NAT и CGNAT. Мобилните станции губят пакети, а публичният им IP адрес или UDP порт може да се смени. Полевите тестове показаха, че при смяна на клетката в мобилната мрежа публичният адрес и портът често остават същите, затова UDPSECv2 третира временната загуба различно от реалната смяна на адреса.

Кратка загуба по същия път

Възстановяване на активността. Станцията повтаря с ограничена честота единствения си неотговорен keepalive ping, със същия пореден номер и с ново криптиране всеки път, докато пристигне автентикиран отговор. Една загубена размяна не прекратява сесията; единствената крайна граница е peer_timeout след последното автентикирано доказателство.

Нов публичен адрес при активна сесия

Автентикирана миграция на пътя. На новия адрес не се има доверие автоматично: пакетите от него трябва да бъдат автентикирани с текущите ключове на сесията. След това услугата aismixer изпраща проверка (challenge) към този адрес и пренасочва отговорите си там едва след като автентикираният отговор на станцията пристигне от същия адрес. Проверката се изпраща най-много четири пъти общо, през поне 2 секунди, в рамките на фиксиран 10-секунден прозорец; повторенията подобряват доставката, но не дават права.

Дълго или окончателно прекъсване

Ново автентикирано установяване. Щом бъде достигната границата за активност, станцията извършва нов подписан handshake, а услугата aismixer сама премахва старата неактивна сесия.

Ограничено, не без загуби. Препращането продължава, докато активността е под съмнение, но UDPSEC никога не буферира и не изпраща повторно NMEA данни: изречения, изпратени по време на прекъсване, може да се загубят дори когато сесията оцелее, и никоя сесия не оцелява при всяко прекъсване. Възстановяването на активността по същия път е наблюдавано при реален тест в движение с по-ранна версия от етапа на разработка; миграцията на пътя е преминала end-to-end тестове и тестове за сигурност в симулирана мрежа, но успешна миграция все още не е наблюдавана при полеви тест. И двата механизма са включени в издание v0.3.0.

nmea_sproxy и физически AIS приемници

Свържете мрежови или физически AIS приемници чрез nmea_sproxy

nmea_sproxy е проксито при станцията, което свързва един локален UDP или физически сериен, включително виртуален сериен през USB, AIS вход с един мрежов изход: UDPSEC или изрично конфигуриран plain UDP.

Физически AIS приемник
сериен порт или виртуално серийно устройство през USB
nmea_sproxy
UDPSEC или изрично доверен некриптиран UDP
Мрежов изход aismixer през UDPSEC или plain-UDP получател в доверена мрежа

Реализирани локални входове

  • UDP от локален мрежов приемник или AIS приложение.
  • Физически сериен вход чрез nmea_sproxy, включително виртуални серийни устройства през USB, предоставени от операционната система.

Реализирани изходи

  • Автентикиран и криптиран UDPSEC: проксито автентикира mixer-а и бива автентикирано от него, участва в проверката за активност, отговаря на автентикирани проверки на пътя, изпълнява незадължително опресняване на ключовата епоха в сесията и след окончателна загуба преминава към нов автентикиран handshake.
  • Изрично конфигуриран некриптиран UDP за доверена LAN, VPN или равностойна граница.

Ясен модел на връзката

Един локален вход се свързва с един конфигуриран изход. Проксито препраща само чистото поддържано AIS NMEA съвпадение, като премахва входните TAG блокове, префиксите, околните байтове и терминаторите. nmea_sproxy не смесва, не разклонява към няколко изхода, не маршрутизира, не дедуплицира и не сглобява multipart AIS, а решенията за миграция на пътя принадлежат на услугата aismixer.

Мрежов приемник може да подава локален UDP към nmea_sproxy или директно към услугата aismixer според внедряването. Основният процес на услугата aismixer не чете серийни портове директно. Довереният некриптиран UDP не предоставя UDPSEC криптиране, автентикация, защита срещу повторение или проверка за активност.

Периферно внедряване с OpenWrt

Стартирайте услугата aismixer или nmea_sproxy върху OpenWrt

OpenWrt е поддържана платформа за периферно внедряване както за услугата aismixer, така и за nmea_sproxy. Подписаното AISMixer APK хранилище за OpenWrt 25.12 в момента публикува 0.3.0-r1 версията на Python/procd пакетите, изградена от изданието v0.3.0, за архитектурите x86_64 и mips_24kc. По-ранните подписани файлове 0.2.1-r4 остават достъпни по точните си имена за изрично връщане към предишна версия, но вече не са включени в индексите на хранилището.

Подписани пакети

Инсталирайте aismixer или nmea_sproxy. Споделената зависимост aismixer-common се добавя автоматично при инсталиране на който и да е от двата пакета.

Публикувани индекси на хранилището:

И двете архитектури използват един и същ публичен ключ на хранилището; добавете го в /etc/apk/keys/, преди да използвате който и да е от двата индекса.

SHA-256 на ключа: 170d30219e0e05d59898cd8ccd5ec9804e915df7882ab56b8e869ef6e99c8f9c

Две роли в периферната мрежа

Услугата aismixer може да работи върху периферен хост или маршрутизатор с OpenWrt. nmea_sproxy може да работи самостоятелно близо до приемника с UDP или сериен вход. Изходът му може да бъде некриптиран UDP, а UDPSEC може да защити мрежовата връзка до услугата aismixer.

nmea_sproxy поддържа физически сериен вход, включително виртуални серийни устройства през USB, предоставени от операционната система. CDC ACM устройствата обикновено се появяват като /dev/ttyACM*, а USB-UART адаптерите — като /dev/ttyUSB*. Необходимият драйвер за ядрото може вече да е включен в OpenWrt образа; в противен случай може да е необходим съответният kmod пакет, например kmod-usb-acm за CDC ACM. Вграденият UART и UDP входът не изискват USB сериен драйвер.

Изрично UDPSEC доверие

Пакетите не съдържат частни ключове. OpenWrt init процесът на aismixer подготвя локалната идентичност и при наличен валиден частен ключ може да поправи съответстващия публичен ключ. nmea_sproxy може да създаде каноничната двойка на станцията само когато и двата файла липсват; частична, невалидна или несъответстваща ключова двойка на проксито води до fail-closed отказ без автоматична подмяна. UDPSEC материалът за доверие към отсрещната страна винаги се конфигурира ръчно: поставете публичния ключ на aismixer при станцията и разрешете публичния ключ на станцията в aismixer.

Пакетна архитектура. PKGARCH:=all описва независимия от архитектурата Python и shell payload; това не прави пакета достъпен във всяко хранилище за конкретна цел. В момента изградените, подписани и публикувани хранилища са за x86_64 и mips_24kc, без умишлено изключване на други подходящи цели. Изберете feed архитектурата, конфигурирана на устройството; не я определяйте чрез apk --print-arch.

Записваемо пространство. Python средата за изпълнение и зависимостите изискват значително повече записваемо пространство от минимална OpenWrt инсталация. Проверете свободното място в overlay преди инсталиране; extroot е възможност за внедряване с OpenWrt, когато вътрешното записваемо пространство е ограничено.

Безопасност при първото стартиране. Hook скриптовете на пакета включват и стартират aismixer по време на инсталирането, а началната пакетна конфигурация съдържа широко достъпни plain-UDP слушатели. Затова предварително приложете firewall правила или мрежова изолация и проверете записваемото пространство. Спрете услугата веднага след инсталиране, конфигурирайте слушателите и UDPSEC разрешенията и чак тогава я стартирайте и проверете.

# Текущо публикувани хранилища: x86_64 или mips_24kc
AISMIXER_ARCH='x86_64'

wget -O /etc/apk/keys/aismixer-openwrt.pem \
  https://aismixer.net/openwrt/keys/aismixer-openwrt.pem

REPO_FILE=/etc/apk/repositories.d/customfeeds.list
REPO_URL="https://aismixer.net/openwrt/25.12/${AISMIXER_ARCH}/packages.adb"

grep -qxF "$REPO_URL" "$REPO_FILE" 2>/dev/null || {
  printf '\n# AISMixer OpenWrt 25.12 %s repository\n%s\n' \
    "$AISMIXER_ARCH" "$REPO_URL" >> "$REPO_FILE"
}

apk update
apk add aismixer
/etc/init.d/aismixer stop
vi /etc/aismixer/config.yaml
vi /etc/aismixer/authorized_keys.yaml
/etc/init.d/aismixer start
/etc/init.d/aismixer status
logread -e aismixer

Версия на пакетите. Пакетите 0.3.0-r1 са пакетна ревизия на издание v0.3.0 на изходния код, а не отделно издание на изходния код, и включват UDPSECv2 с мобилна непрекъснатост на сесиите. По UDPSEC те не са съвместими с компилации от v0.2.1, включително с предишните пакети 0.2.1-r4: използвайте една и съща версия от двете страни на UDPSEC връзката. Проверете ревизията на пакета, бележките към издание v0.3.0, списъка на промените и публикуваните версии.

Обновяване и връщане към предишна версия. aismixer и nmea_sproxy изискват точно aismixer-common=0.3.0-r1, затова apk ги обновява заедно, когато са инсталирани и двата. Станция само с nmea_sproxy не се нуждае от aismixer; посочвайте само инсталирани пакети, защото apk add инсталира всеки посочен пакет, а hook скриптът му го включва и стартира. Това локално фиксиране на версията не проверява UDPSEC съвместимостта между устройствата. Редактираните конфигурационни файлове се запазват, а файловете по подразбиране от пакета, който се инсталира, се записват до тях като .apk-new за преглед; нередактираните може да бъдат заменени. Запазете ключовете за идентичност и след всяко обновяване или връщане към предишна версия проверявайте дали всяка станция и нейният mixer използват един и същ UDPSEC порт (новата стойност по подразбиране е 17779). Hook скриптовете при обновяване и връщане към предишна версия само стартират услугите, затова работеща услуга може да продължи да изпълнява стария код, а умишлено спряна услуга може да бъде стартирана: рестартирайте услугите, които трябва да работят, и спрете отново тези, които трябва да останат спрени. Индексите вече съдържат само 0.3.0-r1; връщайте пакетите към предишна версия само с подписани пакетни файлове, които преминават проверката с apk verify преди употреба: или запазени преди това файлове, или архивираните файлове 0.2.1-r4, изтеглени по точните им имена. Никога не използвайте --allow-untrusted и връщайте UDPSEC страните към предишна версия заедно. Пълната процедура е описана в README.

Валидация от край до край. Пътят за внедряване на mips_24kc с по-ранна линия пакети е валидиран от край до край с физически сериен AIS вход, nmea_sproxy, автентикиран UDPSEC, обработка от услугата aismixer, работа на услугите чрез procd и локален контрол и наблюдаемост по време на изпълнение. Този резултат предхожда 0.3.0-r1 и сам по себе си не валидира новата линия пакети или функциите ѝ за непрекъснатост в UDPSECv2 в реални условия.

Само крайна точка при приемника. Използвайте apk add nmea_sproxy вместо apk add aismixer, за да инсталирате самостоятелно проксито при станцията. Вижте README, ръководството за nmea_sproxy и ръководството за внедряване с OpenWrt за пълните стъпки по внедряване и конфигуриране на доверието.

Внедряване и експлоатация за семейството на Debian

Жизнен цикъл със systemd за семейството на Debian, създаден за реални инсталации

За Debian и Raspberry Pi OS хостове със systemd управляваното от хранилището внедряване поддържа съгласувани файловете за изпълнение, операторското състояние, локалното управление на маршрутизацията и read-only runtime статистиката. OpenWrt използва описания по-горе път с APK/procd.

systemd услуга, управлявана от хранилището

Услугата aismixer създава /run/aismixer по време на работа и поддържа незадължителния локален управляващ сокет.

Инсталиране, актуализиране и деинсталиране

Скриптовете за жизнения цикъл съобразяват работата с root или sudo и поддържат внедрените файлове за изпълнение и unit файловете на услугата. Обновяването на aismixer рестартира услугата и може да стартира неактивна услуга; обновяването на nmea_sproxy презарежда systemd, но не стартира или рестартира proxy инстанции. Обновявайте UDPSEC станциите заедно с mixer-а. Вижте README и ръководството за nmea_sproxy.

Запазени операторски настройки

Обичайните операции за инсталиране, актуализиране и деинсталиране запазват конфигурацията на оператора и криптографските ключове.

Глобален операторски CLI

Инсталацията поставя aismixerctl в /usr/local/bin за локална runtime маршрутизация и read-only статистика.

Документация и състояние на проекта

Реализирана основа, ясно отделена от следващите стъпки

README файлът в хранилището е актуалният обзор на проекта за оператори, договорът за поведение определя точната семантика, а Wiki съдържа по-подробни ръководства за архитектурата и внедряването. Roadmap отделя завършената основа от бъдещата работа без обещани срокове.

Състояние на изданията. Последното издание с етикет е v0.3.0, което включва UDPSECv2 и описаната по-горе мобилна непрекъснатост на сесиите. Публикуваните OpenWrt пакети (0.3.0-r1) са изградени от v0.3.0. По-късните промени в main, включително промени в пакетирането, които вече са включени в 0.3.0-r1, са описани в раздела Unreleased на списъка на промените.

Реализирано сега

  • Неизменяеми IngressFrame стойности на ниво байтове, bytes-native сканиране, еднократно анализирани метаданни и PythonDataPlaneProcessor като единствен текущ продукционен и референтен процесор.
  • Отделни ограничени ingress опашки, споделено ограничено допускане до обработка, ограничено egress предаване, backpressure, собственост на състоянието от процесорната инстанция и обвързване на ProcessingSnapshot при допускане.
  • Компилирана маршрутизация само към числови цели, точни неизменяеми байтове с едно кодиране за всяко изведено изречение, подредени OutputBatch резултати и подредена локална бариера за завършване на egress.
  • Логически зони и дедупликация по цели, атомарни локални за процеса промени на маршрутизацията, интерактивен aismixerctl и read-only агрегирана статистика и статистика по входове и изходи.
  • Детерминирано multipart сглобяване, управление на TAG s/c/g и глобална или отделна за всяка цел дедупликация.
  • UDPSEC с автентикиран ефемерен P-256 ECDHE обмен, конфигурирани дългосрочни P-256 ECDSA идентичности, нови AES-256-GCM ключове за двете посоки, криптирано потвърждение за притежание на ключовете, автентикирани и криптирани данни и проверки за активност, както и автентикирано и криптирано затваряне без гаранция за доставка, DATA защита от повторения за цялата ключова епоха, fail-closed ограничено състояние и изолация на сесиите по физически слушател.
  • Част от издание v0.3.0: непрекъснатост на сесиите в UDPSECv2 — възстановяване на активността по същия път, автентикирана миграция на пътя с доказателство за обратна достижимост и опресняване на ключовата епоха в сесията.
  • За всеки процес или systemd instance на nmea_sproxy — един UDP или сериен вход към един UDPSEC или изрично конфигуриран plain-UDP изход за доверена мрежа, плюс IPv4/IPv6 контрол на крайните точки.
  • Внедряване със systemd за семейството на Debian и RuntimeDirectory, скриптове за жизнения цикъл, съобразени с наличните привилегии, запазено операторско състояние и глобален операторски CLI, наред с подписаното APK/procd внедряване за OpenWrt 25.12, публикувано за x86_64 и mips_24kc (0.3.0-r1, изградено от v0.3.0).

Планирана работа

  • Допълнително укрепване на оперативното внедряване, например изрична собственост на управляващия сокет и валидиране под Linux и Raspberry Pi.
  • Координаторен процес с отделни ingress и egress worker процеси, IPC и междупроцесен надзор, а по-късно и нативен процесор зад установените договори с диференциална проверка за съответствие; днес такава реализация няма и не се твърдят резултати за производителност.
  • Операции със състоянието на маршрутизацията, например незадължително трайно съхранение, безопасно презареждане на конфигурацията и история за връщане назад.
  • Изследвания в областта на морската сигурност и качеството на данните, включително откриване на AIS подправяне и аномалии, което днес не е реализирано.
  • Бъдещо разширяване, например допълнителни изходни адаптери и отдалечено автентикирано управление.

Общност на проекта

Общност и контакт

Изберете публичния канал според вида на разговора. Discussions, Ideas и Q&A помагат и на други потребители, а възпроизводимите дефекти се докладват в Issues. Личният контакт остава достъпен в профила на отговорника за поддръжката по-долу.

Разгледайте дискусиите

Разгледайте публичните разговори за проекта, съобщенията, опита от внедряване, полевите тестове и другите теми на общността.

Разгледайте GitHub Discussions

Споделете идея

GitHub Discussions е подходящо място за архитектурни предложения, идеи за интеграция, опит от внедряване, полеви AIS тестове и академично или изследователско сътрудничество, което може да се обсъжда публично.

Отворете Ideas

Докладвайте проблем

Използвайте GitHub Issues за възпроизводими дефекти и конкретна работа по хранилището, а не за обща лична кореспонденция.

Отворете GitHub Issues

Задайте въпрос в Q&A

Използвайте Q&A за конкретни въпроси относно инсталирането, конфигурацията, използването, архитектурата и експлоатацията.

Отворете Q&A

Основател и отговорник за поддръжката

Iliyan Iliev, PhD

Основател, идеолог и отговорник за поддръжката на AISMixer

Разработчик и изследовател в областта на сървърните и мрежовите системи с интереси в обработката на AIS/NMEA данни, морската и регионалната сигурност, транспорта и туризма.

Разработка с ИИ съдействие: ChatGPT подпомага архитектурното обмисляне, планирането, документацията и прегледите. OpenAI Codex подпомага анализа на хранилището, реализацията, тестовете и проверките. Anthropic Claude Code подпомага прегледа на хранилището, поемането на реализацията, кръстосаната проверка, тестовете и валидацията. Тези инструменти се използват под ръководството на основателя; решенията и крайната отговорност за проекта остават човешки.