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
- Přihlaste se do
adminz údržbového PC (ne z veřejného kiosku). - Sekce Bezpečnost → pole Název konfiguračního souboru.
- Zadejte vlastní název (písmena, číslice,
-,_, tečka; nelzeconfigani vzorconfig.example). - Klikněte Uložit nastavení (stejné tlačítko jako pro celý formulář).
- Ověřte v
check:config_storageukazuje na váš config (bez klíčů v odpovědi),config_active_pointerje 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á
configv kořeni (z kopie vzoruconfig.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žadujeconfig_readable, neconfig_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):
- URL výchozího configu v kořeni → 404 (ne JSON s klíči).
- Při vlastním názvu: URL cesty k configu ve skryté složce → také 404 (zkuste z cizí sítě).
indexacheckmusí fungovat; v diagnostice kontrolujteconfig_storageaconfig_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-xx7je 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
checksledujteexhibit_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í plochy –
taskkill /IM explorer.exe /Fv 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.