Virtuális webszerver hoszting (esettanulmány)

A Unix/Linux szerverek üzemeltetése wikiből

Írta: Glowacz Balázs

Ez a Virtuális webszerver hoszting esettanulmány egy olyan rendszer biztonságosra törekvő konfigurálását mutatja be, amely virtuális WEB, -FTP, szolgáltatásokat nyújt és mysql, php támogatást ad különböző védelmi és megfigyelési modulokkal. A leírás megpróbál összefogni beállításokat, csomagokat, melyek talán csak az alapvető konfiguráció hiányosságainak felfedezése után jutnának eszünkbe ezzel később nehézségeket okozva. Debian Lennyre (ekkor stabil kiadás) értendők a disztribúció specifikus parancsok, elérések stb. és feltételezem, hogy az alap kernel image kerül használatra, vagyis minden kernel szintű beállítás már adott lesz. A konfigurálásokat, különböző modulok alkalmazását és használati módjukat saját tapasztalataim alapján javaslom, ezektől eltérő alkalmazások használata is tökéletes lehet. A leírást úgy próbálom megcsinálni, hogy egy kezdő „linuxos” is képes legyen beállítani mindent lehetőleg úgy, hogy meg is értse (nem teljesen kezdő), mit csinál. Azonban nem térhetek ki mindenre, ilyen például az OpenSSH részben a kulcsok használata, nem is célom bevezetni a kriptográfia rejtelmeibe az olvasót.

Tartalomjegyzék

1 Telepítés

Leszedjük a Lenny iso-t,

ftp://ftp.hu.debian.org/pub/CDROM-Images/debian/5.0.2/amd64/iso-cd/debian-502-amd64-netinst.iso


telepítjük. Törekedjünk arra, hogy a kitűzött szolgáltatásokon kívüli, a gépen fölöslegesnek bizonyuló csomagokat, szolgáltatásokat ne rakjunk föl. (X11, X-es alkalmazások, zene stb.) A továbbiakban NEM feltételezem, hogy bármely csomag, amire szükség lesz, itt telepítésre került.

2 SSH konfiguráció

Az SSH szerver beállítása és keményítése (hardening).

2.1 Telepítés

Ha az alap rendszerrel nem került volna telepítésre, rakjuk föl az openssh csomagot.

# aptitude install openssh-server openssh-client

Mostmár van SSH szerverünk és föltettük az SSH klienst is egyúttal (előbb-utóbb úgyis szükség lesz rá).

2.2 Konfigurálás

A kliens konfigurálásával nem kell sokat vacakolnunk, ha valami spéci beállításra szükség lenne mégis, akkor azt a /etc/ssh/ssh_config fájlban lehet megtenni.
A szerver beállításánál már több dolgot érdemes megnézni. Alap esetben bármely felhasználó shellt kaphat SSH-n (már ha van shellje /etc/passwd). Ezt nem szeretnénk, mert ilyen szolgáltatást nem nyújtunk, anélkül meg elég veszélyes dolog (local exploitok).
Ami biztonsági szempontból érdekes lehet nekünk elsőre:

PermitRootLogin no
AllowUsers user1

Ezzel beállítottuk, hogy root semmiképpen ne léphessen be, majd szigorítottunk is ezen, mert csak a user1 felhasználónak engedjük meg a belépést. user1 értelemszerűen a mi felhasználónevünk, amivel később távolról hozzá szeretnénk férni a szerverhez.

2.3 Keményítés (hardening), tapasztalatok

Még ha az openssh default konfigurációja tartalmaz is védelmet bruteforce-, dictionary- és egyéb támadásokra (nem azonnal ad választ, bont stb.), egy egyszerű jelszavas védelemmel nem érezhetjük elég biztonságban magunkat, hiszen ez a legdurvább belépési pont, amely kapásból shellt is ad. Ezért alkalmazzunk publikus kulcsú hitelesítéssel egybekötött beléptetést, a sima jelszavas autentikációt pedig tiltsuk! Ehhez érdemes fölrakni az openssl csomagot (és függőségeit) és létrehozni a kulcspárt a felhasználó számára. (Ez elvégezhető az ssh-keygen paranccsal is, melyet tartalmaz az openssh csomag. Azonban könnyen lehet, hogy később a webszerverünkhöz is, levelezőszerverünkhöz is stb. szeretnénk könnyű kulcskezelést megvalósítani, ehhez viszont már nem árt az openssl csomag és a vele szerzett tapasztalat.)

1: # aptitude install openssl
2: # openssl genrsa -des3 -out user1_private.key 2048
3: # openssl rsa -pubout -in user1_private.key -out user1_public.key

A 2. sorban a privát kulcs titkosítva kerül fájlba írásra, ezért kérni fog egy passphrase-t a folyamat. (Melyet a titkosításhoz használ.)
Ezután a belépéshez használható kulcspár publikus kulcsát be kell másolni a megfelelő ~/.ssh/authorized_keys fájlba és a megfelelő módosításokat elvégezni az /etc/ssh/sshd_config fájlban.
~/.ssh/autorized_keys:

ssh-rsa johosszukulcs1
amiittisfolytatodhattovabb==
ssh-rsa johosszukulcs2==
...


/etc/ssh/sshd_config:

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
PasswordAuthentication no


Az egyszerű jelszavas belépést (PasswordAuthentication) érdemes csak azután letiltani, ha már biztosan látjuk a kulcsos autentikáció működését, különben kizárhatjuk magunkat. Mindkettő engedélyezésével (eleinte ez javasolt) valamilyen sorrendben mindkét belépési módra lehetőség nyílik. Miután kizártuk a jelszavas belépés lehetőségét, egy olyan felhasználóval való belépési próbálkozás, akinek nincs engedélyezett kulcsa, azonnali visszadobást eredményez. Igazából nincs sem hálózati forgalomból, sem bruteforce szempontból nagy hátránya, de ha valakinek ez mégsem tetszene iptablesben limitálhatja az egy ip-ről érkező próbálkozások időegységenkénti számát.

3 Webszerver konfiguráció

A fejezetben az Apache webszerver konfigurálását fogjuk elvégezni a virtuális szerverek figyelembevételével. A végén más csomagokat, modulokat is bevetünk a biztonság érdekében.

3.1 Telepítés és konfigurálás

# aptiude install apache2 php5 libapache2-mod-php5 mysql-server mysql-client

Ezután kapunk egy default apache konfigurációt php támogatással és még adatbázisszervert és -klienst is telepítettünk, mivel mamár egy valamire való oldal adatázist is használ. A következő apache könyvtárstruktúra áll rendelkezésre ezután (ha nem, hozzuk létre, különben kezelhetetlen lesz a sok virtuális szerver és apache modul).
/etc/apache2/:

1: /etc/apache2/conf.d
2: /etc/apache2/mods-available
3: /etc/apache2/mods-enabled
4: /etc/apache2/sites-available
5: /etc/apache2/site-enabled

Ebben a struktúrában található a konfiguráció különböző fájlokban, melyek Include direktívával össze vannak fűzve,
/etc/apache2/apache2.conf:

...
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/sites-enabled
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/httpd.conf
Include /etc/apache2/ports.conf
Include /etc/apache2/conf.d
...

(ami azt is jelenti, hogy hiba esetén nem tölt be egyetlen virtuális kiszolgálót sem) így egy nagy összetett konfigurációs fájl helyett kapunk több kicsit, például virtuális szerverenként külön fájlal. Így külön tudjunk mindegyiket kezelni. A conf.d, sites-enabled és mods-enabled mappában található fájlok kerülnek betöltésre; a sites-available, mods-available mappa tárolásra szolgál. Innen linkelünk az enabled-be, ha be is akarjuk tölteni. (Erre egyébként használható az a2ensite, a2dissite, a2enmod, a2dismod parancs is.) Virtuális szervereink konfigurációs fájljait a sites-available mappába rakjuk, a2ensite paranccsal engedélyezzük és /etc/init.d/apache2 reload paranccsal újratöltjük.
/etc/apache2/sites-available/virtual_server1 (váz):

ServerAdmin admin@virtual_domain.com
ServerName virtual_domain.com
ServerAlias www.virtual_domain.com
DocumentRoot /home/virtual1/html/
CustomLog /var/log/apache2/virtual_server1/access.log combined
<Directory />
	Options FollowSymLinks
	AllowOveride None
	Order Deny,Allow
	Deny from all
</Directory>
<Directory /home/virtual1/html/>
	Options Indexes FollowSymLinks MultiViews
	AllowOveride All
	Order Allow,Deny
	Allow from all
</Directory>

Mindenféle „redirect trükközés” helyett ServerAlias-nak adjuk meg a www és a www nélküli címet (vagy mást), ha szükség van rá. CustomLog-ot érdemes megadni, hogy statisztikát lehessen készíteni minden domainre (CustomErrorLog-ot is, ha nem globálisan apache2.conf-ból egy fájlban akarjuk tárolni). A „Directory” direktívák alapvető biztonsági szempontból kell, hogy belekerüljenek, az első tiltja az egész fájlrendszerhez való hozzáférést, a második engedélyezi a DocumentRoot-hoz. Fontos az apache2.conf -ban az igényekhez állítani a szerver következő attribútumait:
/etc/apache2.conf:

1: StartServers 15
2: MinSpareServers 15
3: MaxSpareServers 25
4: MaxClients 150
5: MaxRequestPerChild 0
  • 1-5: Valószínűleg egy „IfModule prefork” részlegben lesz megtalálható, mert az apache2 virtuális csomag az apache2-mpm-prefork csomagot teszi föl, amely minden kérésre újabb gyermek processt forkol a kiszolgáláshoz, általában www-data jogokkal futtatva.
  • 1: Ennyi szervert indítson alapból.
  • 2: Minimum ennyi tartalék szerver processz legyen készen kiszolgálásra.
  • 3: Maximum ennyi tartalék szerver processz legyen készen kiszolgálásra.
  • 4: Ennyi klienst tud egyszerre kiszolgálni maximum.
  • 5: Maximum ennyi kérést szolgáljon ki egy processz, ezután meghal és átadja a feladatot másnak. (0->akármennyi; memóriaproblémás moduloknál jól jöhet, ha adunk neki valamekkora értéket) (A fejezet későbbi részében, mpm-itk esetén, egy processz, csak egy klienst szolgál ki. Ennél fogva ez az érték ilyenkor egy kliensre fog vonatkozni.)

3.2 Hardening (keményítés), tapasztalatok

3.2.1 Konfigurációs fájlok

Először is amit a konfig fájlokban tehetünk:
/etc/apache2/apache2.conf:

1: <Directory />
2: 	Order Deny,Allow
3: 	Deny from all
4: </Directory>
5: TraceEnable off
6: ServerTokens Prod
7: ServerSignature off
  • 1-4: Már globálisan tiltjuk a gyökérkönyvtár elérhetőségét, így nem hagyhatjuk ki a virtuális szerverek konfigurációjánál.
  • 5: A trace metódus kikapcsolása (információ szivárogtatás ellen).
  • 6: Alapból általában FULL-on van, ami nem csak az apache verziót, de a PHP és egyéb patchek meglétét és verzióját árulja el a fejlécekben, de ezzel nem szeretnénk segíteni a támadó munkáját, így a Prod-dal mindössze annyit közöl a fejlécben az apache, hogy "Server: Apache".
  • 7: A szerver által előállított lapoknál (pl. 404 stb.) kikapcsolja a lap alján megjelenő aláírást, ami általában tartalmazza a rendszer verziókat.

3.2.2 mpm-itk

Ha azt akarjuk, hogy a virtuális szerverek még véletlenül se tudják egymás fájljait írni/olvasni, meg akarjuk nehezíteni bármely apache bugjának, virtual szerveren elhelyezett oldal bugjának elburjánzását, vagy éppen olyan oldalt akarunk kiszolgálni, ahol a webszerver ír fájlokat (és ezért a www-data tulajdonú fájlok nehézkesek, főleg FTP esetén), akkor használjunk mpm-itk csomagot. Működése megegyezik az mpm-prefork csomagban található apachéval, csak itt a létrehozott processzek rootként indulnak el és a kiszolgált oldalnak megfelelően eldobják jogaikat és pl. virtual1, virtual2 stb. jogokkal futnak tovább és szolgálnak ki. Ennek megfelelően ki kell bővítenünk az apache.conf fájlunkat IfModule mpm_itk_module résszel, illetve a virtuális hosztok konfigurációs fájljaiban meg kell adnunk a kívánt usert és groupot.
/etc/apache2/apache2.conf:

...
<IfModule mpm_itk_module>
	StartServers...
	…
	MaxRequestsPerChild 0
</IfModule>
...

/etc/apache2/sites-available/virtual_server1:

...
<IfModule mpm_itk_module>
AssignUserId virtual1 virtual1
</IfModule>
...

Mpm-itk használata esetén az apache processzek, mivel oldalanként (vagy akár oldalon belül is) más-más felhasználóval futnak, egy bizonyos tétlenségi idő után meghalnak, ha a kliens nem kért közben semmit. (Ez érthető, mivel az apache jogokat visszanyerni, vagy váltani nem képes.) Ha szükséges, születik helyébe egy root jogosultságú, újabb processz, amely később szintén eldobja jogait egy kliens kiszolgálásához.


3.2.3 mod_security2

A legkülönbözőbb cross-site scripting és code injection támadások ellen (vagyis a nem nagy körültekintéssel megírt komplex oldalak támadásai ellen) használhatjuk a mod_security2 apache2 modult. A modul alkalmazásszintű védelmet nyújt, hasonló mintaillesztéssel dolgozik mint a snort.
Példa: egy http://foo.bar/index.php?file=/etc/passwd hívás érkezése esetén (alap szabályokkal) még ha legális kérés is az oldalon, a szerver megtagadja a kiszolgálást.
Ennek megfelelően a modul fals pozitívan is értékelhet egy kérést, főleg összetett CMS-eknél, ezért nagyon körültekintően kell konfigurálni és mérlegelni, hogy egyáltalán szükség van -e rá.
Debian repoban általában megtalálható, azonban bizonyos okokból a Lennyből kimaradt, ennek megfelelően vagy forrásból lefordítjuk (meg kell nézni melyek a szükséges csomagok fordításhoz), vagy nem hivatalos csomagot használunk (ez a könnyebbik út).
Forrás: http://www.modsecurity.org/download/index.html
/etc/apt/sources.list:

...
deb http://etc.inittab.org/~agi/debian/libapache-mod-security2/ ./
...
# aptitude update
# aptitude install libapache-mod-security2

Miután fölkerült a modul, a szokásos a2enmod, a2dismod paranccsal tudjuk engedélyezni, vagy leállítani. Azonban a mod_security2 alap konfigurációja nem valami kielégítő, főleg, hogy nincs is alap konfigurációs fájl amit bütykölhetnénk, sem log fájlok. Ezeket most elkészítjük:

# mkdir /etc/modsecurity2
# mkdir /etc/modsecurity2/logs
# echo „Include /etc/modsecurity2/*.conf” > /etc/apache2/conf.d/mod-security.conf
# cp /usr/share/doc/libapache-mod-security/examples/rules/*.conf /etc/modsecurity2/

A /etc/modsecurity2/modsecurity_crs_10_config.conf -ban pedig írjuk át a SecAuditLog és SecDebugLog -okat, ha nem az /etc/modsecurity2/logs -ba akarjuk, hogy naplózza az eseményeket. Ezután a virtuális hosztokkal karöltve lehet tesztelni és szájíz szerint finomítani a konfigokat, de innentől már működik szépen és konfigurálhatóan.

3.2.4 mod_proxy

Mivel egy virtuális hoszting szolgáltatást állítunk föl, a különféle felhasználók különféle WEB applikációkat töltenek föl, melyek egy része olyan komoly hibákat tartalmazhat, amelyek kihasználása negatív hatással lehet az apache futására és eddigi védelmi intézkedéseink nem segítenek. Egy ilyen hiba az egész virtuális WEB hosztingra kihathat, tehát valamilyen módon el kell tudnunk különíteni egy-egy virtuális hosztot WEB szinten, amíg a hibát a virtuális hoszt tulajdonosa nem javítja (vagy esetleg a kiszolgáló szervert nem patchelik). Első gondolatra mindenkinek egy apache redirect jutna eszébe egy másik kiszolgálóra, azonban ezzel több probléma van. Nem transzparens, a látogatóknak portokat kell írogatni és a linkek mind javításra szorulnak. Indítani kell egy másik WEB kiszolgálót, egy másik (magas) porton. (Érdemes lehet apache egy másik példánya helyett pl. lighttpd-t felrakni, hasonló módon, mint tettük az apache-csal.) Egyszerű redirect helyett azonban „proxyztatjuk” az oldalt az apache kiszolgálón keresztül. Így az összes átirányítással kapcsolatos problémánk megszűnik.
Apache proxy beállítás:
/etc/apache/sites-available/virtual_server2:

1: …
2: ProxyRequests Off
3: <Proxy *>
4: 	Order deny,allow
5: 	Allow from all
6: </Proxy>
7: ProxyPass / http://www.virtual-host2.com:60000/
8: ProxyPassReverse / http://www.virtual-host2.com:60000/
9: …
  • 2: Nem szeretnénk, ha nyílt proxyként üzemelnénk és mindenki ugródeszkának használna.
  • 3-6: Engedélyezzük a proxy-t mindenki számára.
  • 7: Szeretnénk, ha egy kérés a virtuális hoszt gyökérre (és így tovább rekurzívan) a másik kiszolgálóra képződne.
  • 8: Ez reverse proxyként is kell hogy működjön, vagyis hogy teljesen transzparens legyen és képes legyen az apache megfelelően újraírni az URL-eket a kérés-válaszokban.

3.2.5 php.ini

Néhány php.ini beállítás a PHP környezet szigorításához. Ha már több oldalt kiszolgálunk vigyázni kell az itteni módosítgatásokkal, mert lehet, hogy a szigorítás következtében az oldalak funkciói nem fognak mind működni. (Jellemzően a CMS-ek.) PHP 5-től kezdődően több régebben használt módosítást nem célszerű használni, itt csak azokat közlöm, amelyeket továbbra is az. Részletes leírásuk magában a php.ini –ben megtalálhatóak, itt felsorolás szerűen javaslataimat közlöm.
/etc/php5/apache2/php.ini

1: open_basedir
2: display_errors
3: disable_functions
  • 1: A fájlműveletek helyét szűkíti az adott könyvtár alá. Érdemes a virtuális WEB rootokat tartalmazó könyvtárra állítani.
  • 2: Rosszul megírt, átírt oldalak hiba esetén nem fognak debug információkat közölni, pl. nem fognak adatbázis jelszavakat köpködni a php fájlok.
  • 3: Itt lehet kikapcsolni a különböző PHP funkciókat a biztonság növelése érdekében.


Néhány kikapcsolható funkció, melyek nélkül valószínűleg a legtöbb webalkalmazás még működőképes lesz, de növelheti a biztonságot:

disable_functions = "apache_get_modules,apache_get_version,apache_getenv,apache_note,apache_setenv,disk_free_space,diskfreespace,dl,highlight_file,ini_alter,ini_restore,openlog,passthru,phpinfo,proc_nice,shell_exec,show_source,symlink,system"


4 MySQL konfiguráció

Az Apache telepítésekor már feltelepítettük a mysql-server csomagot. Ekkor meg kellett adni az SQL root felhasználóhoz rendelni kívánt jelszavunkat. Ez fontos, mert ezzel fogjuk tudni a további szükséges változtatásokat elvégezni. Amennyiben szeretnénk, hogy a felhasználók hozzáférjenek adatbázisukhoz használhatunk erre webes adminisztrációs felületet, melyek lokális kapcsolatot létesítve működnek, de nekem szimpatikusabb volt a MySQL Administrator program, melyet a www.mysql.com –ról le lehet tölteni. (Ezen kívül biztonságosabb is lehet, mert az SQL manipulációs webalkalalmazásokat rendre föltörik folyamatosan.) Ennek segítségével nem csak a felhasználók adminisztrálhatják saját adatbázisukat, de könnyen adminisztrálhatjuk mi is a MySQL felhasználókat, adatbázisokat, végezhetünk mentéseket stb. Az alap MySQL konfiguráció nem engedi távoli kapcsolat létesítését egyetlen felhasználóhoz sem. Ezt megváltoztatjuk, a root belépést letiltjuk és létrehozunk egy másik felhasználót, amivel adminisztrálni fogjuk a rendszert. A felhasználók a MySQL mysql adatbázisában, a user táblában találhatók. Ide közvetlenül beírva (INSERT, UPDATE, DELETE) létrehozhatunk felhasználókat, de használhatjuk a CREATE USER, GRANT parancsokat is. Lépjünk be lokálisan root-ként és végezzük el a módosításokat.

1: # mysql –u root –p localhost
2: # mysql> CREATE USER ’admin_userem’@’localhost’ IDENTIFIED BY ’admin_jelszava’;
3: # mysql> GRANT ALL PRlVILEGES ON *.* TO ’admin_userem’@’localhost’ WITH GRANT OPTION;
4: # mysql> CREATE USER ’admin_userem’@’%’ IDENTIFIED BY ’admin_jelszava’;
5: # mysql> GRANT ALL PRlVILEGES ON *.* TO ’admin_userem’@’%’ WITH GRANT OPTION;
  • 1: Lokálisan belépünk rootként a MySQL-be (csak lokálisan tehetjük alapértelmezés szerint és ezt így is érdemes hagyni a biztonság érdekében).
  • 2: Létrehozunk egy adminisztrálásra szánt, új felhasználót, amely lokálisan be tud lépni.
  • 3: Összes adatbázison, minden táblához minden jogot megadunk a felhasználónak és ennek továbbörökítésének lehetőségét.
  • 4-5: Mint 2-3, csak a % wildcardot használva bármely kinti hosztról is csatlakozhat a felhasználó ezután és nem csak lokálisan.


Innentől kezdve használhatjuk MySQL Administrator programunkat bármilyen adminisztrációs feladatra. Figyelni kell arra, hogy a létrehozott felhasználók is kétszer szerepeljenek az adatbázisban, localhosttal és % wildcarddal, mert csak akkor tudnak távolról is adminisztrálni és lokálisan (WEB alkalmazás) is módosítani. (Ha MySQL Administrator programból veszünk föl új felhasználót, akkor alapértelmezésben így történik, és nem kell erre külön figyelni.)

5 FTP konfiguráció

Közkedvelt, szélesen skálázható FTP szerver a ProFTPd. Ezt fogjuk használni, mert nagy múltra tekint vissza.

5.1 Telepítés, konfiguráció és keményítés

Telepítés:

# aptitude install proftpd

Fönt van és már működik is az FTP szerverünk, alig kell rajta finomhangolni. Alap esetben – és ezt fogjuk használni – a felhasználó adatbázisát a Linux felhasználó adatbázisából veszi. Ez eddigi törekvéseinknek meg is felel, hiszen egy-egy virtuális WEB szolgáltatáshoz szeretnénk egy-egy FTP szolgáltatást is nyújtani.
(Egy nagyobb virtuális szerver szolgáltató esetében, ahol esetleg kifejezetten csak FTP szolgáltatást is akarunk nyújtani, telepíthetjük a proftp-mod-mysql csomagot is, amely lehetővé teszi, hogy ne valós Linux felhasználók alapján működjön a beléptetés, hanem MySQL táblázatban meghatározott felhasználókat azonosíthasson a szerver. Ez a fájl hozzáférési jogok átgondolását is magában rejti, amennyiben más szolgáltatásokkal szeretnénk összefűzni.)
Pár beállítás változtatási tanács:
/etc/proftpd/proftpd.conf:

1: …
2: Umask 077 077
3: MaxInstances 30
4: DefaultRoot ~
5: ServerName „én szerverem”
6: ServerIdent off
7: …
  • 2: Ennek megfelelően az FTP szerver minden feltöltésnél a fájlhozzáférési jogoknál kapásból kimaszkolja a csoport és bármely felhasználó jogait 0-ra. Fontos, hogy ezt azért is tehetjük meg, mert mpm-itk-t használunk Apache esetében, ugyanis ha nem a virtuális szerver saját felhasználójával futna a WEB szerver, akkor ezzel gyakorlatilag ellehetetlenülnének a WEB-es interfészről konfigurálható CMS-ek.
  • 3: Ez a maximális proftpd gyermek processzek számát határozza meg. Ez a szám egy nagyobb szolgáltató esetén értelemszerűen sokkal nagyobb lehet.
  • 4: Itt egy wildcard karakterrel határoztuk meg, hogy minden felhasználó FTP szolgáltatásának a gyökere a saját $HOME-jában legyen. (Érdemes lehet meggondolni a „DefaultRoot ~/html” beállítást is, illeszekedve az Apache konfigurációjához.)
  • 5: Szerver nevét érdemes lehet megváltoztatni. ;)
  • 6: Alap esetben elárulja verzióját a proftpd, ez nem biztos, hogy hasznos. Megadhatunk más fajta „ident” üzenetet is, de legegyszerűbb, ha off-ra tesszük és kikapcsoljuk, ha valamit közölni akarunk, azt úgyis megtehetjük a welcome.msg fájlba írással.

Ha csak nem változtattuk meg a proftpd.conf –ban a DisplayLogin direktívát, a welcome.msg fájlba írt üzenetet közli a szerver a beléptetett felhasználóval. Itt is gazdagon használhatunk wildcard karaktereket (pl. felhasználónév, dátum stb. kiírására).

6 Kvóta beállítás

Most hogy már föl is tölthetik oldalaikat a felhasználók elengedhetetlenné vált, hogy fájlrendszer szintű kvótákat kezeljünk. Ez arra lesz jó, hogy a felhasználók állományai ne hízhassanak, gyarapodhassanak a végtelenségig, hanem egy jól megszabott korláton belül maradjon. Ehhez szükség lesz quota csomagra:

# aptitude install quota

Ezen kívül mount paraméterként is meg kell adnunk, hogy az adott fájlrendszeren szeretnénk engedélyezni a kvótakezelést. Ezt az /etc/fstab options oszlopában tehetjük meg:

# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
…
/dev/mapper/nvidia_ddagdicb1 /               ext3    errors=remount-ro,usrquota,grpquota 0       1
…

Felkerültek a kvóta kezelő fájlok és programok. (/aquota.* ; quota; edquota stb.) Az „edquota user_name” paranccsal adhatunk meg kvótát a user_name felhasználónak. Az edquota parancs a default editort hívja meg szerkesztéshez. Ha ezen változtatni szeretnénk, annak egyik lehetséges módja, ha az $EDITOR környezeti változót megváltoztatjuk szájízünk szerint.
Például ha a joe szerkesztőt szeretnénk használni:

# export EDITOR=joe
# edquota user_name

Itt a soft és a hard alatti 0-kat fogjuk átírni pl. 200000 és 250000-re. Ez azt jelenti, hogy softlimitnek adtunk körülbelül (mivel blokkokról beszélünk) 200 MB tárkorlátot, hardlimitnek kb. 250 MB-ot. Elmentve a beállítást máris élnek az új korlátok. A softlimit az alapvető tárkorlátot jelenti, ha szeretnénk némi rugalmasságot vinni ebbe, akkor adhatunk nagyobb hardlimitet. Ez azt jelenti, hogy a felhasználónak softlimitnyi tár áll a rendelkezésére, de egy meghatározott ideig túllépheti maximum hardlimitnyi tárkorlátig. Ezt a meghatározott időt „grace period”-nak hívják. Alap beállítása általában 7 nap.
Példa egy kvótáját éppen (egy napja) túllépő felhasználóra:

Disk quotas for user user_name (uid 1005):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/mapper/nvidia_ddagdicb1
                 210224* 210000  250000   6days   14297       0       0


A következő parancsokat használjuk leggyakrabban:

1: # quota –u user_name
2: # edquota user_name
3: # edquota –t
4: # repquota -a
  • 1: Kvóta adatokat kérhetünk le az adott felhasználóról. Argumentum nélkül meghívva a lekérdő kvóta adatait adja. (Hasznos lehet a –s paraméter.)
  • 2: Az adott felhasználó kvóta értékeit változtathatjuk meg.
  • 3: A grace period értékét adhatjuk meg.
  • 4: A repquota parancs összesített kvóta adatok lekérdezésére szolgál („-a” paraméterre minden felhasználó kvóta adatait kiírja).

7 Felügyelet

Nyilvánvaló okokból fontos a szerver felügyelete. Ez magában foglalja a rendszer-, kiszolgálók állapotának monitorozását és a rosszindulatú támadások figyelését is. Ezeket mindig meg lehet oldani konzolos, „log nézegetős” módszerrel, azonban sokkal produktívabb, valami olyan keretrendszer használata, amely földolgozza ezeket és gyors, könnyű áttekintést nyújt. A felügyelet rész erre ad konkrét megoldásokat.

7.1 Munin

Az aktuális és múltbéli rendszer- és kiszolgáló állapotokról ad tájékoztatást, ezekről grafikont rajzol. Szép, webes formában lehet nyomon követni a változásokat.
Részletesen itt: A_munin_működése (tananyag)

# aptitude install munin

Egy alapvető egy node-os munin beállításhoz már csak az /etc/munin/munin.conf „htmldir” direktíváját kell egy megfelelő helyre átírni, vagy éppen linkelni egy létező WEB szolgáltatás egy könyvtárába, hogy böngészhető legyen.
A munin plugin rendszert használ a legkülönfélébb állapot megfigyelésekhez, ezek közül alapból csak néhány van bekapcsolva, de általában az elég fontosak. Ezeket személyre szabhatjuk. A /usr/share/munin/plugins könyvtárban találhatók a pluginek, amelyeket használni lehet. Ezeket belinkelve az /etc/munin/plugins könyvtárba kerülnek használatra.
Például szeretnénk még az uptime-ot is grafikusan monitorozni, mert olyanunk van:

# ln –s /usr/share/munin/plugins/uptime /etc/munin/plugins/uptime

Azonban sokszor nem ilyen egyszerű 1-1 plugin működtetése. Ezeket mindig megtaláljuk a plugin fájlban leírva, a fájl elején kommentezve. Ilyen lehet az „ip_” plugin, amiben olvasható a leírás a használatáról:
/usr/share/munin/plugins/ip_:

#!/bin/sh
#
# Wildcard-plugin to monitor IP addresses through iptables. To monitor an
# IP, link ip_<ipaddress> to this file. E.g.
#
#    ln -s /usr/share/node/node/plugins-auto/ip_ /etc/munin/node.d/ip_192.168.0.1
#
# ...will monitor the IP 192.168.0.1.
#
# Aditionally, you need these iptables rules as the first rules (they don't do anything, just make packet counts)
#
#    iptables -A INPUT -d 192.168.0.1
#    iptables -A OUTPUT -s 192.168.0.1
#
# Furthermore, this plugin needs to be run as root for iptables to work
#
# This plugin is based on the if_ plugin.
#
#$Id:$
#
#
# Magic markers (optional - used by munin-config and some installation
# scripts):
#
#%# family=auto
#%# capabilities=autoconf suggest

Ha mégmégtöbb pluginre vágyunk telepíthetjük a munin-plugins-extra csomagot:

# aptitude install munin-plugins-extra

Utolsó lépésként még szeretnénk, ha csak mi érhetnénk el egy egyszerű jelszavas autentikációval a munin tartalmát. Ha nem kapcsoltuk ki, az apache-ban engedélyezve van a .htaccess fájlok használata. Hozzunk létre egyet a munin web könyvtárában a következő sorokkal:
.htaccess:

AuthType Basic
AuthName munin
AuthUserFIle /etc/apache2/access
Require user felugyelo_usernevem

Ezzel megadtuk, hogy csak akkor szolgáljon ki az apache, ha sikeres jelszavas autentikáció történt. Ezt az /etc/apache2/access fájlból ellenőrizze és csak a felugyelo_usernevem felhasználóra engedélyezze. Már csak az access fájlt kell létrehoznunk és föltöltenünk felhasználó-jelszóhash párokkal. Ezt a htpasswd paranccsal tehetjük:

# htpasswd /etc/apache2/access felugyelo_usernevem


7.2 Acidbase

Az acidbase webalkalmazás a Snort log fájljait képes strukturált, átlátható módon megjeleníteni webes felületen. Miután a Snort egy külön óriás előadást megér, ezért csak néhány alapvető dolgot mondanék el és konfigurációját a telepítés utáni alap konfiguráción hagyjuk, úgy már egy működő rendszert fogunk kapni, igaz sok fals pozitív riasztással.

7.2.1 Snort röviden

A Snort egy IDS (Intrusion Detection System). Szállítási- és alkalmazás rétegben működik, ezért az ezekben a rétegekben történt támadásokat képes csak detektálni. A felismerést minták alapján végzi, az adott alkalmazás protokollal szoros összhangban. Dióhéjban ezek a minták, melyek egy alkalmazás protokollhoz hűen vannak megírva, alkotnak egy szabály(rendszer)t. Ezeknek a finomhangolása nagyon nehéz feladat. A fals pozitív riasztások miatt nem érdemes konkrét intézkedéseket kötni egy-egy riasztáshoz.
Telepítsük a Snort-ot.

# aptitude install snort

Működésbe is lépett, az /etc/snort/rules könytárban található *.rules szabályok alapján már végzi is az illeszkedő forgalom naplózását. Ezek a /var/log/snort/alert fájlba kerülnek kiírásra. Egy ilyen naplófájl elemzése elég nehézkes hosszútávon, főleg sok riasztás esetén. Ennek megoldására fogjuk használni az acidbase-t.
Példa egy riasztásra, melyet az SMTP protokoll FROM mezőjének túlcsordítási kísérlete váltott ki:

[**] [1:2590:4] SMTP MAIL FROM overflow attempt [**]
[Classification: Attempted Administrator Privilege Gain] [Priority: 1]
10/07-14:52:38.291729 174.136.132.221:54052 -> 1.2.3.4:25
TCP TTL:240 TOS:0x10 ID:0 IpLen:20 DgmLen:2960
***AP*** Seq: 0x16EAB190  Ack: 0x4929E8F3  Win: 0x3908  TcpLen: 20
[Xref => http://www.guninski.com/exim1.html][Xref => http://cve.mitre.org/cgi-bin/cvename.cgi?name=2004-0399][Xref => http://www.securityfocus.com/bid/7506][Xref => http://www.securityfocus.com/bid/10290]

Szeretnénk, ha Snort nem csak az alert fájlba írná az eseményeket, hanem adatbázisba is, mert ebben az esetben tud az acidbase átfogó működést biztosítani. A Snort telepítésekor elvileg lehetőség nyílt adatbázis felhasználó és jelszó bevitelére. Ha ezt nem tettük meg, akkor a már följebb tárgyalt módon létrehozunk egy snort felhasználót az adatbázisban és jelszavat hozzá. Létrehozunk egy üres snort adatbázist számára. A Snort maga nem tud még egy üres adatbázissal mit kezdeni, ezért azt a megfelelő táblákkal, oszlopokkal stb. föl kell tölteni. Erre szerencsére nem kell kézzel vállalkoznunk. Egy alkalmas script megtalálható a /usr/share/doc/snort-mysql/create_mysql.gz zgip fájlban. Ezt a legegyszerűbb, ha MySQL administratorral megetetjük, de parancssorosan is megtehetjük. Érdemes snort adatbázis felhasználóval végezni ezt már, nehogy más táblába írjunk bele. Ha megcsináltuk, „dpkg-reconfigure snort” paranccsal frissíthetjük a konfigokat, vagy megpróbálhatjuk manuálisan. Ekkor csak pár módosítás a snort.conf-ban, snort újraindítás és készen vagyunk.
/etc/snort/snort.conf:

…
output database: log, mysql, user=snort password=PASS dbname=snort host=localhost
…
# /etc/init.d/snort restart


7.2.2 Acidbase telepítés

# aptitude install acidbase

Az acidbase a snort adatbázisában tárolt eseményeket olvassa ki és jeleníti meg. Ennek megfelelően meg kell adni neki a snort adatbázis hozzáférési adatait. Ezt telepítéskor van módunk megtenni, ha később manuálisan meg akarjuk változtatni, akkor írjuk át a hozzáférési adatokat az /etc/acidbase/database.php –ben és az /etc/dbconfig-common/acidbase.conf –ban is. Előbbiben meg is kapjuk a magyarázatot utóbbi mivoltára.
/etc/acidbase/database.php

##
## database access settings in php format
## automatically generated from /etc/dbconfig-common/acidbase.conf
## by /usr/sbin/dbconfig-generate-include
## Fri, 29 May 2009 18:54:09 +0200
##
## by default this file is managed via ucf, so you shouldn't have to
## worry about manual changes being silently discarded.  *however*,
## you'll probably also want to edit the configuration file mentioned
## above too.
##
$alert_user='snort';
$alert_password='PASS';
$basepath='';
$alert_dbname='snort';
$alert_host='';
$alert_port='';
$DBtype='mysql';

Rajtra kész a rendszer, az acidbase maga a /usr/share/acidbase mappában található, már csak az Apache-ba kell behegeszteni.
Az /etc/acidbase/apache.conf fájlban állítsuk be, milyen elérési útvonalat szeretnénk használni.
pl:
/etc/acidbase/apache.conf

<IfModule mod_alias.c>
  Alias /acidbase "/usr/share/acidbase"
</IfModule>

<DirectoryMatch /usr/share/acidbase/>
  Options +FollowSymLinks
  AllowOverride AuthConfig
  order allow,deny
  Allow from all
  AuthType Basic
  AuthName "Snort"
  AuthUserFile /etc/apache2/access
  Require user felugyelo_usernevem
  <IfModule mod_php4.c>
    php_flag magic_quotes_gpc Off
    php_flag track_vars On
    php_value include_path .:/usr/share/php
  </IfModule>
</DirectoryMatch>

A /usr/share/acidbase –re Aliasnak megadtuk a /acidbase-t. Ezután a kívánt virtuális webszerver konfigurációs fájljában meg kell hívnunk ezt a konifgot, hogy érvényes legyen alatta. (Vagy ha globálisan szeretnénk, akkor egész egyszerűen linkeljük az /etc/apache2/conf.d könyvtárba.)
/etc/apache2/sites-available/virtual_server1:

…
Include /etc/acidbase/apache.conf
…

Látható az apache.conf –ban, hogy itt is autentikációhoz kötöttük az oldal megtekintését, hasonlóan mint munin esetében, csak nem .htaccess fájlban, hanem Directory tag utasításban.

8 Összegzés

Ezzel a konfigurációval egy elég stabil és relatíve biztonságos rendszert építettem ki tapasztalatom szerint. A debian security frissítéseket alkalmazva a csomagokat is szépen stabil állapotban, biztonsági lyuk mentesen lehet tartani.
/etc/apt/sources.list

deb http://security.debian.org/ lenny/updates main contrib non-free

A brute force jellegű támadások folyamatosak, de haszontalanok. Egy iptables limit direktívát belőve minden szolgáltatási portra csökkenthetjük az egy IP-ről bejövő próbálkozásokat. Iptables konfigurációra nem térek ki, mert az egy nagyon hosszú fejezetet érne meg. Azonban az ezzel kapcsolatos javaslatom, amit érdemes betartani, hogy ha egy komoly, összetett szabályláncot alkalmazunk, amit magunk írunk, akkor annak tesztelésénél érdemes előtte cronban hatástalanító szkriptet futtatni pár perces időközzel, ugyanis, ha valami nagyon nem jól sülne el, kizárhatjuk magunkat a rendszerből, főleg egy deny policy-s lánccal. (Hasonlóan óvatosan bánjunk az ssh távoli átkonfigurálásával és megspórolhatunk egy utazást a hoszting farmra.)
Az alkalmazásszintű támadásoknál leginkább a kiszolgált CMS-ek cross-site scripting és code injection támadása a gyakori. Volt eset, amikor a munin figyelmeztetése ébresztett rá egy sikeres támadásra, amely az apache lelassulását eredményezte, de ezekre megoldást nyújtottak a leírt védelmi megoldások.
Általánosak a botnetek folyamatos próbálkozásai is, de ezek főleg valamilyen hibás kiszolgáló verziót céloznak meg és hatástalanok.

Személyes eszközök