Contents
[hide]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
▼ 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
/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
▼ 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:
▼ 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.
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.
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.
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
- minimální role admin (1)
- https://oracul.framexx.com:8443/oracul/monitor
Register[edit]
Zobrazí seznam připojených klientů
- minimální role admin (1)
- https://oracul.framexx.com:8443/oracul/register
- Zobrazení umožňuje filtrování a řazen výpisu
Actions[edit]
Zobrazí ovládací tlačítka serveru. Umožňuje načíst konfiguraci.
- minimální role root (0)
- https://oracul.framexx.com:8443/oracul/actions
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
.