Tato stránka popisuje různé aspekty týkající se zabezpečení validačního serveru.
Samotný validační server nemusí běžet jako root či jinak privilegovaný uživatel a také se to samozřejmě silně nedoporučuje. Ideální situace je vytvořit speciálního uživatele, pod nímž server poběží. Konkrétně mějme tedy:
Server potřebuje read/write přístup do svých podadresářů, dále potřebuje mít možnost čekání na portu určeném pro RMI (tedy obvykle 1099), což nevyžaduje žádné extra starosti (pouze již nesmí být port obsazen).
V případě, že se například výstupní HTML či XML soubory exportují do nějakého jiného adresáře, musí mít samozřejmě i tam právo zápisu (typicky /var/www). Případně je toto možno řešit opačně s použitím symlinků.
Mnohem větší důraz je logicky kladen na zabezpečení souborů, které validační server přijímá od svých klientů, překládá a poté spouští. Předpokládejme tedy, že máme doménu:
Doména funguje tak, že přijímá JAVA zdrojové soubory, překládá je a spouští, přičemž kontroluje výstupy programů. Z pohledu bezpečnosti je v tomto procesu pro nás kritický pouze krok "spouštění". Spuštění překladače považujeme za bezpečný úkon, který není třeba nijak zabezpečovat (pokud by však bylo požadováno zabezpečení i překladu, není nejmenší problém) .
Při spouštění jakýchkoliv souborů (ať binárních či Java) platí stejná pravidla. Java soubory se spouští jako jakékoliv jiné binární - pro ně se totiž spouští binární příkaz "java" (jehož cesta je zadána v konfiguraci serveru/domény). Proto se nejprve zaměříme na způsob zabezpečení spouštění binárních souborů:
Zabezpečení je řešeno tak, že je umožněno spouštět soubory pod jiným uživatelem, než pod kterým běží vlastní validační server. Tento uživatel může mít zcela minimalizována veškerá oprávnění na systém, zdroje či paměť, což silně snižuje možnost nějakého většího úmyslného poškození systému.
Obvykle ale probíhá komunikace s validovaným programem přes rouru - tj. přes stdin, stdout a stderr, takže výstupy programu jsou přesměrovány jakoby zpět do validačního serveru - a ten je již do souboru ukládat může. 'vs-nobody' tedy nemusí mít právo zápisu ani do 'workdir' adresáře serveru.
<entry key="core.invoke_user">vs-nobody</entry> <entry key="core.sudo_path">/usr/bin/sudo</entry>
validator ALL=(vs-nobody) NOPASSWD: ALL
V tomto okamžiku bude validační server podporovat zabezpečené spouštění všech spustitelných souborů.
Poznámka: Tento způsob zabezpečení se týká pouze operačního systému Linux (či příbuzných - podobných), ve Windows nebude fungovat. Fungoval by v případě, že by uživatel sehnal/naprogramoval jednoduchou utilitku "sudo" pro Windows - tedy program, který by spustil zadaný program pod jiným uživatelem. Bude-li zájem, mohu tuto utilitku naprogramovat.
Předchozí kapitola platí samozřejmě i pro spouštění Javovských programů, protože ty se spouštějí příkazem 'java' - a ten je tedy spouštěn pod uživatelem 'vs-nobody'. Pro případ spouštění Java tříd je však k dispozici ještě další úroveň zabezpečení - Java Policies.
Je možno definovat standardním způsobem Java Policies pro spouštěné Javovské programy:
<entry key="java_policy_file">run.policy</entry>
// Policy soubor pro spousteni vzorovych prikladu // umoznuje cteni/zapis z/do adresare domeny a vsech podadresaru // co muze vzorova trida grant codeBase "file:${validator.classbasedir}/-" { // cteni z domain adresare - budou tam pripadne nejake vstupni soubory permission java.io.FilePermission "${validator.domaindir}/-", "read"; // dalsi "default" opravneni permission java.util.PropertyPermission "java.version", "read"; permission java.util.PropertyPermission "java.vendor", "read"; permission java.util.PropertyPermission "java.vendor.url", "read"; permission java.util.PropertyPermission "java.class.version", "read"; permission java.util.PropertyPermission "os.name", "read"; permission java.util.PropertyPermission "os.version", "read"; permission java.util.PropertyPermission "os.arch", "read"; permission java.util.PropertyPermission "file.separator", "read"; permission java.util.PropertyPermission "path.separator", "read"; permission java.util.PropertyPermission "line.separator", "read"; permission java.util.PropertyPermission "java.specification.version", "read"; permission java.util.PropertyPermission "java.specification.vendor", "read"; permission java.util.PropertyPermission "java.specification.name", "read"; permission java.util.PropertyPermission "java.vm.specification.version", "read"; permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; permission java.util.PropertyPermission "java.vm.specification.name", "read"; permission java.util.PropertyPermission "java.vm.version", "read"; permission java.util.PropertyPermission "java.vm.vendor", "read"; permission java.util.PropertyPermission "java.vm.name", "read"; };
PropertyPermission nejsou důležité, jsou spíše na ukázku. Důležité jsou ukázky toho, jak povolit přístup jen do jednoho adresáře. Je vidět, že lze využít dvou proměnných definovaných validačním serverem a předávaných spouštěnému Java prostředí prostřednictvím "-D" argumentu:
Poznámka: Tento způsob zabezpečení se týká jakéhokoliv operačního systému, na kterém validační server běží.