From kobe
Jump to: navigation, search

Oracul   ❖

Je WebSocketový notifikační server, který doručujenotifikace aplikacím, které jsou připojené, registrované a aktivně poslouchají. Sestává se ze dvou částí. WS serveru, který odesílá notifikace připojeným klientům a klasického http serveru, který příjmá notifikace pro klienty.

Verze[edit]

  • 0.5.14 (06.02.2025) - Podpora POST volání u Pirxe
  • 0.5.6 (22.05.2025) - Možnost logovat konkrétní zařízení
  • 0.5.1 (01.04.2025) - Přístup na server pouze s hash neobo přes ip a heslo

Komponenty[edit]

Výpis základních tříd serveru a popis toho, co zhruba dělají

OraculWSC[edit]

  • Potomek třídy ServletContextListener
  • Nezbytná komponenta která registruje WS listener na Javovském serveru
  • Jinak neprovádí nic dalšího

OraculEndpointConfig[edit]

  • Potomek třídy ServerEndpointConfig.Configurator
  • Jeho úkolem je že údaje z hlavičky předává java properties
  • Tak se k těmto údajům dostanou další třídy ze serveru
[Expand]

▼ ukázka

OraculEndPoint[edit]

  • Potomek třídy Endpoint
  • Hlavní komponenta WS serveru. Zde se vše odehrává.
  • Zahrnuje čtyři subkomponenty
    • Configer - načítá konfigraci serveru
    • Sentinel - hlídá opravnění k připojení
    • Trapper - registruje připojené klienty
    • Bouncer - odmítá nežádoucí připojení

metody[edit]

onOpen[edit]

  • WS Callback
  • Kontroluje se klíč poslaný klientem pomocí Sentinel
  • Odmítají se seriová čísla pomocí Bouncer
  • Připojuje se MessageHandler a metoda gotMessage

onClose[edit]

  • Zruší se registrace klienta v třídě Trapper

onError[edit]

  • při chybě

gotMessage[edit]

  • Všechny zprávy od klienta jdou přes tuto metodu
  • zprávy jsou uvozené klíčovým řetězcem. Jsou to:
    • #ping# - volá se metoda ping
    • #log# - provede se log na serveru - klient zatím posílá jen svůj build number #log#12345
    • #ask# - server pošle klintovy verzi serveru v podobě #answer#version: 0.5.29
    • #reg# - zaregistruje se klient v třídě Trapper

ping[edit]

  • pošle na klikenta odpověď #pong# + číslo které přišlo pingem
  • občerství timestamp ve třídě Trapper (detekuje se tím živé připojení)

Trapper[edit]

  • Udržuje připojené klienty v zásobníku <String, DeviceKeeper>
  • String je session.getId()
  • DeviceKeeper je zásobník, který udržuje informace o spojení

Kontejnery[edit]

DeviceKeeper[edit]

Obsahuje údaje o spojení:

    private String deviceId = "";       // Serial number sent by client
    private String client = "undef";    // Sort of client     
    private long live = 0;              // Time of connection
    private long born = 0;              // Time of last ping/pong
    private Session session = null;     // Session object for message sending

Security[edit]

Zabezpečení komunikace server2server a browser2server

Ověření tokenem[edit]

Klient který se chce připojit na WS serverem musí při připojení oznámit jaký účet používá, poslat správně zašifrovaný hash a na serveru musí být k tomuto účtu příslušn public-key. Jinak se připojení neprovede

Princip[edit]

  • Vygeneruje se pár klíčů
  • private - pro server klient
  • public - pro server master
  • server klient získá čas UTC v ms
  • zakóduje ho pomocí privátního klíče
  • vloží ho do hlavičky zprávy
  • server si z hlavičky vyzvedně klíč
  • rozluští ho pomocí public key
  • porovná poslaný čas s vlastním +/- tolerance

To zajistí, že token posílaný po síti bude mí pořád variabilní podobu a nebude se moci znovu použít

Generování tokenu[edit]

Provádí se na straně klientského serveru

  • Vygeneruje se aktuální UTC timestamp v ms.
  • Pomocí přiděleného PRIVATE_KEY se zakóduje do binární podoby
  • Binární data se převedou na BASE64 hash
  • Vygenerovaný HASH se použije jako TOKEN v hlavičce požadavku
  • Do hlavičky se umístí také přidělěná identifikace Client
  • Client se musí shodovat se prefixem poskytnutého klíče
  • Identifikace slouží k výběru správného páru PRIVATE/PUBLIC KEY

Kontrola tokenu[edit]

Se provádí na straně WS serveru

  • Z hlavičky požadavku se načtou informace
    • Bearer TOKEN
    • Client CLIENT
  • Dle zaslaného CLIENT se vybere příslušný PUBLIC_KEY
  • Zaslaný token se převede z BASE64 do binární podoby
  • Binární data se dekódují Pomocí PUBLIC_KEY
  • Provede se pokus převést dekódovaná data na long value
  • long value se porovná s aktuálním timestampem na serveru
  • Při vyhodnocování je akceptovaná maximální odchylka 10 minut

Praxe[edit]

Pro generování klíčů je použit script

[Collapse]
/home/bilbo/acta/dev/tomcat/kobe/oracul/bin/generate-key.sh troll
#!/bin/bash
# vygeneruje pár klíčů pro komunikaci server2server

# Zkontrolovat, jestli je parametr předán
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <keyname>"
    exit 1
fi

KEYNAME=$1

# Vytvořit adresář /keys pokud neexistuje

mkdir -p ../keys

# Vygenerovat soukromý klíč
openssl genpkey -algorithm RSA -out ../keys/${KEYNAME}-private.pem -pkeyopt rsa_keygen_bits:512

# Vygenerovat veřejný klíč
openssl rsa -pubout -in ../keys/${KEYNAME}-private.pem -out ../keys/${KEYNAME}-public.pem

echo "Klíče byly úspěšně vygenerovány a uloženy do adresáře ../keys:"
echo "../keys/${KEYNAME}-private.pem"
echo "../keys/${KEYNAME}-public.pem"

Vygenerované klíče script uloží do adresáře

/home/bilbo/acta/dev/tomcat/kobe/oracul/keys/troll-private.pem
/home/bilbo/acta/dev/tomcat/kobe/oracul/keys/troll-public.pem
  • Privátní klíč se poskytne klientské aplikaci aby si s ním podepisovala tokeny
  • Public klíč se umístí na sever do adresáře keys aby server mohl ověřovat tokeny

Ověření IP adresou[edit]

Na serveru jsou definované IP adresy, které se považují za ověřené klienty/administrátory

Omezení[edit]

  • IP adresy se až moc často mění
  • Příliš otevřené řešení
  • Vhodné spíše pro umístění v jedné sub síti (VPN, virtuál)
  • Slouží spíše pro testování nebo administraci

Ověření heslem[edit]

Provádí se pouze u administrátorských stránek v kombinaci s kontrolou IP adresy. Hesla a login se ukládají do cookies a jejich expirace je 1 měsíc

Connection[edit]

HTTP side[edit]

Klasický http servlet, který poslouchá na síti a přeposílá data na WS side. Skládá se z url adresy a body, kde jsou přenášená data.

implementace[edit]

URL dresa[edit]

https://oracul.framexx.com:8443/oracul/transfer?id=SERIAL

kde SERIAL je seriové číslo klienta, pod kterým se na server připojil

BODY part[edit]

{"action"="new_file"}

Příklady[edit]

WS side[edit]

URL[edit]

Klient se na WS server připojuje pomocí knihovny onyx, která má v sobě zabudovanou WS URL addresu

https://oracul.framexx.com:8443/oracul/ws

Implementace[edit]

Připojení[edit]

OnyxKeeper onk = new OnyxKeeper(Sockets.PUBLIC, mLongKey);
Onyx mONX = new Onyx(this, onk);

Přijmutí zprávy[edit]

Přijatá data přicházejí na callBack onOnyxData

public void onOnyxData(final String data) {
    runOnUiThread(() -> distilData(data));
}

PingPong[edit]

Onyx knihovna udržuje pinpog se serverem a v případě výpadku, restartuje spojení. Interval pinpongu je defaultně nastavený na

    public static final int DEF_BEAT = 55;                  // Default HeartBeat frequency in second 55sec
    public static final long IS_LIVE = 3*DEF_BEAT*1000;	        // 165 sec

Komunikace[edit]

Registarace[edit]

Registrace seriového čísla, které slouží jako adresa kam se má doručit notifikace. Zpráva je odesílaná ze klienta na WS server a je to kromě pinpongu jediná komunikace tímto směrem.

#register#SN123456

Notifikace[edit]

Notifikační data, která jsou posílána na klienta. Jedná se o data, která jsou na serveru přijatá přes HTTP side.

#data#{asdasd}

Reconnection[edit]

V případě přerušení spojení klienta se serverem se klient snaží znovu připojit na server. Má to svá prvidla aby v případě hramadného výpadku, znovunaběhnutí mnoha klientů naráz nezpůsobilo pád serveru.

Pravidla[edit]

  • O rekonexi se stará knihovna Onyx
  • O rekonexi rozhoduje příliš velká prodleva v ping/pongu
[Collapse]

▼ code

        if (mBeatSent - mBeatBack > 0) {
            if (!mReconectionRun) {
                Log.w(TAG, WHO + " - Ping lost detected!");

                for (OnyxInterface oni : getOnis()) {
                    oni.onOnyxDebug("Ping lost detection");
                }

                reconnectRun();
                return;
            }
        } else {
            if (DEBUG) Log.i(TAG, WHO + " - OK");
        }

Mechanismus[edit]

  • Pro každé připojení se vygeneruje ticket kde je čas znovupřipojení randomizován v danném intervalu.
  • Intervaly znovupřipojení se mění podle toho jak dlouho se už klient snaží o připojení.
  • Postupně se intervaly prodlužují
  • Jsou tři stupně intervalů, zde je defince v kódu:
[Collapse]

▼ data

    // Minutes from last kiss, interval from in sec, interval to in sec
    private static int[] ZONE_FAST = {5, 1, 10};
    private static int[] ZONE_WARY = {12, 12, 120};
    private static int[] ZONE_LAZY = {Integer.MAX_VALUE, 30, 300};

Takže pokud už 12 minut neproběhl validní ping/pong tak další pokus připojení bude probíhat v náhodném intervalu od 12 do 120 sekund

Management[edit]

Vnitřní mechanismy usnadňujicí provoz serveru.

Pirx - Notifikace[edit]

Pro lepší identifikaci připojených zařízení třetími stranami slouží notifikace. K tomu byla napsaná knihovna pirx

Konfigurace[edit]

Knihovna má svůj konfigurační soubor, kde jsou definované pro jednotlivé klienty url adresy, kam se oznamuje událost připojení/odpojení

Hodnota client je přebíraná od hodoty kterou se klient připojuje k serveru. Stejnou hodnotu má prefix u public klíče.

  • Možnosti pro method - GET|POST
  • Možnosti pro token - DATE|NONE

Konfigurace se dá načíst a aplikovat při běhu serveru pomocí Servletu Actions a tlačítka RELOAD TRAPPER CONFIG. Servlet je dostupný pouze z předdefinovaných adres nebo pod VPN.

[Collapse]
fish://tomcat@pm-oracul:22/home/tomcat/config/pirx.json
{
  "start": [
    { "client": "framexx", "uri": "http://192.168.88.249/api/device_on?id=", "method":"GET", "token":"DATE" },
    { "client": "remixx", "uri": "http://192.168.88.249/api/browser_on?id=", "method":"GET", "token":"DATE" },
    { "client": "polygon", "uri": "http://192.168.88.249/api/device_on?id=", "method":"GET", "token":"DATE" }
  ],
  "close": [
    { "client": "framexx", "uri": "http://192.168.88.249/api/device_off?id=", "method":"GET", "token":"DATE" },
    { "client": "remixx", "uri": "http://192.168.88.249/api/browser_off?id=", "method":"GET", "token":"DATE" },
    { "client": "polygon", "uri": "http://192.168.88.249/api/device_off?id=", "method":"GET", "token":"DATE" }
  ]
}

Bouncer[edit]

Třída má na starost odmítání zlobyvých klientů Identifikace odmítnutých je na základě poslaného SN

Konfigurace[edit]

Bouncer má svůj konfigurační soubor, podle kterého vyhodnocuje knaves alias syčáky.

[Collapse]
fish://tomcat@pm-oracul:22/home/tomcat/config/bouncer.json
{
  "knaves": [
    "out-PG4d563df7d1b820f1"
  ]
}

Konfigurace se dá načíst a aplikovat při běhu serveru pomocí Servletu Actions a tlačítka RELOAD BOUNCER CONFIG. Servlet je dostupný pouze z předdefinovaných adres nebo pod VPN.

Chronicler[edit]

Třída vrací informaci, zda se mají logovat události k danému klentovi do souboru client.log

Konfigurace[edit]

Chronicler má svůj konfigurační soubor, kde mohoou být definováy clans tedy WS klient, kteří mají být detailněji sledovány. Uvádí se SN WS klienta.

[Collapse]
fish://tomcat@pm-oracul:22/home/tomcat/config/bouncer.json
{
  "clans": [
    "AU0A2320004299"
  ]
}

Konfigurace se dá načíst a aplikovat při běhu serveru pomocí Servletu Actions a tlačítka RELOAD CHRONICLER CONFIG. Servlet je dostupný pouze z předdefinovaných adres nebo pod VPN.

Administrace[edit]

Pro jednoduší přehled co se na Oracul serveru děje, existuje několk administrativních stránek. Všechny stránky mají omezený přístup. Omezení se nastavuje pomocí IP adresy a páru login/heslo

Login[edit]

Umožňuje připojení administrítora

Monitor[edit]

Zobrazí statistické informace o serveru

Register[edit]

Zobrazí seznam připojených klientů

Actions[edit]

Zobrazí ovládací tlačítka serveru. Umožňuje načíst konfiguraci.

Jednotlivé akce

  • RELOAD SECURITY CONFIG - načte znovu konfigurační soubor /home/tomcat/config/oracul.json a uloží joho definice do zásobníků servisy Configer. Takže další přihlášení na server bude konfrontováno s novými pravidly aniž by se musel restartovat server. Nová pravidla se týkají zabezpečení komunikace.
  • RELOAD TRAPPER CONFIG - načte znovu konfigurační soubor /home/tomcat/config/pirx.json a uloží jeho definice do zásobníků servisy Trapper. Takže další přihlášení na server bude konfrontováno s novými pravidly aniž by se musel restartovat server. Nová pravidla se týkají možnosti oznámit třetímu serveru události nastalé na WS scéně. Zatím je to jen operace připojení/odpojení WS clienta.
  • RELOAD BOUNCER CONFIG - načte znovu konfigurační soubor /home/tomcat/config/bouncer.json a uloží jeho definice do zásobníků servisy Bouncer. Takže další přihlášení na server bude konfrontováno s novými pravidly aniž by se musel restartovat server. Nová pravidla se týkají možnosti odmítnout připojení danému zařízení podle jeho UID. To v případě, že zařízení zobí.
  • RELOAD CHRONICLER CONFIG - načte znovu konfigurační soubor /home/tomcat/config/chronicler.json a uloží jeho definice do zásobníků servisy Chronicler. Takže další přihlášení na server bude konfrontováno s novými pravidly aniž by se musel restartovat server. Nová pravidla se týkají možnosti podrobnějšího sledování daného WS klienta podle jeho UID. To v případě, že se zdá že komunikace vázne.
  • EXPEL_CLIENT - umožní násilné odpojení definovaného klienta od WS serveru. Jeho identifikace se provádí pomocí jeho UID.

Nasazení[edit]

Momentálně je Oracul provozován na dvou serverech. Jeden pro účely FrameXX ekosystému, druhý pro účely OnePro. Oba mají nasazené stejnou aplikaci, jen se občas liší verzemi. Taky konfigurace se liší.

FrameXX[edit]

  • IP adresa - 87.236.199.249/192.168.88.231
  • url - https://oracul-ws.framexx.com:8443/oracul/ws
  • Poslední verze - 0.5.4
  • Admin rozhranní
  • podporované účty/klienti
    • framexx - tím se připojuje FrameXX aplikace
    • remote - tím se připojuje datový Backend
    • remixx - tím se připojují browsery Frontendu
    • polygon - tím se připojuje testovací aplikace Polygon Download
    • test - sloužil pro testování a bude odstraněn

OnePro[edit]

  • IP adresa - 87.236.199.249/192.168.88.231
  • url - https://artemisoracul.eu:8443/oracul/ws
  • Poslední verze - 0.5.14
  • Admin rozhranní
  • podporované účty/klienti
    • philips - tím se připojuje Artemis server
    • onepro - tím se připojuje OnePro v případě že je aplikace spojená s ostrým Artemis serverem
    • devonepro - tím se připojuje OnePro v případě že je aplikace spojená s devel Artemis serverem
    • test - sloužil pro testování a bude odstraněn

Development[edit]

Soubory[edit]

Tomcat je umístěn:

/usr/local/share/tomcat9

Lokální konfigurace Oracul kontextu

/usr/local/share/tomcat9/conf/Catalina/localhost/oracul.xml

Deployed aplikace se hledá v

/home/bilbo/acta/dev/tomcat/kobe/oracul/target/oracul.war

Log je uložen v

lnav /home/tomcat/logs/oracul.log

Testování[edit]

K testování přenosu dat na klienta souží jednoduché stránky napsané v PHP

Dotazy na implementaci[edit]

Dotazy byly poslány emailem 2.11.2026

Změna adresy WS serveru[edit]

Dotaz[edit]

Navrhujeme, aby se screeny připojovaly na wss://ws.artemisone.eu místo dnešní https://artemisoracul.eu:8443/oracul/ws

Odpověď

Je to realizovatelné ale nejdříve se musí modifikovat stávající server aby forwardoval požadovanou adresu na už určený port. Pak se bude moci změnit Defaultní adresa na klientovi

Dotaz[edit]

Jde adresu na screenech změnit? Pokud ano, jak: můžeme ji posílat my v konfiguraci přehrávače (podobně jako dnes tlog_server)

Odpověď

Defaultní adresa je napevno zadrátovaná do knihovny Onyx. Dá se měnit jen custom WS url a posílání v konfiguraci je možné.

Dotaz[edit]

mění se jen v nastavení přehrávače přímo na zařízení, nebo jen ve firmwaru?

Odpověď

Mění se jen v OnePro klientovi, s FW nemá nic společného. Po resetu se info ztratí.

Dotaz[edit]

Jde změnit celá adresa, nebo jen host (port a cesta jsou pevné)?

Odpověď

Adresa se bere jako jeden string včetně portu, pokud je definovaný

Obnovení spojení[edit]

Dotaz[edit]

Jak se knihovna Onyx připojuje znovu po výpadku spojení nebo restartu serveru: okamžitě, nebo s rostoucí prodlevou a náhodným rozptylem mezi zařízeními? Jak rychle to zkouší a vzdá to někdy? Potřebujeme vědět, jestli se po restartu serveru připojí všechny screeny ve stejný okamžik.

Odpověď

Doplněno v sekci Reconnection

Klíč pro přihlášení screenů[edit]

Dotaz[edit]

Jakým klíčem a identifikátorem (hlavička Client …) se screeny přihlašují k WS serveru? Je to stejný klíč philips, kterým podepisujeme volání /oracul/transfer?

Odpověď

Ne, je to jiný klíč

Dotaz[edit]

Pokud ne, pošlete nám prosím veřejný klíč (soukromý nepotřebujeme).

Odpověď

Pošlu

Dotaz[edit]

Jde klíč na screenech změnit? Dnešní má 512 bitů, rádi bychom vydali silnější.

Odpověď

Klíč je napevno zadrátovaný v knihovně Onyx. Delší klíč by šel vygenerovat, otázka je zda to má smysl. Tento klíč brání server před neoprávněným obsazením soketů. Ochrana klienta před podvodným ovládáním je zaručena přes certifikát a tam je délka dostatečná. Navíc i sebesilnější privátní klíč klienta jde získat lehce pomocí dekompilace.

Notifikace o připojení[edit]

Dotaz[edit]

Volá Oracul při připojení nebo odpojení screenu nějakou naši adresu, například /api/devices/device_conn? Pokud ano, kterou a s jakými parametry?

Odpověď

Ne, prozatím pouze provede zalogování do runtime logu

Zprávy z firmwaru[edit]

Dotaz[edit]

Co firmware posílá ve zprávě #log#, a používá po připojení #ask# (dotaz na verzi)? Posílá nebo očekává ještě něco mimo zdokumentované #register#, #ping# a #data#?

Odpověď

Doplněno v sekci OraculEndPoint > gotMessage


.