Obsah · Kapitola 10 · Zabezpečení provozu

Zabezpečení provozu

← Kapitola 10: Technické požadavky

Hlasový exponát běží veřejně – návštěvník mluví do mikrofonu, server volá placená cloudová API a v configu jsou uloženy klíče a heslo administrace. Bezpečnost není jedna volba v adminu, ale soubor opatření na serveru, v konfiguraci a na fyzickém kiosku. Tato stránka shrnuje doporučené postupy pro produkční nasazení v muzeu, na veletrhu nebo ve firmě.

Přehled – co chránit a kde

Vrstva Co je v sázce Kde v návodu
Vlastní název configu Obecný název config v kořeni – uhodnutelná URL Administrace → Bezpečnost
Config na disku API klíče, heslo admina, MySQL heslo, prompty Config, Administrace
HTTP / webový server Stažení configu URL, přístup k adminu bez HTTPS Ne ke stažení, HTTPS
Administrace Změna nastavení, únik klíčů přes slabé heslo Heslo, test_mode
MySQL Katalog exponátů – ne náhrada configu Config vs. databáze, Znalostní báze
Veřejný kiosk Únik z prohlížeče, plocha Windows, fyzický přístup Kiosk, explorer.exe
Obsah odpovědí AI Nevhodné dotazy návštěvníků (škola, muzeum) Profily a filtry

Config a MySQL – co kam patří

Zapnutí MySQL v administraci nepřesouvá config do databáze. Aplikace pořád načítá nastavení ze souboru config; MySQL slouží pro data modulů (katalog exponátů, budoucí deníček…). Přihlašovací údaje k databázi jsou uloženy v configu – config tedy nesmazat po migraci katalogu.

  • Config – klíče AI, heslo admina, hlas, idle, motiv, texty exponátu.
  • MySQL – řádky katalogu, AI popisy exponátů, stav migrací tabulek.
  • Doporučení: nechat současný model; config zabezpečit podle kapitol níže, MySQL chránit síťově (localhost / interní síť, silné heslo DB uživatele s minimálními právy).

Konfigurační soubor (config) v produkci

Soubor config v kořeni instalace je jediné úložiště citlivých dat aplikace (nebo vlastní soubor ve skryté provozní složce – viz níže). PHP ho při každém požadavku čte; veřejný kiosk ho nepotřebuje měnit. V produkci řešte dvě nezávislé věci: nesmí jít stáhnout v prohlížeči a nesmí být zapisovatelný účtem PHP (kromě doby údržby).

Fiktivní názvy v návodu: níže uvádíme jen příkladové názvy složek a souborů (provoz-xx7, .ukazatel-cfg, vas-config-xx) a u adres bez koncovky .php (např. check, admin) – aby veřejný návod neprozrazoval skutečnou strukturu vaší instalace. Reálné cesty uvidíte v administraci a v diagnostice (pole config_storage); tyto názvy nesdílejte a chraňte před HTTP stažením.

Vlastní název souboru – doporučené pro veřejný provoz

Výchozí soubor config v kořeni instalace je běžně známý – útočníci i skenery často zkouší URL /config. V administraci lze zvolit vlastní název (např. vas-config-xx – koncovku .json doplní aplikace sama). Citlivá data pak leží ve skryté složce (příklad provoz-xx7/vas-config-xx.json); který soubor je aktivní, určuje malý ukazatel ve stejné složce (příklad provoz-xx7/.ukazatel-cfg – jeden řádek s názvem, bez API klíčů). Kořen webu kvůli tomu nemusí být zapisovatelný pro účet IIS – zápis jde jen do provozní složky.

Postup v administraci
  1. Přihlaste se do admin z údržbového PC (ne z veřejného kiosku).
  2. Sekce Bezpečnost → pole Název konfiguračního souboru.
  3. Zadejte vlastní název (písmena, číslice, -, _, tečka; nelze config ani vzor config.example).
  4. Klikněte Uložit nastavení (stejné tlačítko jako pro celý formulář).
  5. Ověřte v check: config_storage ukazuje na váš config (bez klíčů v odpovědi), config_active_pointer je vyplněný, config_file_exists = true.
Co aplikace udělá při uložení
Krok Soubor / akce
1 Přesune (nebo zkopíruje ze vzoru) obsah do provozní složky pod zvoleným názvem
2 Zapíše ukazatel aktivního souboru (jeden řádek s názvem configu, bez API klíčů)
3 Smaže původní config v kořeni (pokud už není potřeba)
4 Další ukládání z adminu jde do nového souboru; kiosk a API čtou přes loadConfig()

Stavy instalace:

  • Nová / vývoj – bez ukazatele zůstává config v kořeni (z kopie vzoru config.example).
  • Produkce – doporučeno vlastní název configu a ukazatel ve skryté složce; v kořeni už config s klíči nebývá.
  • Změna názvu – zadejte jiný název v adminu a uložte; soubor se přejmenuje v provozní složce, ukazatel se přepíše.
  • Starší instalace – mohly mít ukazatel v kořeni webu; aplikace ho při startu převede do provozní složky. Legacy soubor v kořeni pak lze smazat.

HTTP ochrana: ve web.config / nginx skryjte celý segment provozní složky (název z vaší instalace) – URL typu https://…/provoz-xx7/vas-config-xx.json musí vrátit 404. Diagnostika: check vrací config_storage, config_active_pointer_writable (zápis do provozní složky pro admin a statistiky), config_readable / config_writable vztahující se k aktivnímu JSON. Detail v adminu: Administrace – bezpečnost.

Kořen webu jen pro čtení (doporučeno)

Přejmenování configu z administrace zapisuje pouze do provozní složky (ukazatel aktivního souboru, samotný JSON, soubory statistik). Účet IIS (application pool) tedy nemusí mít zápis do kořene instalace – snížíte riziko změny PHP skriptů z webu. V kořeni stačí čtení pro PHP; v provozní složce zápis (přejmenování configu, ukládání z adminu, statistiky API).

Proč chránit config

Riziko Důsledek
Stažení přes HTTP Únik všech API klíčů a hesla admina – fakturace u poskytovatele AI, zneužití D-ID.
Zápis z webu Slabé heslo v admin, session nebo api?action=voice může přepsat config (cizí klíč, jiný prompt).
Záloha / RDP / SMB HTTP ochrana nepomůže – config na disku musí mít omezená NTFS/Linux práva i mimo web.
Diagnostika check klíče nevrací, ale prozradí stav instalace – viz níže.

Co funguje, když je config jen pro čtení

Po dokončení nastavení v administraci může mít účet PHP (IIS / php-fpm) k souboru pouze čtení:

  • chat, TTS, idle, znalostní báze (MySQL), překlady UI (cache v prohlížeči), výběr avatara (localStorage),
  • check"ready": true – vyžaduje config_readable, ne config_writable.

Bez zápisu nefunguje (nebo jen dočasně): ukládání v administraci, trvalé uložení hlasu z kiosku (api?action=voice), údržbové skripty. Statistiky API jdou do provozní složky (ne do configu).

Config ne ke stažení – IIS, nginx, Apache

PHP čte config přímo z disku – soubor nemusí být dostupný jako statická URL. Pokud prohlížeč zobrazí JSON s api_key, ochrana selhala. Cíl: 404 nebo 403.

Ověření (z jiného PC nebo mobilu):

  1. URL výchozího configu v kořeni → 404 (ne JSON s klíči).
  2. Při vlastním názvu: URL cesty k configu ve skryté složce → také 404 (zkuste z cizí sítě).
  3. index a check musí fungovat; v diagnostice kontrolujte config_storage a config_file_exists.

Windows + IIS – v kořeni je web.config, sekce hiddenSegments (segment provozní složky podle vaší instalace – v příkladu fiktivní název):

IIS web.config – hiddenSegments (příklad)

<security>
  <requestFiltering>
    <hiddenSegments>
      <add segment="config.json" />
      <add segment="provoz-xx7" />
    </hiddenSegments>
  </requestFiltering>
</security>
  • provoz-xx7 je jen ilustrace – v konfiguraci serveru použijte skutečný název složky z instalace (nesdílejte ho veřejně).
  • Po úpravě restartujte application pool. Když test stále ukáže JSON, zkontrolujte fyzickou cestu site v IIS Manageru.

Linux + nginx – v bloku server před location ~ \.php$:

nginx zákaz přímého stažení

# kořen – výchozí názvy
location = /config.json { deny all; return 404; }
location = /config.example.json { deny all; return 404; }
# skrytá provozní složka (fiktivní název – použijte svůj z instalace)
location ^~ /provoz-xx7/ { deny all; return 404; }

Po změně: nginx -t a reload služby.

Apache (volitelně) – v kořeni site nebo vhostu:

Apache Files – deny

<Files "config.json">
    Require all denied
</Files>

Config na disku – jen čtení pro PHP

  • Po finálním uložení v adminu odeberte zápis pro identitu PHP (IIS: IIS AppPool\…; Linux: www-data).
  • Windows: vlastnosti souboru → Zabezpečení → pro účet poolu u JSON configu jen Čtení (zápis jen ve skryté provozní složce). Kořen webu může zůstat jen pro čtení.
  • Před úpravou v administraci zápis dočasně povolte, nebo nasaďte config kopírováním ze zálohy.

Kontrola check – žádoucí stav v provozu

{
  "config_readable": true,
  "config_writable": false,
  "ready": true
}

Pole config_writable: false na produkčním kiosku je správně, ne chyba. Popis polí configu: Administrace a konfigurace.

Administrace, HTTPS a příprava na veřejný provoz

  • HTTPS – exponát i admin pouze přes https://. Bez HTTPS prohlížeč na síťové adrese často zablokuje mikrofon. Certifikát (Let’s Encrypt, firemní CA) na serveru i kiosku.
  • Heslo administrace – změňte výchozí; v check sledujte exhibit_ready (varování při výchozím hesle). Admin nepoužívejte z veřejného kiosku – jen z údržbového PC nebo VPN.
  • test_mode – před otevřením návštěvníkům vypněte. V test režimu se chování liší od produkce.
  • API klíče – omezte quota a billing alert u Google / OpenAI / D-ID; klíče nevkládejte do chatu ani e-mailu.
  • Oddělené účty – pro kiosk OS účet bez práv admina; pro správu serveru jiný účet (RDP jen z interní sítě).

Diagnostika – check a citlivé soubory

check ověří PHP, SSL balíček a stav configu bez vypisování klíčů. Přesto prozradí např. chybějící klíč, zapnutý test_mode nebo výchozí heslo admina.

  • Po nasazení: nechte dostupný jen z interní sítě, chraňte heslem na úrovni IIS/nginx, nebo soubor smažte / přejmenujte.
  • Odkaz na diagnostiku je v adminu – pro veřejný internet není potřeba trvalá URL bez ochrany.
  • Podrobnosti polí: Server – diagnostika ready.

Veřejný prostor – kiosk a fyzický přístup

V sále nebo hale útočník nemusí hackovat server – stačí klávesnice, USB nebo odchylka od kiosk režimu. Doporučený postup pro Windows kiosk:

  • Dedicated účet – lokální uživatel „kiosk“ bez admin práv, automatické přihlášení, autostart Chrome/Edge. Viz Doporučený autostart.
  • Kiosk režim – spouštění s --kiosk, ne jen F11. Parametry: přehled přepínačů.
  • Skrytí plochytaskkill /IM explorer.exe /F v autostart bat (volitelně), aby nebyl vidět hlavní panel. Detail: explorer.exe.
  • USB a klávesnice – fyzicky zalepte nebo v BIOS vypněte boot z USB; zvažte klávesnici bez Win klávesy nebo blokaci Ctrl+Alt+Del (Group Policy na doméně).
  • URL – kiosk směřuje jen na HTTPS exponát; neponechávejte záložky na admin ani phpMyAdmin na stejném PC.
  • Síť kiosku – pokud je server v DMZ, kiosk potřebuje jen HTTPS k hostu exponátu a odchozí internet pro STT/TTS v prohlížeči (Google speech) a případně D-ID. Příchozí porty z internetu na kiosk neotevírejte.
  • Server – firewall: povolit 443 z kiosku/lan; MySQL port 3306 neexponovat na internet. Zálohy configu šifrovat nebo držet mimo web root.

Nevhodný obsah – filtry AI a provozní profily

Technické zabezpečení neřeší vulgarismy ani nebezpečné rady – to řeší kombinace filtrů poskytovatele AI (Gemini / OpenAI) a system promptu z provozního profilu (Mládež, Muzeum, Firma…).

Kompletní popis: Nevhodný obsah – filtry AI a profil. Pro školy a veřejné prostory volte profil Mládež nebo Muzeum a otestujte hraniční dotazy před otevřením.

Kontrolní seznam zabezpečení před provozem

# Oblast Co splnit
1 Vlastní název configu Admin → Bezpečnost: jiný název než výchozí config; config_storage ukazuje na skrytou složku; ukazatel aktivního souboru existuje
2 Config HTTP Kořen /config i cesta ke configu ve skryté složce → 404
3 Config disk PHP účet: čtení ano, zápis ne (config_writable: false)
4 HTTPS Exponát i admin jen přes TLS; mikrofon na kiosku funguje
5 Admin Silné heslo, test_mode vypnuto, exhibit_ready bez varování
6 Diagnostika check chráněn nebo odstraněn z veřejného přístupu
7 MySQL Pouze interní síť; DB uživatel s právy jen na potřebné tabulky
8 Kiosk --kiosk, účet bez admina, autostart, volitelně skrytá plocha
9 Obsah AI Provozní profil + test nevhodných dotazů v reálném hluku
10 Server ready: true; zálohy configu mimo veřejný přístup

Provozní kontrolní seznam (hlas, mikrofon, D-ID): Server – před spuštěním.

Shrnutí: pro veřejný provoz zvolte vlastní název configu v adminu (soubor ve skryté provozní složce, ukazatel aktivního souboru); kořen webu ideálně jen pro čtení; chránit před HTTP stažením; HTTPS a silné heslo admina; kiosk na omezeném účtu; obsah řídit provozním profilem. MySQL nenahrazuje config.