Omezení systémových prostředků
Důležitou částí ochrany počítače je šetření jeho prostředků. Vyčerpání systémových zdrojů má často za následek zablokování počítače, tzv. Denial of Service. Obvyklé útoky spočívají v zaplnění paměti nebo disku, nebo přetížení procesoru. Známým příkladem jednoduchého linuxového odepření služby je „procesová exploze“:
$ DoS() { DoS | DoS ; } ; DoS
Pokud byste se rozhodli si DoS vyzkoušet nanečisto a nechcete si poškodit systém, měli byste před pokusem připravit jisté mantinely, především omezit maximální počet procesů na nějakou přijatelnou hodnotu:
$ ulimit -Su 100 $ sync
Tato forma útoku nemusí být záměrná, může se jednat o chybu v programu. Rozhodně je vhodné takovému chování předejít. K tomu nám poslouží modul pro omezení přidělování prostředků pam_limits. Jeho funkční oblastí je vcelku přirozeně správa relací (session). Uživatelům omezíme prostředky hned při přihlášení:
#%PAM-1.0 # This is /etc/pam.d/login auth requisite pam_securetty.so auth required pam_pwdb.so shadow nullok auth required pam_nologin.so account required pam_pwdb.so password required pam_cracklib.so password required pam_pwdb.so nullok use_authtok md5 shadow session required pam_pwdb.so session required pam_limits.so session optional pam_console.so
Modulu pam_limits se nastavení limitů nepředává jako parametr, k tomu slouží zvláštní konfigurační soubor /etc/security/limits.conf. Jeho struktura je jednoduchá, přesto umožňuje dobrou kontrolu nad systémem. Řádky se skládají ze čtyř polí: domény, typu omezení, názvu prostředku a hodnoty limitu.
# DOMENA TYP PROSTREDEK HODNOTA @users hard nproc 100 @users soft nproc 50 badguy hard nproc 30 badguy hard cpu 5 badguy - maxlogins 1 * soft core 5000
Doména určuje, koho se omezení týká. Může se jednat o uživatelské jméno, nebo jméno skupiny uvozené znakem @. Doména * určuje implicitní záznam.
Existují dva typy limitů: hard (pevné) a soft (doporučené). Pevné limity není možné překročit, jsou vynuceny jádrem operačního systému a měnit je má povoleno jen superuživatel. Uživatel může měnit doporučené limity, ale nejvýše po hodnotu pevného omezení.
Názvy nejdůležitějších prostředků a jejich význam udává tabulka:
| Prostředek | Význam | Jednotka |
| core | Maximální velikost souboru core, do něhož se ukládá obraz paměti (obvykle při chybě programu) | KB |
| data | Maximální velikost datového segmentu | KB |
| fsize | Maximální velikost souboru, který lze vytvořit | KB |
| nofile | Nejvyšší možný počet současně otevřených souborů | – |
| cpu | Čas spotřebovaný procesorem | minuty |
| nproc | Počet současně spuštěných procesů | – |
| maxlogins | Počet současných přihlášení do systému (typ omezení nemá význam) | – |
Nyní již můžeme vysvětlit význam výše uvedeného příkladu: členové skupiny users mohou současně spustit až 50 procesů. Limit si však mohou v případě potřeby zvýšit až na 100. Uživatel badguy, který si patrně znepřátelil správce systému, může spustit nejvýše 30 procesů, spotřebovat 5 minut strojového času a pracovat v jediné relaci. Velikost zapsaného paměťového obrazu je implicitně omezen na 5 megabajtů, ale kdokoliv si toto omezení může změnit (pevný limit totiž není stanoven).
Položka cpu, čas spotřebovaný procesorem, často nebývá správně pochopena. Nejedná se v žádném případě o délku relace, takže nepočítejte s tím, že po pěti minutách bude uživatel badguy automaticky odhlášen. Omezení strojového času se projeví při spuštění nějaké zdlouhavé operace (například utility yes). Přehled o časových nárocích vašich aplikací vám odhalí třeba osvědčený top ve sloupci TIME.
S pomocí modulu pam_limits snadno zabráníme útokům DoS vedeným především zevnitř systému (tedy způsobené „hravými“ uživateli). A protože pevné limity jsou kontrolovány na úrovni jádra, neporuší je ani chybně napsaná aplikace. Proto by se měl správce systému zamyslet, jaká omezení nebudou uživatelům působit problémy při práci a bez váhání je uplatnit. (Málokterý uživatel potřebuje desítky současně spuštěných procesů.)
Pokud se považujete za nerestriktivního správce, můžete uvážit nastavení jen doporučených limitů. Uživatelé si pak v případě, že jim toto omezení bude působit potíže, mohou sami pomoci příkazem ulimit.
Přístup jen během „úředních“ hodin
Občas vyvstane potřeba, aby přístup k nějaké službě byl regulován i vzhledem k denní době. Motivační příklad by mohl vypadat následovně: „služba Quake smí být využívána v pracovní dny jen od půlnoci do 5:00, nebo od 18:00 do půlnoci, zatímco o víkendech ji mohou zaměstnanci spouštět bez omezení.“ Dalších analogických případů můžeme najít více, často se budou vztahovat ke službám shutdown, reboot a halt.
Modul pam_time nám pomůže poměrně snadno vyřešit takový správní úkol. Funkční oblastí tohoto modulu je kontrola účtu (account). Samotný modul nepřijímá žádné argumenty na příkazové řádce, takže v souboru definujícím zabezpečení služby se objeví jen řádek
account required pam_time.so
Samotné nastavení parametrů této kontroly je uloženo v souboru /etc/security/time.conf. Jeho syntaxe je vcelku jednoduchá, ale umožňuje dostatečně pružné řízení přístupu. Na řádcích se záznamy (jeden záznam může být rozdělen na více řádků obvyklým použitím zpětného lomítka na konci řádku) najdeme tato pole oddělená středníky:
služby; tty; uživatelé; čas
Pro další vysvětlování si musíme přiblížit pojem logický seznam. Jedná se o posloupnost hodnot spojených logickými operátory & (a zároveň) a | (nebo), přičemž hodnoty mohou být i negativní: !xyz znamená cokoliv kromě hodnoty xyz. Hodnoty mohou obsahovat nejvýše jeden zástupný znak *. Bohužel výrazy nelze závorkovat ani není určená precedence logických operátorů, čímž trpí především přehlednost.
Pole služby je logický seznam názvů autentizovaných služeb, kterých se časové omezení týká. Tyto položky odpovídají názvům souborů v adresáři /etc/pam.d. Obvykle se uvádí jen jedna služba.
Pomocí pole tty určujeme, na které terminálové linky se záznam vztahuje. Zde narazíme na drobný nedostatek modulu, protože v moderních distribucích Linuxu se pseudoterminály vážou ke speciálním souborům /dev/pts/, nikoliv /dev/ttyp (aktuální terminálovou linku zjistíme příkazem tty), ale modul pam_time neumožňuje používat znak lomítka. Takže v současné verzi 0.72 nebudeme schopní zadat třeba pts/1.
Pole uživatelé obsahuje logický seznam uživatelů ovlivněných záznamem. Je škoda, že modul nenabízí i specifikaci skupiny uživatelů podle souboru /etc/groups. V některých případech by to podstatně ulehčilo konfiguraci.
Aby se záznam vzal do úvahy při vyhodnocování, musí se shodovat všechna tři uvedená pole. Pokud některé pole nevyhovuje, nebo záznam není syntakticky korektní, jednoduše je přeskočen. Při chybě v záznamu je navíc zaprotokolováno upozornění (obvykle pomocí syslogu).
Posledním, nejdůležitějším polem je čas, tedy určení, ve kterou dobu je služba přístupná. Jedná se opět o logický seznam, jehož hodnoty mají formát DenHhMm-HhMm. Položka Den může mít hodnotu podle tabulky:
| Hodnota | Význam |
| Mo | Pondělí |
| Tu | Úterý |
| We | Středa |
| Th | Čtvrtek |
| Fr | Pátek |
| Sa | Sobota |
| Su | Neděle |
| Wk | Pondělí – pátek |
| Wd | Víkend |
| Al | Všechny dny v týdnu |
V části Den může být i více hodnot. Pokud je však některá hodnota zopakována, neprovede se sjednocení, ale vyjmutí ze seznamu. Toto chování je ilustrováno na příkladech níže.
Druhá část pole Čas, HhMm-HhMm, jednoduše určuje časový interval, během kterého je služba povolená.
Nyní konečně můžeme uvést několik příkladů. V první řadě implementujeme časové omezení hry Quake (samozřejmě čistě hypoteticky, autorovi není známo, že by Quake podporoval systém PAM :)
quake; *; *; Wk0000-0500 | Wk1800-2400 | Wd0000-2400
V dalším příkladu určíme, že služby reboot a shutdown mohou dva vybraní uživatelé provést jen v pondělí, středu či pátek. Zde si můžeme všimnout vícenásobného uvedení dnů úterý a čtvrtek v části Den:
shutdown | reboot; *; karel | milan; WkTuTh0000-2400
Pomocí modulu pam_time ovšem nemusíme omezovat přístup jen z hlediska času. Následující příklad demonstruje, jak uživateli badguy povolit přístup jen z první textové konzole. Za povšimnutí stojí druhý a třetí řádek: oba určují stejné omezení, ale různým způsobem. Druhý řádek vyjadřuje „nikdy“ pomocí vlastností logického seznamu, třetí řádek vícenásobným uvedením stejného dne. Tím vznikne „žádný den“.
login; tty1; badguy; Al0000-2400 login; !tty1; badguy; !Al0000-2400 login; !tty1; badguy; MoMo0000-2400
Pozor na určování časových intervalů u „nikdy“ a u negovaných hodnot obecně. Zatímco MoMo1200–2400 určuje opět „nikdy“, výraz !Al1200–2400 specifikuje totéž, jako Al0000–1159.
Na závěr určíme, že superuživatel se může přihlásit do systému jen z prvních dvou textových konzolí (tty1, tty2), z ostatních terminálových linek jedině v pracovní dny během pracovní doby:
login | ssh | su; !tty1 & !tty2; root; Wk0700-1800
Je nutné si uvědomit, že modul pam_time slouží k omezování; pokud trojice služba, tty, jméno není nalezena v konfiguraci modulu, je přístup ke službě povolen (tohoto chování využívá poslední ukázka). Samozřejmě nesmíme zapomenout vložit volání modulu pam_time.so do příslušných autentizačních souborů v adresáři /etc/pam.d, jinak se kontrola časových údajů neprovede.
Závěrem můžeme shrnout, že modul pam_limits je vhodné nasadit prakticky do libovolného systému – jeho použití na domácí pracovní stanici neuškodí, ale může zabránit některým incidentům. Oproti tomu je modul pam_time určen spíše pro mnohouživatelské systémy, v nichž správce potřebuje omezit přístup k nějaké službě podle času, terminálových linek nebo v nouzi i jmen oprávněných uživatelů (ale k tomuto účelu existují samostatné, výkonnější moduly).