Usporedba nginx-a, lighttpd-a i apache-a, sa posebnim naglascima na raspoloživost i mogućnosti sigurnosnih nadogradnja i sigurnosti

Izvor: SIS Wiki
Skoči na: orijentacija, traži
PODJELA RADA:

NGINX - Ivan Pušić
Lighttpd - Mario Peroković
Apache - Tomislav Priselac
Cherokee - Alen Pek

Zaključak i testovi - Zajednički rad


Sadržaj

NGINX

Logo nginx.png

NGINX je HTTP i “reverse proxy” server kao i “mail proxy” server kojeg koriste već mnoge poznate web stranice, npr youtube, wordpress itd.. Iako se po internetu može pročitati dosta o tome kako NGINX baš i nije lagano konfigurirati, i vjerovatno je to jedan od razloga zašto neki ljudi jednostavno niti ne probaj ovaj odličan server, smatram da konfigurirajne ovog servera nije ništa kompliciranije od konfiguriranja npr. Apache-a, jer imamo dostupnu odličnu dokumentaciju a također i njihov wiki http://wiki.nginx.org/Main, a uz to mozemo pomoć potražiti i na IRC kanalu #nginx irc.freenode.net.

Samo razvijanje web sustava može samo po sebi biti i lagano, no problem dolazi sa skalabilnošću. Upravo za to je NGINX odličan izbor jer se fokusira na visoke performanse, visoku konkurentnost te malu količinu memorije koju će upotrebljavati, a kao potvrdu tome pogledajmo iduću sliku na kojoj su prikazana neka nama poznata imena koja su svoje povjerenje što se tiče web servera dali NGINX-u. http://nginx.com/company.html#nginx-users -> izvor

Problem kod tipičnih arhitektura web servera je što se teško nose sa velikim brojem konkurentnih konekcija, a vidimo i sami da je to danas zahtjev bez kojeg bi neke veliki web sustavi teško funkcionirali. Neka standardna arhitektura web servera prije dolaska NGINX-a i njegove arhitekture bila je da svaku novu konekciju obrađuje u novoj dretvi ili procesu, i samim tim dolazilo je do problema što se tiče iskorištenja procesora, memorije i sl., jer samo stvaranje procesa je zahtjevan posao za sustav jer mora alocirati memoriju i druge sustavke resurse kako bi sve zajedno uredno radilo.

NGINX nije išao tim smjerom nego je donio sam sobom jednu novu filozofiju što se tiče upravljanja konkurentnim konekcijama a to je tzv. “event based mechanism”, a to je rezultiralo serverom koji je naposljetku imao modularanu, “event-driven, asynchronous, single-threaded, non-blocking” arhitekturu. NGINX obrađuje zahtjeve u tzv. “worker”-ima, koji su jednodretveni procesi, a svaki takav može obraditi po nekoliko tisuća konkurentnih konekcija. Zbog njegove modularne arhitekture developeri su u mogućnosti da prošire samu arhitekturu servera, te da dodaju neke svoje “feature” koji su im potrebni. Na sljedećoj slici možemo vidjeti izgled NGINX arhitekture:

NGINX arhitektura

Na sljedećem linku se nalazi i odličan članak koji objašnjava NGINX arhitekturu servera: http://www.aosabook.org/en/nginx.html

Sam NGINX server možemo lako instalirati pomoći "package manager-a". Također imamo opciju i da kompajliramo source kod servera ukoliko to želimo ili imamo potrebu za takvim načinom instalacije servera. Ukoliko se odlučimo za ovaj lakši način, odnosno instaliranje putem package manager-a, možemo na instalirati (pod pretpostavkom da koristimo apt-get PM) naredbom:

sudo apt-get install nginx

Ukoliko koristimo yum PM server možemo instalirati naredbom:

sudo yum install nginx

Nakon što smo instalirali server isti možemo pokrenuti naredbom:

sudo service nginx start

Konfiguracijski file-ovi se obično nazale u

 /etc/nginx/ 

ili

 /usr/local/etc/nginx/ 

Dijelovi konfiguracijskih file-ova se mogu razdvojiti u više datoteka, te samim time se dobiva na lakoći održavanja konfiguracijskih file-ova, a sami konfiguracijski file-ovi koriste “c-style” oblik sintakse.

Konfiguracija NGINX-a

Što se tiče samog sadržaja konfiguracijskih file-ova kao što sam već rekao oni mogu biti razvojeni u više dijelova, no postoji jedan početni file iz kojeg NGINX čita neke globalne postavke što se tiče konfiguracije. U mom slučaju (Fedora Linux) taj konfiguracijski file se nalazi u /etc/nginx/nginx.conf datoteci, i jedan od mogućih sadržaja tog file-a je:

user              nginx;
worker_processes  4;

error_log  /var/log/nginx/error.log;

pid        /run/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;

    gzip             on;
    gzip_min_length  1000;
    
    # Load config files from the /etc/nginx/conf.d directory
    # The default server is in conf.d/default.conf
    include /etc/nginx/conf.d/*.conf;

}

Na početku smo definirali korisnika pod čijim imenom će se NGINX pokretati. U ovom slučaju smo samo specificirali korisnika, ali ne i grupu kojoj pripada. Grupu možemo definirali npr. sa user nginx users; gdje je "users" zapravo grupa. Keepalive Kod direktive worker_processes ukoliko se NGINX bavi zahtjevnijim poslovima dobro je broj tih "worker-a" (o njima smo pričali u prošlom poglavlju) staviti na broj jezgri procesora. Znači ukoliko imamo neki dual core procesor onda ćemo ovdje staviti broj 2.

Taj broj možemo doznati linux naredbom:

nproc

Ukoliko želimo detaljnije informacije o procesoru servera na kojem se nalazi NGINX server to možemo doznati naredbom:

lscpu

Primjer ispisa:

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 58
Stepping:              9
CPU MHz:               1200.000
BogoMIPS:              4190.37
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              6144K
NUMA node0 CPU(s):     0-7

Zatim sa error_log definiralo na koju lokaciju želimo da nam se spremaju error logovi, u našem slučaju to je /var/log/nginx/error.log. Zatim smo definirali lokaciju file-a u kojem će se spremat PID od NGINX-a kako bi mogli prema tom PID-u poslati NGINX-u određene signale.

Poslije toga nam dolazi events blok, koji je dio EventsModule modula i definira kako NGINX postupa sa konekcijama. U bloku vidimo da definiramo broj worker_connections-a, a pomoću ovoga mozemo izračunati maksimalni broj konekcija koji nam NGINX može obraditi. Taj broj se dobije sljedećom formulom:

max clients = worker_processes * worker_connections 

Zatim u http bloku definiramo MIME tipove koji su podržani. u ovom slučaju su definirani u odvojenom file-u /etc/nginx/mime.types. Sadržaj tog file je npr:

types {
    text/html                             html htm shtml;
    text/css                              css;
}

Naravno vrlo vjerovatno ćemo trebati dodati još podržanih tipova, no to nam sigurno neće biti problem. Ukoliko se tip ne može pronaći u definiranima upotrebljen će biti onaj koji je specificiran default_type direktivnom. Sa log_format definiramo standarni oblik LOG zapisa.

Sa direktivom access_log definiramo file, veličinu buffera i format ove vrste LOG zapisa. SendFile direktivna omogućuje kopiranje file-ova između file-deskriptora. Ovo je učinkovitiji način kopiranja od kombinacije "read", "write", jer ovdje prenosimo direktno podatke sa memorije računala na kojoj se vrti server na buffer mrežne kartice.

keepalive_timeout direktivom definiramo timeout tijekom kojeg će NGINX držati konekciju sa klijenom otvorenom. postoji također i keepalive direktiva kojom definiramo maksimalan broj konekcija koje server drži otvorenima. Ukoliko taj broj pređe specificirano server zatvara najstariju konekciju.

Sa gzip direktivom možemo uključiti kompresiranje podataka koji se prenose NGINX serverom. Također smo specificirali da file-ovi veličime manje od 1000 bajova ne budu kompresirani. Ovo nam može smanjiti količinu podataka koje se prenose između servera i klijenta jer će podaci biti kompresirani.

Na kraju smo uključili direktivom include ostale konfiguracijske file-ove, a sada pogledajmo sadržaj jednog takvog file-a.

server {
    listen   80 default_server;

    server_name  127.0.0.1;

    location / {
        root   /usr/share/nginx/html;
	index  index.html index.htm 
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Ovdje vidimo neku osnovnu konfiguraciju za npr. neku domenu. Ovime smo zapravo definirali jedan virtualni NGINX server, a takvih možemo imati naravno više. Postavlja se pitanje kako NGINX odlučuje kojem virtualnom serveru da proslijedi zahtjev. On to radi tako da pretražuje imena servera koji su specificirana u direktivi server_name. Npr. u našem slučaju server se zove 127.0.0.1, no mogao se zvati i www.mojserver.com. Vidimo da smo definirali i port na kojem server prima dolazeće zahtjeve, to je u ovom slučaju port 80. Zatim nam dolaze location direktive. Njima definiramo specifične opcije i akcije za pojedine URL-ove kojima može korisnik pristupiti. Vidimo da smo za lokaciju "/" definirali da je folder u kojem se nalazi sadržaj kojem trebaju pristupati klijentu na lokaciji "/usr/share/nginx/html", a index stranice su file-ovi imena oblika "index.html, index.htm". Navest ću postojanje i alias direktive, koju neki mješaju sa root direktivom. U jednom i drugom specificiramo lokacije na kojima server treba tražiti sadržaj, no ipak se razlikuju u jednoj bitnoj stvari koja nam u pojedinim slučajevima može stvarati probleme.

Uzmimo sljedeći primjer. Recimo da imamo definiranu lokaciju oblika:

location /test/ {

}

Pretpostavimo da se sadržaj koji želimo posluživati ovom lokacijom nalazi u direktoriju /tmp/test/.

Ukoliko koristimo direktivu root da bi ovo radilo trebamo staviti

root     /tmp/

Dok u slučaju da koristimo alias direktivu, da bi stvar uredno radila trebamo definirati alias oblika:

alias    /tmp/test/

Naime kod direktive root NGINX automatski na folder koji smo definirali dodaje i lokaciju za koju smo definirali root direktivu, u našem slučaju konačan folder na kojem će NGINX tražiti sadržaj biti će /tmp/test/, dok u slučaju da smo u root direktivu stavili lokaciju kao i kod alias, NGINX bi tražio na lokaciji /tmp/test/test/ što bi izazvalo grešku. U ostatku konfiguracijskog file-a smo definirali defaultne lokacije za pojedine response kodove.

Odličnu dokumentaciju o samom konfiguriranju servera, primjere konfiguracijskih file-ova te još mnogo toga možemo potražiti na sljedećoj lokaciji http://wiki.nginx.org/Configuration

U nastavku ćemo malo po malo nadograđivati ovaj osnovni konfiguracijski file sa posebnim naglascima na sigurnost i visoku raspoloživost NGINX servera.

Raspoloživost (High-avability)

Kao što svi već znamo visoka raspoloživost je jedna od najbitnijih komponenti u procjeni jel neki web sustav dobar (za korisnike) ili ne. U ovom dijelu ćemo se bazirati na pregled alata i konfiguracijskih file-ova koji mogu unaprijediti raspoloživost NGINX servera. Primjetite da sam “servera” rekao u množini, jer kada gradimo “high-avability” sustave onda to podrazumjeva veći broj računala koja međusobno “surađuju”. Kako bi testirali neke alate koji nam pružaju podršku što se tiče high-avability-a napravio sam dvije ubuntu virtualke koje će glumiti dva web-servera, a treće računalo pogoni “Linux-Fedora” i na njemu će biti smješteni ti “alati” (HeartBeat, HaProxy, UpStart). Postoji opiširna priča oko ovih alata, no mi ćemo se bazirati na njihovu konfiguraciju. Prvi alat s kojim ćemo se poigrati je “HeartBeat”.

HeartBeat

HeartBeat je “deamon” koji pruža grupnu odnosno “cluster” arhitekturu servisa svojim klijentima. Ovo omogućava da klijenti razmjenjuju poruke o tome dal je neki server u nekom trenutku “up” ili “down”. Npr. u slučaju da imamo 2 servera, ukoliko jedan iz nekih razloga više nije u mogućnosti posuživati klijente njegovu ulogu preuzima drugi server, te tako održava cijeli sustav dostupnim. Konfiguracija svakog servera može biti jednostavna a isto tako i prilično složena, ovisno o zahtjevima koje imamo, i o opsegu arhitekture za koju radimo određenu konfiguraciju servera. Ovdje ćemo se pozabaviti nekim osnovnim konfiguracijama koje su dovoljno dobre da korektno prikažu funkcionalnost softwera kojeg opisujemo u nekom trenutku.

Konfiguracija HeartBeat-a je rascjepkana u 3 file-a, a to su authkeys, ha.cf i haresources. Lokacija ovih file-ova je obično u /etc/ha.d/ direktoriju. U file-u authkeys je kao što već i sami pretpostavljate autentikacijski file za “heartbeat cluster messaging layer”, odnosno file nam omogućava da sigurno autenticiramo nodove koji se nalaze u nekoj grupi servera (eng. Cluster). Naš file će se sastojati od svega dvije linije. Prva služi da specificiramo koji ključ da upotrebljavamo prilikom potpisivanja odlaznih paketa, a drugi da definiramo kako dolazni paketi mogu biti potpisani. Taj file izgleda otprilike ovako:

auth num
num method secret
num method secret
num method secret

num je numericki identifikator čija vrijednost je između 1 i 15, a mora biti jedinstven na razini ove datoteke. Method predstavlja jednu od podržanih metoda za potpisivanje (podržani su sha1, md5, crc), a secret je alfanumericki ključ koji je podjeljen svim članovima clustera.

auth 2
2 sha1 test-ha

Ovo je sadržaj authkeys file-a koji je rađen za potrebe ovog projekta. Također je bitno da podesimo dozvole nad file-om, a to možemo učiniti sljedećom komandom:

chmod 600 /etc/ha.d/authkeys

Sljedeći jako bitan file je ha.cf, a pomoću njega konfiguriramo “messsaging layer” heartbeat clustera. U tom file-u nalaze se imena nodova koji su članovi clustera, zatim u tom file-u možemo uključiti ili isključiti pojedine funkcionalnosti, itd.. Od važnijih postavki u tom konfiguracijskom file-u izdvojio bi “keepalive” kojim specificiramo vrijeme koji će biti između dvaju “heartbeat” paketa. Deadtime je vrijeme nakon kojeg će heartbeat proglasati neki nod mrtvim ukoliko mu naravno isti ne šalje odgovore. Sa auto_failback specificiramo dal želimo da heartbeat odmah nakon oporavka primarnog noda, postavi primarni nod kao glavi na koji će stizati zahtjevi od klijenata. Node direktiva nam govori koja su to račuala u clusteru. Ovdje imamo konfiguracijski file za naš pokazni primjer, i vidimo da smo specificirali 2 servera u njemu.

logfile /var/log/ha-log
logfacility local0

keepalive 10ms
warntime 100ms
deadtime 200ms
initdead 10

bcast eth0
udpport 696
auto_failback on
node server1
node server2

Zadnji file s kojim se moramo poigrat a potreban je da bi heartbeat proradio je haresources. Tim file-om govorimo koje resurse želimo da nam osposobi heartbeat, i na kojoj ip adresi. Heartbeat će u ovom slučaju sam pokrenuti NGINX server. Ovdje imamo i prikazan izgled našeg pokaznog konfiguracijskog file-a.

server1 10.24.21.122 nginx

Ova 3 konfiguracijska file-a trebaju biti identicna na oba računala. Kada smo sve kopirali na oba računala spremi smo da testiramo naš high-avability cluster pokretan NGINX serverima. Možemo na pokrenuti na sljedeći način (potrebno pokrenuti na oba servera):

sudo service heartbeat start

Nakon toga ukoliko odemo na adresu 10.24.21.122 (u našem slučaju) vidjet ćemo odgovor primarnog servera. No ukoliko na tom serveru isključimo npr. mrežu, svi zahtjevi će se preusmjeriti na drugi server, i tako će sustav i dalje biti dostupan klijentima. Nakon što se primarni server vrati u funkciju, svi zahtjevi će se usmjeravati prema njemu. U ovom primjeri smo vidjeli kako se NGINX može lagano ukomponirati pomoću heartbeat-a u jednu cluster high-avability arhitekturu. Dokumentaciju možemo pronaći na ovom linku http://www.linux-ha.org/doc/users-guide/users-guide.html

DEMO možete pogledati ovdje: http://www.youtube.com/watch?v=X8vD75CNa5o&feature=youtu.be

Sada ćemo pogledati i jedan modul koji nam dolazi sa samim NGINX-om a može također pridonijeti visokoj dostupnosti servera.

HttpUpstreamModule modul

Jedan od zanimljivijih NGINX modula je zasigurno i upstream, koji nam pruža “load-balancing”. Uz pomoć ovog modula na jednostavan način možemo ostvariti balansiranje prometa između NGINX servera, sve što trebamo je u konfiguracijskom file-u imat ovako nešto:

upstream lb_units {
      server 10.24.21.122:80 weight=2 max_fails=0;
      server 10.24.21.123:80 weight=1 max_fails=0;
}
location / {
      proxy_pass         http://lb_units;
}

U direktivi “upstream” specificiramo ime koje želimo dati našem server clusteru, a kao što vidimo on se sastoji iz 2 servera. Sa “wight” specificiramo koliko će requestova za redom ići na server prije nego što load-balancer ne presumjeri promet na drugi server iz clustera. Pomoću “max_fails” specificiramo nakon koliko neuspješnih pokušaja komunikacije sa serverom će server biti proglašen da je izvan funkcije. Nakon ovih postavki, restart-amo naš NGINX server na kojeg smo pisali ove konfiguracijske postvke, i imamo postavljen load-balancing između NGINX servera.

Postoji i modul koji nam omogućava da prije nego pošaljeno neki zahtjer na server provjerimo stanje tog servera, te ukoliko nešto nije u redu sa serverom da automatski šaljemo na drugi server definiran u upstream direktivi. Više o tome se može pročitati ovdje: http://wiki.nginx.org/HttpHealthcheckModule.

Također postoji modul koji nam omogućava ograničavanje broja konekcija po serverima koji su definirani u upstram direktivi. Više o tome se može pročitati ovdje: https://github.com/cfsego/nginx-limit-upstream/.

Dokumentaciju modula možemo pronaći na ovom linku: http://wiki.nginx.org/HttpUpstreamModule

DEMO možete pogledati ovdje: http://www.youtube.com/watch?v=m-wfxDNr29o&feature=youtu.be

HaProxy

HaProxy se može definirati kao high-avability proxy kao i TCP/HTTP load-balancer. U ovom dijelu ćemo pokazati konfiguracijski file u kojem će se balansirati promet između dva NGINX servera. HaProxy sprječava preopterećenje nekog servera tako da balansira promet između servera na način da koristi jednu zadanu shemu balansiranja. Napomenimo da je dostupno i više shema balansiranja (roundbin, leastconn...). HaProxy ima i mehanizam detekcije ispada nekog od servera, jer prilikom balansiranja ukoliko je neki server van funkcije, dok isti ne dodje ponovo u normalno stanje zahtjevi moraju biti usmjeravani na druge servere. Prednost HaProxy-a je i to što imamo jednu Public IP adresu koja je dodjeljena HaProxy-u i iza nje se moze nalaziti dosta servera kojima pristupamo preko te jednistvene IP adrese. Konfiguracijski file za HaProxy uobčajeno se nalazi u /etc/haproxy/ direktoriju, a sadržaj tog konfiguracijskog file-a koji je kreiran za potrebe ovog rada je:

global
        log 127.0.0.1   local0
        log 127.0.0.1   local1 notice
        maxconn 4096
        user haproxy
        group haproxy

listen stats :1936
    mode http
    stats enable
    stats hide-version
    stats realm Haproxy\ Statistics
    stats uri /
    stats auth Username:Password

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        redispatch
        maxconn 2000
        contimeout      5000
        clitimeout      50000
        srvtimeout      50000

listen webfarm 127.0.0.1:80
       mode http
       balance roundrobin
       cookie JSESSIONID prefix
       option httpclose
       option forwardfor
       option httpchk HEAD /check.txt HTTP/1.0
       server server1 10.24.21.122:80 cookie A weight 1 check
       server server2 10.24.21.123:80 cookie B weight 5 check

U global sekciji postavljamo parametre koji će kao što pretpostavljamo i sami biti globalni, odnosno zahvaćat će proces cijelog balansiranja prometa. Kao i kod NGINX konfiguracije i ovdje možemo definirati korisnika i grupu kojoj korisnik pripada pod kojima će se pokretati HaProxy. Sa maxconn parametrom omogućavamo proxy-u da ograniči broj simultanih konekcija u sustavu. Sa HaProxy-em također možemo vidjeti i neka izvješća o aktivnosti samog proxy-a, i o stanju servera na koje on preusmjerava zahtjeve. Ključna riječ kojom možemo omogućiti ovakve izvještaje jer su po defaultu isključeni je "stats", a u našem slučaju to web sučelje je dostupno na portu 1936. Vidimo da koristimo i "defaults" sekciju kojom "override-amo" defaultne vrijednosti sa novima. Vidimo da imamo i listen sekciju koja se sastoji od dva parametra. Prvi je ime instance, i ovo ime ćemo naći u LOG file-ovima, npr. kod nas za adresu 127.0.0.1 je ime instance "webfarm". Primjetimo da je HaProxy vezan za adresu 127.0.0.1, i za port 80. Vidimo da smo u toj sekciji definirali dva NGINX servera na koja ćemo slati dolazeće zahtjeve. Opcija weight definira koliko će se zahtjeva poslati tom serveru prije nego se zahtjevi počnu slati drugom. Taokđer možemo definirati i algoritam balansiranja prometa opcijom balanca, a popis možemo vidjeti ovdje http://wiki.joyent.com/wiki/display/jpc2/Load+Balancing+with+HAproxy#LoadBalancingwithHAproxy-RoundRobin.

Nakon što smo spremili konfiguracijski file, iduće što trebalo je pokrenuti i testirati naš high-avability sustav temeljena na NGINX serverima. U mom slučaju oni su bili smješteni na dvije virtualke, dok je na mom glavnom računalu bio instaliran HaProxy, ali također i NGINX koji se pokreće prilikom podizanja sustava. Ukoliko je NGINX pokrenut, i pokušamo pokrenuti i HaProxy dobit ćemo grešku, pa stoga moramo prvo ugasiti NGINX server i osloboditi port 80. To možemo učiniti naredbom:

sudo service nginx stop

Nakon toga možemo startat naš HaProxy server:

sudo service haproxy start

Kako bi testirali HaProxy odimo na adresu 127.0.0.1, i HaProxy bi trebao balansirati i usmjeravati probmet prema dva NGINX servera.

Dokumentacija HaProxy-a se može naći na sljedećem linku http://haproxy.1wt.eu/download/1.3/doc/haproxy-en.txt

DEMO možete pogledati ovdje: http://www.youtube.com/watch?v=0J3u9cHqONk&feature=youtu.be

Sigurnost (Security)

Što se tiče same sigurnosti NGINX-u ne nedostaje modula i sigurnosnih nadogranji kojima možemo povećati sigurnost nekom sustava kojeg NGINX poslužuje. Postoji dosta načina i modula koji nam mogu pomoći u tome, no mi ćemo se ovdje bazirati samo na neke od njih. Naglasit ću da svi moduli neće uvijek biti korisni za svaku situaciju, nego ćemo po svojim potrebama i situaciji u kojoj se nalazimo izabrati one koji ne nam najviše koristiti. Pogledajmo u nastavku jedan od najčešćih načina na koje vlasnici nekom sustava žele zaštiti sadržaj koji se prenosi putem njihovog sustava.

HttpSslModule modul

Kao što već znamo SSL je jedan od čestih načina zaštite podataka od neovlaštenog čitanja, i sličnih nezakonitih akcija. Sama konfiguracija SSL-a na NGINX-u je vrlo jednostavna. Kao što već i sami znamo da bi SSL radio moramo generirati ključeve i certifikate koji će biti potpisani od strane određenih tijela ("Certification Authority"). Također imamo opciju da u svrhu npr. testiranja sami potpišemo neki certifikat ("self-signed"), no u tom slučaju će nam web preglednik javljati određenu grešku, odnosno upozorenje da certifikat nije potpisan. Certifikat možemo generirati sa openssl toolkitom, npr. koristeći naredbu:

openssl req \
  -x509 -nodes -days 365 \
  -newkey rsa:1024 -keyout mycert.pem -out mycert.pem

Nakon što smo generirali sve potrebne certifikate i ključeve vrijeme je da "nadogradimo" naš NGINX config sa SSL podrškom. U konfiguracijski file servera kojeg želimo stavit na SSL dodamo sljedeće linije:

listen                  443;
ssl                     on;	 
ssl_certificate         /etc/nginx/conf.d/server.crt;
ssl_certificate_key     /etc/nginx/conf.d/server.key;

Ukoliko sada restartamo NGINX naredbom

sudo service nginx restart

i odemo na url našeg servera npr https://nasserver.com, i ukoliko sve radi vidjet ćemo upozorenje preglednika koje nam govori da certifikat na toj stranici kojoj pristupamo nije potpisan. Kako bi ovo izbjegli (kao što sam već spomenuo) certifikat nam mora "validirati" određeno cerfikikacijsko tijelo. Ukoliko odemo na url http://nasserver.com vidjet ćemo da nam se više ne pokazuje to upozorenje iz razloga što više nismo na HTTPS-u, nego na običnom HTTP-u. Ova situacija u nekim slučajevima može biti nezgodna ukoliko želimo da se baš sav promet odvija preko porta 443, odnosno preko SSL-a. Ukoliko želimo korisnike "natjerati" da budu na HTTPS-u u NGINX konfiguracijski file možemo dodati sljedeće:

server {
       listen 80; 
       server_name _;
       return       301 https://127.0.0.1$request_uri;
}

Kod ovog servera "slušamo" na portu 80, te sve requestove usmjeravamo na HTTPS, odnosno na SSL i port 443. Da bude malo jasnije, kada korisnik pokuša pristupiti stranici na port 80, NGINX će zaključiti da korisnika treba prebaciti na neki drugi link, i onda će potražiti u konfiguracijskom file-u server koji se slaže sa linkom na koji se korisnik prebacuje i naći će server koji je na portu 443, a ujedno i na SSL-u.

Dokumentaciju modula možemo pronaći na ovom linku: http://wiki.nginx.org/HttpSslModule

HttpLimitReqModule modul

Svi smo vjerovatno čuli za "denial of service" tzv. DOS napade. Postavlja se pitanje kako se boriti protiv tih napada. Ukoliko budemo pažljivi pri programiranju i ne pravimo neke sigurnosne propuste, i za aplikaciju možemo reći da je odlična sa aspekta sigurnosti, naša web aplikacija unatoč tome može biti nedostupna zbog eventualnog "zagušenja" samog servera na kojem je hostana, te samim time sav trud oko programiranja u ovom slučaju pada u vodu. Da bi izbjegli ovakve slučajeve gdje zlonamjerne osobe velikim brojem zahtjeva koje šalju serveru nastoje onemogućiti ili otežati pristup našoj stranici, i samom radu na njoj možemo iskoristiti NGINX HttpLimitReqModule modul. Sama konfiruacija modula je vrlo jednostavna. Sve što trebamo napraviti je dodati u konfiguracijski file sljedeće linije koda:

limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;

...


location / {
...
            limit_req   zone=one  burst=5;
}

Pojasnimo malo što se ovdje točno događa i kakav će biti krajnji rezultat modifikacije našeg konfiguracijskog file-a. Ovdje smo za neku zonu ograničili broj zahtjeva koji dolaze od nekog klijenta na jedan po sekundi. Zatim smo za neku lokaciju koja je pokrivena određenim regex-om definirali da ukoliko broj requestova koji čekaju pređe 5 za zonu sa imenom "one", server će vratiti kod 503 "Service Temporarily Unavailable". Primjetimo da smo ovime otežali napadaču da nam učini sustav nedostupnim. Ovakav pristup bi po meni bilo odlično integrirati sa već spomenutim HeartBeatom te u slučaju da imamo npr. neki veliki DDOS napad i ukoliko da napadač ipak uspije na neki način srušiti server i učiniti ga nedostupnim, HeartBeat može "podići" pomoćni server, i dok ne osposobimo server koji je pao, sustav može nastaviti raditi.

Dokumentaciju modula možemo pronaći na ovom linku: http://wiki.nginx.org/HttpLimitReqModule

Postoji još jedan modul sličan ovome koji ima sličnu funkcionalnost a zove se HttpLimitZoneModule, pa pogledajmo o čemu se radi.

HttpLimitZoneModule modul

Za razliku modula HttpLimitReqModule koji ograničava broj zahtjeva po sekundi, ovaj modul ograničava broj simultanih konekcija za neku zonu. Ovo nam također može biti korisno ukoliko želimo spiječiti "zagušenje" samog web servera. Sada konfiguracija ovog modula je jako slična prošloj i izgleda otprilike ovako:

http {
  limit_zone   one  $binary_remote_addr  10m;
 
  server {
    location /download/ {
      limit_conn   one  1;
    }
  }
}

Ovime smo broj simultanih konekcija za klijenta sa određenom IP adresom ograničili na 1.

Dokumentaciju modula možemo pronaći na ovom linku: http://wiki.nginx.org/HttpLimitZoneModule

Prošla dva modula mogu biti još učinkovitija ukoliko se kombiniraju sa npr. politikom kontrole pristupa serveru kojom možemo određene (npr. nama sumljive IP adrese) klijente odbiti, odnosno onemogućiti im pristup serveru. Pogledajmo kako možemo to realizirati.

HttpAccessModule modul

Ovim modulom možemo specificirati kojim klijentima na osnovu IP adrese ili domene želimo omogućiti pristup serveru, ili pak isti odbiti. Da nam bude malo jasnije o čemu se radi pogledajmo sljedeći isječak konfiguracijskog file-a:

location / {
  deny    192.168.1.1;
  allow   192.168.1.0/24;
  allow   10.1.1.0/16;
  deny    all;
}

Ovime smo omogućili pristum klijentima koji dolaze iz mreža 192.168.1.0/24 i 10.1.1.0/16, s tim da smo adresi 192.168.1.1 onemogućili pristup. Svim ostalim klijentima van ove dvije mreže pristup je zabranjen. Primjetimo da se pravila evaluiraju odozgo prema dole. Kako bi ilustrirali bitnost redosljeda pravila pogledajmo sljedeći primjer:

location / {
  deny all;
  deny    192.168.1.1;
  allow   192.168.1.0/24;
  allow   10.1.1.0/1
}

U ovom slučaju će prvo pravilo, odnosno deny all; odbiti sve klijente, te ostala pravila neće biti ni provjeravana. Ovo treba imati na umu jer nas u pojedinim slučajevima može dovesti do problema.

Ovo također može biti korišteno u paru sa error_page direktivnom, jer ukoliko nam je pristup odbijem server nam vraća 403 kod, a to možemo iskoristiti npr. da napravimo poseban html na koji čemo redirectati sve klijente i dati im doznanja (ukoliko to želimo) da im je pristup zabranjen, ili taj html može biti i nekog drugog sadržaja, sve zavisi od naše situacije.

error_page  403  http://example.com/forbidden.html;

Dokumentaciju modula možemo pronaći na ovom linku: http://wiki.nginx.org/HttpAccessModule

HttpAuthBasicModule modul

Korištenjem ovog modula možemo zaštititi određene datoteke ili foldere pomoću "HTTP Basic Authentication", odnosno prijava korištenjem korisničkog imena i lozinke. Naglasit ću da ovaj način zaštite određenih dijelova sustava baš i nije najsigurniji, posebno ukoliko ne koristimo SSL. Naime korisničko ime i lozinka u slučaju da ne koristimo SSL se šalje serveru u obliku "plain text" datoteke, te nam svatko može uskrasti podatke za prijavu. No u nekim slučajevima kada ne postoji opasnost od toga, možemo koristiti i ovu metodu. Prvo što trebamo je kreirati datoteku koja će sadržavati korisnička imena i lozinke. Možemo ju kreirati npr. naredbom:

sudo htpasswd -c .htpasswd ivan

Nakon ovoga sve što trebamo je odabrati neki folder koji želimo zaštititi, i u konfiguracijski file dodati sljedeće:

location /admin {
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;
}

Znači ovime smo zaštitili folder admin i sav njegov sadržaj. Sve što smo trebali je navesti putanju do datoteke koja sadrži korisnička imena i lozinke osoba koje smiju pristupiti ovom dijelu sustava.

Dokumentaciju modula možemo pronaći na ovom linku: http://wiki.nginx.org/HttpAuthBasicModule

Tips & tricks

U ovom dijelu ćemo spomenuti neke preporuke (dobra praksa) koje se tiču povećanja sigurnosti servera, a i sustava na kojem se server nalazi.

Koristiti SE Linux

Security-Enhanced Linux je jedan od značajki Linux kernela koja nam omogućava da pravimo svoju politiku pritupa pojedinim resursima samog sustava. Samim tim ovo može pomoći u sprečavanju različitih napada. Npr. mailovima nekog korisnika mogu pristupiti samo on i mail program koji koristi. No što sprečava mail program da šalje te iste mail-ove na neke druge lokacije, i tako ugrožava samu privatnost korisnika. Tu SELinux uskače u pomoć tako da definiramo politike kojima definiramo tko gdje smije pristupiti, i tko šta smije raditi na sustavu. Po defaultu SELinux neće štititi NGINX server, no postoji rješenje. Za sve zainteresirane imam sljedeći link: http://sourceforge.net/projects/selinuxnginx/.

Izolirana okruženja

Izolirana okruženja (Isolated Environment, Chroot Environment) je jedna od značajka UNIX sustava preko koje možemo unaprijediti sigurnost samog sustava. O čemu se ovdje zapravo radi? Uzmimo za primjer NGINX server. Kako bi pokrenuli NGINX u jednom takvom okruženju moramo prvo kreirati strukturu direktorija koje zahtjeva NGINX. Zatim moramo tim okruženju dati neke sistemske resurse koje zahtjeva server da bi mogao normalno raditi. Nakon svih potrebnih modifikacija koje smo napravili na našem okruženju možemo pokrenuti i NGINX server. Što smo time dobili? Pa unaprijedili smo sigurnost samog sustava, jer će se NGINX izvršavati u svom "malom dijelu svemira", odnosno našeg UNIX sustava, te u slučaju mogućih upada u sustav od strane neželjenih osoba putem web servera otežat ćemo im daljnji posao npr. narušavanja dostupnosti servera, otkrivanja lozinki i slično. Također super kod ovakvih okruženja je i to da se više ne moramo brinuti oko kompaktibilnosti pojedinih verzija programa. Znači sada možemo imati istovremeno više verzija istog programa pod uvijetom da se oni nalaze u odvojenim okruženjima, što često zna biti cool stvar.

Kod NGINX-a bi trebalo ovakvu nekakvu strukturu direktorija kreirati:

D=/nginx
mkdir -p $D
mkdir -p $D/etc
mkdir -p $D/dev
mkdir -p $D/var
mkdir -p $D/usr
mkdir -p $D/usr/local/nginx
mkdir -p $D/tmp
chmod 1777 $D/tmp
mkdir -p $D/var/tmp
chmod 1777 $D/var/tmp
mkdir -p $D/lib64

Nakon toga bi trebali uključiti neke sistemske resurse koje zahtjeva NGINX i samo okruženje za normalan rad. Detaljne upute o ovome mogu se naći na sljedećoj stranici: http://www.cyberciti.biz/faq/howto-run-nginx-in-a-chroot-jail/

Na sljedećoj stranici se može pogledati i o samoj chroot naredbi http://linux.about.com/library/cmd/blcmdl2_chroot.htm/

Također na ovom linku se može naći koristan članak o tome kako ovakvo jedno okruženje postaviti na CentOS-u http://geek.co.il/wp/2010/03/14/how-to-build-a-chroot-jail-environment-for-centos

Isključiti sve nekorištene NGINX modula

Prilikom kompajliranja NGINX-a da bi se dodatno povećala sigurnost potrebno je isključiti sve module koji se ne koriste. To možemo učiniti sljedećom komandom:

./configure --without-http_autoindex_module --without-http_ssi_module
Kontrolirati dostupne informacije o serveru

Ukoliko koristimo verziju NGINX-a za koju se u određenom vremenu otkriju određene ranjivosti, u svakom slučaju dobro bi bilo "natjerati" NGINX da ne govori o svojoj verziji. To možemo na sljedeći jednostavan način napraviti:

server_tokens off;

Također još jedan koristan modul kojim možemo kontrolirati Headere NGINX-a je modul HttpHeadersMoreModule. Ovim modulom možemo postaviti, ili izbrisati headere koji vraća NGINX server.

more_set_headers 'Server: my-server';

Više o tom modulu možete pronaći ovdje: http://wiki.nginx.org/NginxHttpHeadersMoreModule

Onemogućiti "Buffer Overflow" napade

Kako bi spiječili ovu ranjivost moramo ograničiti veličinu podataka koje primamo od klijenata. Primjer:

  client_body_buffer_size  1K;
  client_header_buffer_size 1k;
  client_max_body_size 1k;
  large_client_header_buffers 2 1k;

Npr. u ovom slučaju ako je veličina tijela zahtjeva (eng. body size) veća od definirane, klijent će dobiti pogrešku sa porukom "Request Entity Too Large" (413).

Ograničavanje dostupnih metoda (GET, POST...)

Ukoliko server ne zahtjeva korištenje svih dostupnih HTTP metoda, onda bi bilo dobro da sve one koje ne koristi odbijamo. Npr. ovime možemo ograničiti NGINX da koristi samo GET, POST i HEAD metode.

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
       return 444;
}
Blokiranje tzv. Referral Spam-a

Ovdje možemo pročitati o čemu se radi http://en.wikipedia.org/wiki/Referer_spam, a tu je i primjer NGINX konfiguracije kako se možemo braniti od takve vrste spama.

if ($http_referer ~* (babes|click|diamond|forsale|girl|jewelry|love|nudit|organic|poker|porn|poweroversoftware|sex|teen|video|webcam|zippo)) {
  return 403;   
}
Spriječavanje Hotlinking-a

Hotlinking je zapravo mogućnost da neki korisnik uzme URL od npr. neke naše slike te ga prikazuje u svojoj stranici. Loša strana ovoga je što nam nepotrebno opterećuje server, jer kada se nekom korisniku bude učitavala ta slika iako se stranica nalazi na drugom serveru za tu sliku će se kontaktirati naš server. Ovome možemo stati na kraj na sljedeći način:

location /images/ {
  valid_referers none blocked www.example.com example.com;
   if ($invalid_referer) {
     return   403;
   }
}

3rdPartyModules

U ovom dijelu ćemo spomenuti kako instalirati i neke module koji nisu službeno podržani, no postoje i vrlo vjerovatno većina njih će raditi sasvim korektno nakon instaliranja na sustav. Kod NGINX-a da bi koristili neki modul koji nije kompajliran po defaultu moramo ponoviti proces kompajliranja prilikom čega moramo naglasiti da želimo da nam se uključi i željeni modul. Npr. ukoliko želimo instalirati neka dva modula, i skinuli smo njihov source, to možemo učiniti sljedećom komandom (pod pretpostavkom da imamo source od NGINX-a)

./configure --add-module=/path/to/module1/source \
            --add-module=/path/to/module2/source

Nakon ovoga proces instalacije nastavlja se standardnim putem. Ukoliko smo NGINX instalirali preko "package-manager-a" morat ćemo nažalost skinuti source i ručno kompajlirati i instalirati NGINX server.

Ukoliko imamo želju razviti neki svoj vlastiti modul za NGINX pomoć oko toga možemo potražiti na sljedećim linkovima: https://github.com/simpl/ngx_devel_kit i http://www.evanmiller.org/nginx-modules-guide.html.

Listu dostupnih dodatnih modula možemo pronaći na sljedećem linku: http://wiki.nginx.org/3rdPartyModules. Na ovom popisu može se pronaći dosta zanimljivih modula koji mogu dodatno povećati sigurnost i raspoloživost NGINX servera. Jedan od takvih koje bi volio istaknuti je i "Naxsi" odnosno Web Application Firewall za NGINX. No na toj listi se mogu naći i moduli za mnoge druge namjene.

Konfiguracijski file-ovi

Konfiguracijski file-ovi se mogu naći u sljedećem gitHub repozitoriju:

https://github.com/ivpusic/SIS_configs


--Ivan 14:47, 20. siječnja 2013. (CET)

Lighttpd

lighttpd logo

Lighttpd je siguran, brz i vrlo fleksibilan web server koji je optimiziran za okruženja gdje su potrebne visoke performanse. Upravo s niskim memorijskim tragom, kada se usporedi s ostalim web serverima, te efektivnim upravljanjem opterećenjem CPU-a, kao i skupom naprednih svojstava (FastCGI, SCGI, Auth i drugi..) lighttpd je idealno rješenje za svaki server. Ono što je najbolje, jest to da je Open Source, licenciran pod revidiranom BSD licencom.

Lighttpd pokreće nekoliko popularnih Web 2.0 stranica, poput Youtubea, Wikipedije i meebo-a. Njegova vrlo brza io-infrastruktura mu dopušta da radi brže na istom hardveru nego alternativni web-serveri. Njegova event-driven(http://en.wikipedia.org/wiki/Event-driven_architecture) arhitektira je optimizirana za veliki broj paralelnih konekcija, što je vrlo važno za AJAX aplikacije s visokim performansama.


Instalacija

Lighttpd server se vrlo lako instalira pomoću naredbe:

sudo apt-get install lighttpd

Ukoliko se koristi apt-get package manager, za ostale, pogledajte upute na sljedećem linku: http://redmine.lighttpd.net/projects/lighttpd/wiki/GetLighttpd

Pokretanje lighttpd-a se radi pomoću:

sudo service lighttpd start

Konfiguracijske datoteke se za lighttpd nalaze u:

/etc/lighttpd/

Dobra praksa pisanja konfiguracijskih datoteka, kada uključujemo pojedine module, jest korištenje naredbe

lighty-enable-mod

Tada možemo odabrati koji modul želimo uključiti. Primjerice, ja sam odabrao modul ssl za uključiti.

mario@mario-laptop ~ $ sudo lighty-enable-mod 
[sudo] password for mario: 
Available modules: auth accesslog cgi evasive evhost expire fastcgi flv-streaming no-www proxy rrdtool simple-vhost 
ssi ssl status userdir usertrack fastcgi-php debian-doc 
Already enabled modules: 

Enable module: ssl
Enabling ssl: ok
Run /etc/init.d/lighttpd force-reload to enable changes

Kao što se vidi na primjeru, da su neki moduli prije uključeni, ispisali bi nam se pod Already enabled modules.

Nakon toga nam se u

/etc/lighttpd/conf-enabled

nalazi dio konfiguracije za modul ssl, koji izgleda ovako:

# /usr/share/doc/lighttpd-doc/ssl.txt

$SERVER["socket"] == "0.0.0.0:443" {
        ssl.engine  = "enable"
        ssl.pemfile = "/etc/lighttpd/server.pem"
}

Tako možemo svaki modul uključiti opcije koje su bitne za taj modul će se nalaziti u odvojenoj konfiguracijskoj datoteci.

No, za potrebe testiranja ovog projekta, ja sam sve opcije pisao u jednu datoteku, glavnu konfiguracijsku datoteku lighttpd servera, lighttpd.conf.


Konfiguracija

U početku ću opisat sintaksu konfiguracijske datoteke koju sam koristio prilikom konfiguriranja servera. Najćešće korišten način definiranja neke opcije je sljedeći:

naziv_opcije = vrijednost

Ukoliko je vrijednost brojčana, pišemo je bez navodnika, a ukoliko je vrijednost string ili neka putanja, moramo je upisati s navodnicima.

Također, koristio sam i vrijednosti pomoću kojih želim obuhvatiti neku IP adresu, url i slično. U nastavku ću objasniti značenja pojedinih vrijednosti.

To je zapravo to što se osnovne sintakse tiče.

Sada ću u nekoliko koraka objasniti što bi svaka početna konfiguracijska datoteka trebala imati. Svakako, to su root direktorij, IP adresa te port na kojem će server osluškivati.

server.document-root       	= "/var/www"
server.bind			= "127.0.0.1"
server.port 			= 80

Isto tako, možemo dodati i vrste datoteka koje će se moći otvoriti na serveru pomoću:

mimetype.assign = (
	".html" => "text/html",
	".htm" => "text/html",
	".txt" => "text/plain",
	".css" => "text/css",
	".js" => "text/javascript",
	".xml" => "text/xml",
	".php" => "application/x-httpd-php",
	".jpg" => "image/jpeg",
	".png" => "image/png"
)

Sljedeće što možemo definirati jesu nazivi indeksnih datoteka i to pomoću:

index-file.names            	= ( "index.php", "index.html", "index.htm")

Trebali bi definirati i lokacije gdje će se spremati logovi za greške i pristup. To možemo učiniti pomoću:

server.errorlog             	= "/var/log/lighttpd/error.log"
accesslog.filename		= "/var/log/lighttpd/access.log"

Također, potrebno je učitati module koji na neki način grupiraju povezane opcije. Moduli se učitavaju pomoću:

server.modules = (
	"mod_access",
	"mod_accesslog",
	"mod_alias",
	"mod_compress",
 	"mod_redirect",
	"mod_proxy"
)

Detalji o modulima se mogu pronaći na sljedećoj lokaciji: http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs No, više o tome u nastavku kada ću pojasniti učitavanje modula koji nam mogu pomoći u povećanju sigurnosti te visokoj raspoloživosti servera.


Raspoloživost

Što se raspoloživosti tiče, ona je jedna od najbitnijih komponenata kada procjenjujemo da li je neki sustav dobar za korisnike. Testiranje bitnih svojstava servera sam radio na način da sam instalirao dvije virtualne mašine, na svakoj od njih sam instalirao Lubuntu te upogonio lighttpd.


mod_proxy

Modul mod_proxy nam daje mogućnost korištenja tri opcije prilikom konfiguriranja servera. Upravo taj modul sam iskoristio da bih prikazao load-balancing između više servera.

"round-robin" bira drugi host za svaki zahtjev; "hash" generira hash od request-uria i brine se da isti URI zahtjeva bude uvijek poslan istom hostu; "fair" je normalno, pasivno balansiranje, ovisno o opterećenju sustava

U konfiguracijskoj datoteci sam upisao sljedeće postavke:

$HTTP["host"] == "localhost"{
	proxy.balance = "round-robin"
	proxy.server = ("" => 
				( ( "host" => "192.168.1.135" ),
				  ( "host" => "192.168.1.137" ) )
			 )
}

Dakle, sve što ide na host localhost se balansira pomoću "round-robin" načina, što znači da će svaki zahtjev ići na drugi host. Definirao sam dva hosta na koja se može balansirati promet, a to su upravo dvije virtualne mašine koje sam instalirao. Više o modulu mod_proxy se može pronaći na http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModProxy

Nadalje, što se raspoloživosti tiče želio bih spomenuti opciju kojom možemo ograničiti količinu podataka po sekundi za sve otvorene veze, pomoću opcije server.kbytes-per-second. To se može napraviti na sljedeći način:

server.kbytes-per-second	= 1024

Isto tako, moguće je ograničiti količinu prometa i po pojedinoj konekciji, što je objašnjeno nešto kasnije, u odjeljku o sigurnosti.

Video koji prikazuje funkcioniranje load-balancinga kod korištenja lighttpd servera možete pogledati na sljedećem linku: http://screencast-o-matic.com/watch/cIVqIyVQB3


alat Monit

Nebrojeno mnogo puta se zna desiti da ne možemo osobno nadzirati dostupnost servera cijelo vrijeme. Korištenjem nekog alata koji automatski nadgleda status servera, ukoliko dođe do nekog ispada u kojem sustav radi, taj alat će automatski uključiti server. Naravno, ukoliko se dogodi ispad u kojem sustav ne radi, recimo prekid dovoda struje, tada nam ova metoda ne pomaže već imamo koristi od balansiranja, opisanog u prethodnom odjeljku.

Ovaj alat nije vezan striktno uz server lighttpd, već može poslužiti da pokrene bilo koji servis koji je isključen. Instaliranje alata se radi pomoću naredbe:

sudo apt-get install monit

ukoliko koristimo apt-get package manager. Nakon što je instalacija gotova, potrebno je konfigurirati navedeni alat. Konfiguracijska datoteka se nalazi u:

/etc/monit/monitrc

Prva stvar koju je u konfiguracijskoj datoteci moguće promijeniti je broj sekundi nakon kojih će alat provjeravati da li su definirani servisi pokrenuti ili ne. Naredba koja definira taj broj sekundi jest:

set daemon 120

Dakle, ovdje je postavljeno da se svakih 120 sekundi (2 minute) provjerava da li su definirani servisi pokrenuti. Nakon toga možemo promijeniti lokaciju datoteke u koju će se zapisivati logovi. Po defaultu je to:

set logfile /var/log/monit.log

Nakon toga sam definirao dio koji će provjeravati da li je uključen lighttpd server, i ako nije, uključit će ga.

check process lighttpd with pidfile /var/run/lighttpd.pid
group lighttpd
start program = "/etc/init.d/lighttpd start"
stop program = "/etc/init.d/lighttpd stop"
if failed host 127.0.0.1 port 80
protocol http then restart
if 5 restarts within 5 cycles then timeout

Nakon toga je potrebno pokrenuti monit servis pomoću:

sudo /etc/init.d/monit start

Sada će monit svakih 120 sekundi provjeravati da li lighttpd radi, i ukoliko ne radi, pokušati ga ponovno pokrenuti.

Detaljnije o alatu se može naći na: http://mmonit.com/monit/


Sigurnost

SSL

Za korištenje SSL zaštite ne moramo uključivati niti jedan modul, već se on nalazi u osnovnom (core) modulu. Sama konfiguracija SSL-a je vrlo jednostavna. No, prije konfiguriranja, potrebno je generirati "self-signed" SSL certifikate. Naravno, korištenje takvih certifikata je korisno samo kada ih koristimo u svrhu testiranja. Inače nam certifikat mora potpisati CA (Certification Authority). Certifikat možemo kreirati pomoću sljedeće naredbe:

openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes

Naravno, prije toga se potrebno pozicionirati u onaj direktorij gdje ćemo certifikat pospremiti. Nakon generiranja certifikata, potrebno je uključiti SSL u konfiguracijskoj datoteci lighttpd-a.

$SERVER["socket"] == "127.0.0.1:443"{
	ssl.engine = "enable"
	ssl.pemfile = "/etc/lighttpd/ssl/lighttpd/server.pem"
}

Dakle, ukoliko smo na IP adresi 127.0.0.1 te na portu 443, uključiti ćemo SSL pomoću ssl.engine. Pomoću ssl.pemfile se upisuje lokacija certifikata koji smo ranije generirali. Potrebno je ponovno pokrenuti lighttpd kako bi upisane promjene u konfiguracijskoj datoteci bile uključene. Lighttpd možemo ponovno pokrenuti pomoću:

sudo service lighttpd restart

Sada, ukoliko odemo na https://localhost, preglednik će nam izbaciti upozorenje u kojem piše da certifikat na stranici kojoj pristupamo nije potpisan. Kako bi se ovo izbjeglo, potrebno je da nam certifikat potpiše CA. Ukoliko bi imali potpisan certifikat, potrebno bi bilo dodati i sljedeću liniju u konfiguracijsku datoteku:

ssl.ca-file = "/etc/lighttpd/ssl/lighttpd/CA_issuing.crt"

gdje ssl.ca-file predstavlja lokaciju do datoteke u kojoj se nalaze informacije da je naš certifikat potpisan.

Ono što možemo učiniti da bi se uvijek koristio https jest običan url.redirect (iz modula mod_redirect) pomoću sljedećeg odječka konfiguracijske datoteke:

$HTTP["scheme"] == "http" {
	$HTTP["host"] =~ ".*" {
		url.redirect = (".*" => "https://%0$0")
	}
}

gdje je $HTTP["scheme"] uvijek ili http ili https. U sljedećem koraku koristimo regex pravilo gdje host može biti bilo kakav, i njega preusmjeravamo na https. %0 označava zapravo naziv hosta. Dakle, pomoću ovoga ćemo svaki zahtjev koji će ići na http preusmjeriti na https.

Video koji prikazuje funkcioniranje SSL-a kod lighttpd servera možete pogledati na sljedećem linku: http://screencast-o-matic.com/watch/cIVqINVQBu


mod_evasive

Pomoću modula mod_evasive možemo ograničiti maksimalan broj konekcija s jedne IP adrese. To nam je korisno kada se donekle želimo osigurati od DoS(Denial of Service) napada. Korištenje navedenog modula nije teško. Potrebno je samo iskoristiti opciju evasive.max-conns-per-ip. Primjer je dan u nastavku.

evasive.max-conns-per-ip	= 1

Također, moguće je ograničiti maksimalan broj veza na sljedeći način:

evasive.max-conns-per-ip = 1

$HTTP["host"] == "example.com" {
	evasive.max-conns-per-ip = 2
}
$HTTP["host"] == "example2.com" {
	evasive.max-conns-per-ip = 0
}

gdje će defaultne stranice imati maksimalno jednu vezu, example.com će imati dvije, a example2.com će ih imati neograničeno. Primjetimo dakle, da 0 označava neograničeno. Također, moguće je uključiti opciju silent, tako da se ne bilježe blokirane IP-adrese.

evasive.silent			= "enabled"

Također, ovdje bih želio spomenuti i jednu opciju koja nije vezana uz ovaj modul, a predstavlja ograničavanje prometa po sekundi za jednu vezu. To je opcija connection.kbytes-per-second koja se postavlja na sljedeći način:

connection.kbytes-per-second	= 64

Dakle, ovdje smo ograničili količinu prometa po sekundi na 64 kB za jednu vezu.


mod_access

Pomoću modula mod_access možemo zabraniti pristup određenim datotekama. Najjednostavniji način za to jest pomoću url.access-deny. Primjer:

url.access-deny             = ( "~", ".inc" )

Dakle, u ovom slučaju se neće moći otvoriti datoteke koje završavaju s tildom (~) ili .inc zato što editori teksta često ostavljaju datoteke koje završavaju s "~" kao backup datoteke, a ".inc" ekstenzija se koristi za uključivanje datoteka s programskim kodom, što bi se moglo zloupotrijebiti. Također, ovo možemo iskoristiti i da praktički zabranimo pristup cjelom direktoriju, na sljedeći način:

$HTTP["url"] =~ "^/lighttpd" {
	url.access-deny	= ("")
}

Svaki url koji će završavati sa /lighttpd će biti zapravo blokiran. Listu datoteka smo ostavili praznu, i to znači da će blokirati sve vrste datoteka. Pojavit će se greška 404.

Ovom prilikom bih spomenuo i jednu opciju kojom možemo definirati lokaciju vlastite datoteke koja će se prikazati u slučaju greške 404. To radimo na sljedeći način:

server.error-handler-404	= "/error-handler.html"

Dakle, datoteka error-handler.html će se otvoriti umjesto defaultne 404 greške lighttpd servera.

Naravno, prije početka testiranja unesenih promjena, potrebno je ponovno pokrenuti lighttpd server.

Također, vezano uz korištenje modula mod_access, moguće je zabraniti nekoj određenoj IP adresi da pristupi serveru. Tako je moguće, primjerice IP adresi 127.0.0.1 zabraniti pristup preko sljedećeg dijela koda:

$HTTP["remoteip"] == "127.0.0.0/24" {
	url.access-deny = ( "" )
}

Također, moguće je upisivanje više IP adresa, što bi izgledalo ovako:

$HTTP["remoteip"] =~ "202.54.1.1|202.54.2.5" {
	url.access-deny = ( "" )
}

Primjetite korištenje "=~" umjesto "==", što znači da se koristi regex pravilo umjesto klasičnog operatora "==". Uz upisivanje više adresa, moguće je i korištenje CIDR notacije, što bi izgledalo na sljedeći način:

$HTTP["remoteip"] == "202.54.1.0/24" {
	url.access-deny = ( "" )
}


mod_auth

Modul mod_auth nam omogućava korištenje autentikacije. Modul kao takav ima dvije metode autentikacije:

Mogući načini za pohranu korisinčkih podataka, s obzirom na metode su:

Ja ću u nastavku pojasniti korištenje htpasswd_ načina spremanja korisničkih podataka i, s obzirom da je htpasswd_ podržan u basic metodi autentikacije, upravo tu metodu.

Prije samog konfiguriranja servera, potrebno je kreirati datoteku koja će sadržavati korisničke podatke te upisati podatke u nju. Pomoću sljedeće naredbe sam kreirao datoteku korisnici.txt te dodao u nju sadržaj za korisnika pod imenom mario. Napomenut ću da sam opciju "-c" koristio iz razloga što datoteka dosad nije postojala. Ukoliko datoteka postoji, naredba htpasswd bi se koristila bez te opcije, i ona bi u zadanu datoteku dodala novi zapis, za navedenog korisnika.

htpasswd -c korisnici.txt mario

Prikazat ću i kako izgleda uneseni zapis u datoteku. (Kao lozinku sam upisao lighttpd nakon upisivanja prethodne naredbe.)

mario:$apr1$fkH1tr9l$rco8DcP2XHdRH/UYtYt3f1

Sada, kada imamo spremnu datoteku s korisničkim podacima, potrebno je i dodati korištenje autentikacije u konfiguracijsku datoteku servera.

$HTTP["url"] =~ "^/admin/" {
	auth.backend			= "htpasswd"
	auth.backend.htpasswd.userfile = "/var/www/admin/korisnici.txt"
	auth.require = ( "/admin" => (
		"method" => "basic",
		"realm" => "Password protected area",
		"require" => "user=mario"
	) )
}

Pomoću auth.backend smo definirali način za pohranu korisničkih podataka, dok smo sa auth.backend.htpasswd.userfile definirali lokaciju na kojoj se nalazi ta datoteka. Nadalje, pomoću auth.require smo definirali u kojem ćemo direktoriju zahtijevati pristup pomoću lozinke. U ovom slučaju to je direktorij /admin. Nakon toga, definirali smo tri vrijednosti. Prva, method, je vrsta autentikacije, realm je poruka koja će se ispisati korisniku prije unosa korisničkih podataka, a pod require možemo definirati koji korisnik će moći ući u ovaj direktorij. Ukoliko pod require stavimo valid-user, direktoriju će moći pristupiti svi korisnici koji imaju svoje podatke u datoteci s podacima.

Video koji prikazuje funkcioniranje autorizacije korištenjem htpasswd kod servera lighttpd možete pronaći na sljedećem linku: http://screencast-o-matic.com/watch/cIVq2oVQBw


Tips & tricks

Izolirana okruženja

Korištenjem chroota možemo kreirati izolirano okruženje kojim se unaprijeđuje sigurnost samog sustava. Ono što se time zapravo radi, jest to da lighttpd-u damo određeni dio prostora na disku koji će biti izoliran i iz kojeg korisnici koji koriste web sustav neće moći izaći.

Također, ono što je odlična stvar vezana uz izolirana okruženja, jest to da praktički možemo imati instalirane različite verzije programa, primjerice php. Bitno je samo da je svaka verzija u zasebnom izoliranom okruženju.

U nastavku ću opisati postupak kako bi se takvo virtualno okruženje napravilo. Prvo je potrebno kreirati root direktorij okruženja. Nakon toga je potrebno kreirati i ostale direktorije u koje će se kopirati sistemski resursi koje server zahtjeva da bi normalno radio.

# mkdir /webroot 
# mkdir /webroot/tmp/ 
# chmod 1777 /webroot/tmp/ 
# mkdir /webroot/etc

Nakon kreiranih direktorija, potrebno je kopirati sistemske resurse koje lighttpd server koristiti.

# cp /etc/hosts /webroot/etc/ 
# cp /etc/nsswitch.conf /webroot/etc/ 
# cp /etc/resolv.conf /webroot/etc/ 
# cp /etc/services /webroot/etc/ 
# cp /etc/localtime /webroot/etc/

Nakon toga je potrebno kreirati i ostale direktorije koji su potrebni za rad servera, kao što su root direktorij za server, direktorij za bilježenje logova i ostali.

# mkdir -p /webroot/var/log/lighttpd 
# chown lighttpd:lighttpd /webroot/var/log/lighttpd 
# mkdir -p /webroot/var/tmp/lighttpd/cache/compress/ 
# chown lighttpd:lighttpd /webroot/var/tmp/lighttpd/cache/compress/ 
# mkdir -p /webroot/home/lighttpd 
# mkdir -p /webroot/var/www 
# chown lighttpd:lighttpd /webroot/home/lighttpd 
# chown lighttpd:lighttpd /webroot/var/www 
# chmod 0700 /webroot/home/lighttpd 
# ls -dl /webroot/home/lighttpd

Kada smo kreirali i ostale direktorije, potrebno je i umetnuti sadržaj unutra, kao što su html datoteke i ostalo.

Ono što posljednje moramo napraviti, je u glavnoj konfiguraciji lighttpd servera dodati liniju koja će odrediti gdje se nalazi root direktorij izoliranog okruženja. Ovo radimo pomoću:

server.chroot = "/webroot"

Jednom kada definiramo chroot, nitko osim root korisnika ne može pristupiti bilo čemu izvan /webroot direktorija. Nakon što smo sve ovo napravili, potrebno je ponovno pokrenuti lighttpd server i tada će funkcionirati novo postavljeno izoliranje okruženje.

Jedan odličan tutorijal o postavljanju chroota s PHP-om i MySQL-om možete pročitati na: http://www.cyberciti.biz/tips/howto-setup-lighttpd-php-mysql-chrooted-jail.html.


Konfiguracijske datoteke

Konfiguracijske datoteke za lighttpd server i alat monit se nalaze na sljedećem linku: https://github.com/maperokov/SIS_config


--Maperokov 13:08, 20. siječnja 2013. (CET)


Apache

apache logo

Apache web server je server koji je imao jako veliku ulogu u početnom rastu world wide web-a. Prije 3 godine na apache web serveru vrtilo se 100 milijuna web stranica i prvi je server s tom brojkom. Apache je zamišljen, a i napravljen, za "Unix-like" operativne sustave, odnosno ako želimo specificirati za Linux. No to ne znači da ga ja nemoguće instalirati i konfigurirati na Windowsima. Apache je razvijen od strane "open-source" zajednice pod budnim okom Apache software foundation-a. Iako danas možemo birati između mnoštva web servera(samo u ovom radu vidjeti ćete njih 4) i mnogi se slažu da danas postoje web serveri koji su bolji od apache-a(nginx op.a.), podatak da se 2012. godine na njemu vrtilo otprilike 55 % svih aktivnih web stranica govori da je apache i dalje najpopularniji web server na svijetu. Jedan od glavnih razloga uspjeha apache-a je taj što je "open source" te na taj način svatko može pisati module koji su mu potrebni.

Instalacija Apache-a

Apache se instalira jednostavnom naredbom u terminalu:

 
 apt-get install apache2 

Nakon što je instalacija završena apache server možemo vrlo lagano pokrenuti. Konfiguracijski fileovi se obično nalaze u /etc/apache2, a do tog direktorija dođemo naredbom u terminalu:

 
 cd /etc/apache2 

U tom direktoriju postoji nekoliko poddirektorija i fileova:

Apache pokrećemo jednostavnom naredbom:

 
 service apache2 start 

Isto tako sa sličnim naredbama apache možemo zaustaviti ili ponovno pokrenuti (restart):

 
 service apache2 stop
 service apache2 restart 
        

Sve promjene u terminalu koje su ovdje navedene naravno moramo napraviti kao root korisnik. Ukoliko ne želimo prije svake naredne pisati sudo napišemo na početku :

 
 sudo su 

Kada "uključimo" neki mod ili stranicu ili napravimo bilo kakvu drugu promjenu, apache je potrebno ponovno pokrenuti kako bi promjene bile vidljive.

Konfiguracija

 PidFile ${APACHE_PID_FILE}  

 Timeout 20

 KeepAlive On
 MaxKeepAliveRequests 100
 KeepAliveTimeout 5

 User ${APACHE_RUN_USER}
 Group ${APACHE_RUN_GROUP}

 <Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy all
 </Files>

 HostnameLookups Off
 
 ErrorLog ${APACHE_LOG_DIR}/error.log	
 LogLevel warn	

 SecResponseBodyMimeType text/plain text/html text/css

 Include mods-enabled/*.load
 Include mods-enabled/*.conf

 Include httpd.conf
 Include ports.conf
 Include conf.d/
 Include sites-enabled/


    

Sa PidFile odredimo putanju gdje ćemo spremati id procesa kada se on pokrene. Ovdje je postavljena varijabla APACHE_PID_FILE koja je definirana u envvar, kao uostalom i sve varijable okoline. Zatim je postavljeno maksimalno vrijeme (u sekundama) koje će apache čekati na kompletiranje uspostave konekcije. Dakle to možemo povezati sa gradivom Mreža računala i prisjetiti se three-way-handshakea. Klijent šalje serveru request za uspostavu konekcije, server zatim vraća odgovor klijentu. I sada klijent treba vratiti bit ACK serveru i to vrijeme koje će sever čekati tu potvrdu od klijenta je zapravo timeout. Ovdje možemo napomenuti i mali "security tip". Ukoliko timeout postavimo na neku nižu vrijednost time smo smanjili efekt mogućeg DOS napada. Zatim smo omogućili otvaranje perzistentne konekcije prema korisniku. Zašto je ovo dobro i zašto bi ovo uvijek trebali biti omogućeno ? Zato jer kada otvorimo perzistentnu konekciju prema određenom klijentu ne moramo otvarati novu konekciju svaki puta kada on pošalje neki request prema serveru. Kada bi ovo bilo postavljeno na OFF, klijent bi poslao neki request, npr. zahtjev za neku sliku, server bi mu odgovorio na request i zatvorio konekciju, a klijent kada bi sada ponovno poslao neki request, server bi trebao otvoriti novu konekciju i tako stalno. Naravno, to je puno veće opterećenje za server te je za efikasniji rad servera prijedlog da se perzistentna konekcija prema klijentima uvijek omogući. Zatim samo postaimo još neke postavke za tu perzistentnu konekciju (naravno pod uvijetom da smo je prethodno omogućili). Možemo odrediti koliko maksimalno requestova po jednoj perzistentoj konekciji omogućavamo i koliko se dugo čeka na novi request. Ukoliko u naznačenom vremenu ne stigne novi request perzistentna konekcija se gasi. Što se tiče maksimalnog broja requestova, što je veći broj to su performanse servera bolje. Ukoliko imamo stranicu bogatu slikama i sličnim sadržajem(npr. puno javascrip koda i sl.) možemo MaxKeepAliveRequests postaviti i na 500. Zatim definiramo "usera" i "group". Ovdje smo im dodijelili varijablu koja je postavljena zajedno sa svim ostalim varijablama okline u envar. Zatim onemogućimo klijente da vide .htaccess and .htpasswd fileove. Kada bismo HostnameLookups postavili na "ON", mogli bismo u log fileove zapisivati imena hostova. Po defaultu je ta opcija postavljena na "OFF" i moja preporuka bi bila da tako i ostane. Kada bismo to omogućili trošili bismo dosta mrežnog prometa. Ukoliko je pak bitno da spremamo imena hostova u log fileove to možemo napraviti i sa "logresolve". Više o tome možete pročitati na http://httpd.apache.org/docs/current/programs/logresolve.html. Sljedeće što navodimo je putanju do error.log filea. I ovdje smo proslijedili varijablu koja je postavljena u envvar, a po trentunim postavkama error.log file se nalazi u /var/log/apache2. Mi naravno možemo postaviti i neku drugu putanju, a to ćemo naznačiti u envvar. Ukoliko netko to želi može tu putanju postaviti i direktno u konfiguracijskom fileu. Ovdje još postavljamo i razinu poruka koje spremamo u error log, a ovdje je to postavljeno na warn što označava warning. Na sljedećem linku možete pogledati koje su još opcije ovdje moguće http://httpd.apache.org/docs/current/mod/core.html#loglevel. Zatim smo sa, SecResponseBodyMimeType, definirali koje sve ekstenzije će naš server prepoznati. Po "defaultu" prepoznava html i plain text, a mi smo još dodali i css. Na kraju konfiguracijskom filea još samo uključimo neke druge fileove koji su nam potrebni. Tako uključimo sve .conf i .load fileove sa iz mods-enabled te httpd.conf i ports.conf, kao i stranice koje su "uključene". Sve to je već opsiano prethodno, a ovdje ću samo još jednom napomenuti da je fileu ports.conf postavljeno koje portove "sluša" apache.

Kreiranje virtualnih hostova

Virtualni hostovi nam omogućavaju da "hostamo" više web stranica na jednom serveru. Na apacheu je to poprilično jednostavno za konfigurirati. Prvi korak je kreiranje direktorija u root folderu. Po defaultu root folder za apache je /var/www, te ukoliko ništa nije mijenjano ovdje bi trebalo napraviti novi direktorij. Novi direktorij možemo nazvati npr. ovako: www.primjer.com, a naredba kojom kreiramo novi direktorij je sljedeća:

 mkdir  -p /var/www/www.primjer.com

Sljedeći korak je dodjeljivanje prava pristupa novo kreiranom direktoriju. To radimo sa sljedećom naredbom:

 chown -R group:user /var/www/www.primjer.com

gdje umjesto groop pišemo ime grupe, a umjesto user ime "usera". Isto tako moramo još i omogućiti svima prava pristupa čitanja ovog direktorija, a to radimo naredbom:

 chmod 755 /var/www 

Sada možemo kreirati neku stranicu koja će se pokazati kada u naš preglednik upišemo www.primjer.com. Tu stranicu možemo nazvati index.html, a mora biti smještena u direktoriju kojeg smo na početku kreirali(www.primjer.com). Ta stranica za ovaj konkretni slučaj ne mora biti ništa posebno već čisto da pokažemo da smo uspješno konfigurirali virtualni host. Nakon što upišemo naredbu

 nano /var/www/www.primjer.com/index.html

kreirali smo novi html dokument. U njega možemo upisati jednostavno:

		
<html>
   <body>
      <h1>Virtual host je uspješno postavljen!</h1>
   </body>
</html>	

I sada, kada ćemo u web preglednik upisati www.primjer.com, ukoliko smo sve dobro konfigurirali, ispisati će se tekst "Virtual host je uspješno postavljen!".

Kada smo sve prethodne korake završili, možemo ići konfigurirati novi virtualni host. Nakon što smo instalirali apache, sa njim smo dobili "defaultne" predloške za konfiguriranje servera koje sada možemo iskoristiti. U folderu /etc/apache2/sites-available se nalazi virtual host koji se zove default. Možemo kopirati taj konfiguacijski file i iskoristiti ga za konfiguriranje našeg virtual hosta. Upišemo sljedeću naredbu:

 
 cp /etc/apache2/sites-available/default /etc/apache2/sites-available/www.primjer.com 

Sa naredbom

 
 nano www.primjer.com

otvaramo konfiguracijski file našeg novog virtualnog hosta. Pošto smo jednostavno bili kopirali postojeći konfiguracijski file, nemamo puno posla.

 <VirtualHost 127.0.2.2:80>
    ServerAdmin webmaster@localhosto" 
    ServerName www.primjer.com
	
    DocumentRoot /var/www/www.primjer.com

    <Directory />
    Options FollowSymLinks
    AllowOverride None
    </Directory>

    <Directory /var/www/www.primjer.com>
	.
	.
	.
 </VirtualHost>

Gore su navedene sve promjene koje moramo napraviti u našem konfiguracijskom fileu kako bi naš virtual host ispravno radio. Odredili smo da će ovaj virtual host raditi na ip adresi 127.0.2.2. i na portu 80. Morali smo promijeniti ServerName i dodati ime našeg novog servera(Virtual hosta), te smo morali promijeniti DocumentRoot i putanju za Directory. Virtual host koji smo kreirali raditi će na portu 80. Ukoliko bismo željeli napraviti ssl virtual host, onda bismo u koraku gdje smo kopirali konfiguracijski file kopirali file defaul-ssl i napravili iste promjene kao i ovdje. Jedino na što bi trebali paziti je da u novokreiranom konfiguracijskom fileu stavimo port 443.

Još nam je jedan korak ostao prije nego možemo isprobati naš virtual host. Moramo otići u file hosts, koji se nalazi u direktoriju /etc i tamo još naznačiti ime našeg virtual hosta sa ip adresom koju smo mu dodijelil. Tamo se već nalazi localhost postavljen na ip adresu 127.0.0.1, a mi sada dodajemo naš kreirani virtual host:

   .
   .
 127.0.0.1       localhost
 127.0.2.2       www.primjer.com
   .
   .

Sada smo u potpunosti završili sa konfiguriranjem našeg novog virtual hosta. Jedino što još moramo je postaviti virtual host na enabled. To radimo sa sljedećemo naredbom:

 
 a2ensite www.primjer.com 

Ovime smo naš virtual host stavili u direktorij sites-enabled i sada ga možemo isprobati. Prije treba naravno restartirati server sa

 service apache2 restart 

te nakon toga u web preglednik možemo upisati www.primjer.com i trebao bi se pojaviti ispis: "Virtual host je uspješno postavljen!" Više o konfiguriranju virtual hostova na apacheu možete pročitati na: http://httpd.apache.org/docs/2.2/vhosts/


Availability

Load balancer

Zamislimo da imamo neki servis koji radi na više servera(npr. Facebook). Kako bi što lakše objasnili uzeti ćemo da imamo 2 servera. Kada jedan od tih servera prestane raditi, taj servis i dalje treba nastaviti raditi na ovom drugom serveru koji i dalje radi. Nadalje, dok rade oba dva servera, requestovi pristuži i na jedan i na drugi server. Na taj način rasteretimo servere. Upravo ovo postižemo load balancerom. Sada ćemo pokazati kako to konfigurirati.

Na početku trebamo postaviti proxy mod na enabled. To radimo sa sljedećom naredbom.

 
 a2enmod proxy

Sada u glavni konfiguracijski file od apachea stavimo sljedeće:

 <Proxy balancer://www.primjer.com>
    BalancerMember http://10.24.21.202:80
    BalancerMember http://10.24.21.203:80
 </Proxy>
		
 <Location />
    ProxyPass balancer://www.primjer.com
 </Location>
 


I to je sve što trebamo konfigurirati kako bi load balancer radio. Sa balancer member postavljamo ip adresu svih servera na kojima se neka stranica vrti. Ovo jednostavno možete testirati na način da podignete dvije virtualne mašine. Na svakoj od njih ćete dobiti zasebnu ip adresu koju stavite ovdje i jednostavno se može provjeriti da load balancer radi.

Link sa kojeg možete downloadati video na kojem je prikazano kako load balancer radi: https://www.dropbox.com/s/pc36l3sbgz0o6ty/load_balancer.ogv

Security

SSL

Secure Sockets Layer (SSL) je protokol koji ostvaruje identifikaciju dva sugovornika povezana preko računalne mreže i zaštićeni prijenos podataka među njima. To je danas vjerojatno najpopularniji način zaštite prijenosa podataka na internetu. Na apacheu je SSL poprilično jednostavno konfigurirati. SSL mod omogućimo u terminalu jednostavnom naredbom(naravno kao root korisnik):

a2enmod ssl

I SSL mod je sada omogućen na apache serveru. Da bi ovaj mod uopće radio on treba ključ i certifikat. No na apacheu već postoji "defaultni" ključ i certifikat pa se za potrebe ovog projekta može koristiti taj. Ukoliko netko treba kreirati svoj certifikat i ključ detaljne upute može potražiti na sljedećem linku: https://help.ubuntu.com/10.04/serverguide/certificates-and-security.html. Upute su vrlo jasne i mislim da ne bi trebalo biti problema sa kreiranjem vlastitog cerifikata. Nakon što je certifikat kreiran, njega treba i potpisati. To inače potpisuje ovlašteno tijelo (Certification Authority) no isti taj certifikat možemo potpisati i sami što je također objašnjeno u prethodnom linku. Treba ovdje napomenuti da ukoliko sami potpišemo certifikat prije otvaranja stranice u pregledniku javiti će nam se sljedeći "warning" : This Connection is Untrusted. To se dogodilo zato jer smo mi sami potpisali ovaj certifikat, a ne nadležno tijelo.

Što se tiče ostalih promjena koje trebamo napraviti prije nego možemo koristiti SSL podršku, trebamo u konfiguracijskom fileu servera kojeg želimo pokretati preko SSL-a dodati sljedeće:

 <VirtualHost  127.0.2.3:443>
    SSLEngine 	on
    SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
      .
      .
      .
 </VirtualHost>
 

Ovdje smo sada definirali da će se promet odvijati preko porta 443 (treba paziti i da je u ports.conf postavljeno da apache "sluša" port 443), te smo postavili SSLEngine na "on " što mora biti ukoliko želimo koristiti ovaj mod. Zatim smo još samo postavili putanje do vlastito potpisanog certifikata.

Nakon što restartiramo apache naredbom:

service apache2 restart

možemo otići na https://www.primjer.com i vidjeti jesmo li sve dobro konfigurirali. Ukoliko jesmo treba se pojaviti već gore spomenuti "warning" te kada se to zanemari pokazati će se stranica. Treba primjetiti da i dalje možemo pristupiti i preko http-a, odnosno ukoliko bismo upisali http://www.primjer.com to bi radilo. Ukoliko želimo da sav promet ide preko porta 443, to možemo napraviti na sljedeći način:

 <VirtualHost 127.0.2.3:80>
    ServerAdmin webmaster@localhost
    RewriteEngine on
    RewriteCond %{SERVER_PORT} !^443$
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
 </VirtualHost>
	
 <VirtualHost  127.0.2.3:443>
    SSLEngine 	on
    SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
	.
	.
	.
 </VirtualHost>

Što smo ovime postigli ? Server će svaki puta klijenta sa porta 80 preusmjeriti na port 443. Kada nam je to korisno ? Možda i nije potrebno svaku stranicu preusmjeriti na HTTPS, ali servis poput npr. emaila svakako jest. Napomena: ukoliko nije, prije nego će ova konfiguracija ispravno raditi morate postaviti mod rewrite na enabled. To možete učiniti sa sljedećom naredbom:

a2enmod rewrite

Detaljnije o ovom modulu možete pogledati na sljedećem linku: http://httpd.apache.org/docs/2.2/mod/mod_ssl.html

Na sljedećem linku možete downloadati video na kojem je prikazano kako radi mod ssl: https://www.dropbox.com/s/pgkrnd73b80bqag/mod_ssl.ogv

Mod_evasive

Mod_evasive je još jedan u nizu modova kojim možemo podići razinu sigurnosti apachea na još višu razinu. Njime se možemo zaštititi od potencijalnih DoS napada te čak i od brute force napada. Ukratko, sa konfiguriranjem ovog moda možemo ograničiti broj requestova po stranici unutar jedne sekunde, onemogućiti klijenta da šalje bilo kakve requestove dok je na "black listi" Mod_evasive ćemo instalirati putem apache extension toola, odnosno apxa. Sa sljedećim naredbama možemo instalirati mod_evasive:

  wget wget http://www.zdziarski.com/blog/wp-content/uploads/2010/02/mod_evasive_1.10.1.tar.gz
  tar xzf mod_evasive_1.10.1.tar.gz
  cd mod_evasive
  apxs -cia mod_evasive20.c

Sa sljedećom naredbom postavljamo mod_evasive na enabled:

a2enmod evasive20

Nakon što smo instalirali mod_evasive možemo ga ići konfigurirati. Konfiguraciju za mod_evasive stavljamo u glavni konfiguracijski file od apachea, apache2.config.


 <IfModule mod_evasive20.c>
    DOSPageCount        2
    DOSSiteCount        50
    DOSPageInterval     2
    DOSSiteInterval     1
    DOSBlockingPeriod   10
    DOSEmailNotify admin@email.com
 </IfModule>


Što smo ovdje sve konfigurirali ? Sa DOSPageCount smo postavili maksimalan broj requestova za određenu stranicu unutar postavljenog intervala. Sa DOSSiteCount odredili maksimalan broj requestova za svaki pojedini objekt na toj stranici unutar postavljenog intervala. Ukoliko će broj postavljenih requestova u bilo koja od ova dva slučaja prijeći ovaj prag koji smo postavili, klijent ide na "block listu". Spomenute intervale postavljamo sa DOSPageInterval i DOSSiteInterval. Na koliko sekundi je blokiran IP klijenta koji je završio na "black listi" određujemo sa DOSBlockingPeriod, dok smo sa DOSEmailNotify postavili e-mail adresu (najčešće od admina) na koju želimo primiti obavijest o DoS napadima.

Naravno, prije nego što idemo raditi bilo šta drugo server je potrebno restartirati kako bi uzeo promjene u obzir:

service apache2 restart 

Gore navedene vrijednosti svatko, naravno, prilagođava sebi. Ovdje su vrijednosti postavljene tako da će biti lako testirati radi li uopće mod_evasive. Naime,postavili smo DOSPageCount = 2 te DOSPageInterval = 2. To možemo interpretirati na sljedeći način: svaki klijent može unutar 2 sekunde prema serveru uputiti najviše 2 requesta. Ako će poslati više od 2 requesta, klijent ide na "block listu" i neće moći pristupiti stranici 10 sekundi(jer smo toliko odredili sa DOSBlockingPeriod = 10). Sve to možemo testirati na sljedeći način. Odemo na stranicu www.primjer.com (nju smo definirali na početku prilikom objašnjavanja virtual hosta) i kliknemo 3 puta brzo F5. Na taj način prema serveru smo poslali 3 requesta, umjesto maksimalnih 2 i taj klijen ide na "block listu" što je vidljivo jer će se ispisati error: "Forbidden. You don't have permission to access / on this server." Na taj način smo uspješno provjerili da mod_evasive radi.

Na sljedećem linku možete downloadati video na kojem je prikazano kako mod_evasive radi: https://www.dropbox.com/s/7esss1d3loolo8l/mode_evasive.ogv

Mod_security

Mod_security je mod napravljen za apache server kojim se možemo zaštiti od raznoraznih napada, kao što su npr XSS, SQL injection i sl. Mod_security je u biti firewall pa njime možemo i blokirati određenje ip adrese. Sve to radimo pisanjem pravila unutar konfiguracijskog filea. Pošto je mod_security zaseban projekt, nećemo ga ovdje opisivati jako detaljno već ćemo samo pokazati kako ga instalirati i napraviti neke potrebne promjene u početnoj konfiguraciji. Sljedećim naredbama možete instalirati mod_security:

 sudo apt-get install libxml2 libxml2-dev libxml2-utils
 sudo apt-get install libaprutil1 libaprutil1-dev
 sudo apt-get install libapache-mod-security

Prije nego što ga počnemo koristiti, moramo mod_security postaviti na enabled, a to radimo sljedećom naredbom:

 a2enmod mod_security

Mod_security je sada instaliran i kako bismo ga dalje koristili potrebno je napraviti neke promjene u konfiiguracijskom fileu. U direktoriju /etc/apache2/mods-enabled biti će konfiguracijski file mods_security.conf. No ovdje smo samo uključili, sa naredbom include, konfiguracijski file od mod_security-a koji se nalazi u direktoriju /etc/modsecurity. To je po "defaultu" napravljeno naredbom:

 Include "/etc/modsecurity/*.conf" 

Ovime smo uključili sve fileove sa ekstenzijom .conf, a koji se nalaze u naznačenom direktoriju. Ovdje se nalazi i "defaultni" konfiguracijski file za mod-security, mod-security.conf-recommended. Ovdje moramo napraviti nekoliko promjena.

	
  .
  .
  .
 SecRuleEngine On
 SecRequestBodyLimit 13107200
  .
  .
  .

Najbitnije što smo ovdje napravili, a nikako ne smijemo zaboraviti, je postavljanje SecRuleEngine na "On". Po "defaultu" to je stavljeno na "DetectionOnly", a sa time će mod_security otkriti prijetnju ali ju neće blokirati. Mod_security će početi blokirati prijetnje serveru tek kada ga stavimo u aktivno stanje, odnosno kada postavimo SecRuleEngine na "On". Još možda samo da spomenemo SecRequestBodyLimit. Ovo iznad je "defaultna" vrijednost, a ona se naravno može postaviti na neku drugu, željenu vrijednost. To je broj u bajtovima kojim označavamo najveću veličinu neke datoteke koju smijemo uploudati na server. Ukoliko imate web stranicu na kojoj dopuštate uploud datoteka velikih veličina, ovaj broj mora biti što veći.

I što se tiče neke početne konfiguracije to su sve promjene koje smo trebali napraviti. Već od prije smo u glavni konfiguracijski file za apache, apache2.conf uključili sve konfiguracijske fileove modova koje smo postavili na enabled tako da bi sada mod_security trebao raditi. Ukoliko ga dalje ne konfiguriramo sam po sebi mod_security i neće biti od velike koristi. Kao što sam već naveo, mod_security je firewall, točnije web aplication firewall, i pisanjem pravila u biti potpuno koristimo njegove mogućnosti. Pravila pišemo u konfiguracijski file mod-security.conf-recommended ili u neki drugi ako smo ga kreirali(bitno je samo da se nalazi u direktoriju kojeg smo definirali u fileu mod-security.conf). Navesti ću samo neka pravila kako bismo prikazali kako ona izgledaju. Npr. protiv napada XSS možemo iskoristiti sljedeća pravila:

 SecFilter "<(.|\n)+>"
 SecFilter "<[[:space:]]*script"
 SecFilter "<script"
 SecFilter "<.+>" 

Sa sljedećim pravilom bismo blokirali naznačenu ip adresu:

SecRule REMOTE_ADDR "^127\.0\.0\.1$" nolog,phase:1,denny

Za kraj, još bih samo napomenuo da nisu naredbe ostale iste kada se prelazilo sa mod_securitya 1.x na noviju verziju 2.x. Na sljedećem linku možete downloadati pdf dokument u kojem su lijepo naznačene sve promjene koje su se dogodile: http://goo.gl/J2Sgm .

Mod_access

Mod_access je još jedan u nizu "security" modula koji je dostupan za apache. Ovaj modul smo već dobili kada smo instalirali apache server. Samo jedna napomena: u prijašnjim verzijama apache servera, ovaj modul se zvao mod_access, a u novijim verzijama 2.x se zove authz_host. Ukoliko nije postavljen na enabled po "defaultu", uključujemo ga sa naredbom:

a2enmod authz_host

Za ovaj mod nećemo dobiti na početku konfiguracijski file gdje ćemo pisati neke naredbe, već ćemo sve naredbe koje se odnose na ovaj mod pisati npr. unutar kongfiguracijskog filea za svaki pojedini virtual host. Pogledajmo sljedeći primjer.

<VirtualHost 127.0.2.2:80>
 ServerAdmin webmaster@localhost
 ServerName www.primjer.com
 DocumentRoot /var/www/www.primjer.com
 <Directory /var/www/www.primjer.com>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all           
 </Directory>
          .
          .
          .

Ovo je konfiguracijski file za virtual host www.primjer.com. Unutar taga <Directory> možemo pisati naredbe za authz_host. Po "defaultu" je za svaki virtual host postavljeno "allow from all" što znači da će se tome serveru moći pristupiti sa svih ip aresa. Ukoliko želimo blokirati nekog klijenta(uzmimo za primjer da je ip adresa od klijenta 192.168.1.1) jednostavno blokiramo njegovu ip adresu i taj klijent više neće moći pristupiti tom serveru. Dakle promjena koju bi trebali napraviti je sljedeća:

 deny from 192.168.1.1         

Sada taj klijent neće moći pristupiti tom serveru. Možemo ovdje koristiti i cider notaciju ukoliko bismo željeli blokirati neki raspon ip adresa.

Više o ovom modu možete pronaći na: http://httpd.apache.org/docs/2.2/mod/mod_authz_host.html

Na sljedećem linku možete downloadati video na kojem je prikazano kako ovaj mod radi: https://www.dropbox.com/s/lboizqwsx8hgk8g/mod_authz_host.ogv

Konfiguracijske datoteke

Konfiguracijske datoteke se nalaze na githubu na sljedećem linku:

 https://github.com/toprisela/apache-configuration

--Toprisela 13:10, 20. siječnja 2013. (CET)

Cherokee

Cherokee pek sddgssgsg.jpg

Cherokee je open source web server visokih performansi, poprilično brz, fleksibilan i relativno jednostavan za konfiguraciju zahvaljujući kvalitetnom admin panelu. Radi na svim platformama, te je jednako efikasan i na Windowsima i na UNIX-u. Podržava najnovije tehnologije tipa FastCGI, SCGI, PHP, CGI, SSI, TLS i SSL kriptirane konekcije, virtualne hostove, autentikaciju, "fly encoding", "Load Balancing", log datoteke kompatibilne sa Apache serverom, HTTP Proxy i još dosta toga. Tako bar Cherokee vendor navodi. U nastavku ćemo pokušati ispitati većinu toga, sa naglaskom na stvari koje su u domeni projekta.


Instalacija

Server se instalira jednostavnom i klasičnom naredbom za UNIX sustav:

 sudo apt-get install cherokee 

Naša preporuka je instalacija dodatnog paketa u kojem se između ostalog nalaze i recovery file-ovi u slučaju da smo greškom izbrisali neku sistemsku datoteku.

sudo apt-get install lcibherokee-mod-rrd

Sljedećom naredbom pristupamo poprilično intuitivnom "user-friendly" grafičkom sučelju sa brojnim mogućnostima.

sudo cherokee-admin

Nakon izvršene naredbe dobivamo podatke kao na slici ispod.

Cherokee pek prijava.jpg


Radi se o useru koji je uvijek standardno "admin" i jednokratkoj lozinci. Potrebno ih je unijeti u formu dobivenu na generiranom linku http://127.0.0.1:9090/ tj. localhostu. Vidimo da je standardni port 9090. Ovo služi tome kako bi se ostali korisnici na hostu onemogućili u pristupu admin panelu bez prethodne autentifikacije.


Osnovnim operacijama možemo pristupiti kroz administratorsko sučelje ili preko sljedećih naredbi:

sudo service cherokee status
sudo service cherokee stop
sudo service cherokee start
sudo service cherokee restart

Kako bi se zaobišla ranije navedena autentifikacija (pitanje sigurnosti), koristi se sljedeća naredba:

sudo cherokee-admin -u

Ona se preporuča isključivo u razvojnom procesu i treba ju onemogućiti u stvarnoj upotrebi.

Zanimljiva je još i sljedeća naredba:

sudo cherokee-admin -b

Sa navedenom naredbom omogućujemo pristup administratorskom sučelju sa nekih udaljenih računala, točnije sa svih :-) tako da sa ovim u praksi treba biti poprilično oprezan. Najbolje je da se navedena naredba ne koristi, već da se koristi njena sigurnija verzija realizirana putem SSH tunela. Ta naredba izgleda ovako:

ssh -L 9090:localhost:9090 remote_IP

a služi spajaju na IP adresu udaljenog računala, točnije na administratorsko sučelje servera. Isto tako, moguće je specificirati adresu kojoj je pristup dozvoljen zajedno sa portom na kojem će se slušati. U primjeru je to adresa 92.150.1.1, te port 5000:

cherokee-admin -b 92.150.1.1 -p 5000


Eventualno bismo još dodali naredbu koja prikazuje sve aktivne konekcije i brojeve portova koji su vezani za rad servera. Naredba je sljedeća:

sudo netstat -antp | grep cherokee 

Ostale korisne naredbe, mogu se naći na [1]

Konfiguracija

Konfiguracijski fileovi standardno su smješteni na sljedećoj lokaciji

/etc/cherokee

a konkretno do početne osnovne konfiguracije servera dolazimo naredbama:

$ cd /etc/cherokee
$ nano cherokee.conf

Otvara nam se .conf file sljedećeg sadržaja:

config!version = 001002101 
server!bind!2!interface = 127.0.0.1 
server!bind!2!port = 80 
server!bind!2!tls = 0 
server!collector = rrd 
server!group = alpek
server!keepalive = 1 
server!keepalive_max_requests = 500 
server!panic_action = /usr/share/cherokee/cherokee-panic 
server!pid_file = /var/run/cherokee.pid 
server!server_tokens = full 
server!timeout = 15 
server!tls!protocol!SSLv2 = 0 
server!user = alpek

vserver!1!directory_index = index.html 
vserver!1!document_root = /var/www 
vserver!1!error_writer!filename = /var/log/cherokee/cherokee.error 
vserver!1!error_writer!type = file 
vserver!1!logger = combined 
vserver!1!logger!access!buffsize = 16384 
vserver!1!logger!access!filename = /var/log/cherokee/cherokee.access 
vserver!1!logger!access!type = file 
vserver!1!nick = default 

icons!default = page_white.png 
icons!directory = folder.png 
icons!file!bomb.png = core 
icons!suffix!page_white_php.png = php 

mime!application/x-latex!extensions = latex 
mime!application/x-tar!extensions = tar 
mime!audio/mpeg!extensions = mpga,mpega,mp2,mp3,m4a 
mime!image/gif!extensions = gif 
mime!image/jpeg!extensions = jpeg,jpg,jpe 
mime!image/png!extensions = png 
mime!text/css!extensions = css

Ukratko ćemo pojasniti što znači koji od navedenih parametara u početnoj konfiguraciji. Jedino smo izmijenili paramtere za korisnika i grupu, iz www-data u postojeći, točnije replicirali www-data i nazvali ga ovako kako je navedeno. Na taj način onemogućavamo pristup drugim korisnicima u ulozi superusera.Ovaj način inače treba izbjegavati jer može stvoriti probleme u radu sa drugim programima i tijekom instalacija. Potrebno je učitati passwd file:

 user@ubuntu:/etc$ nano passwd 

te u istom file-u promijeniti novokopirani www-data u proizvoljni:

 alpek:x:33:33::/var/www:/bin/sh 

te na taj način omogućiti standardnu upotrebu dodanog korisnika.

Od važnijih parametara tu je server!bind!2!interface kojim bindamo adresu preko koje ćemo pristupiti serveru (ranije smo naveli naredbe koje služe za to), zatim server!bind!2!port označava port na kojem server čeka konekciju. server!bind!2!tls je logička varijabla koja označava da li je omogućena sigurna konekcija preko TLS protokola.

Parametar server!keepalive kao i kod ostalih server općenito označava održavanje perzistentne konekcije, odnosno neotvaranje nove konekcije za svaki zahtjev posebno, već se veza održava neko određeno vrijeme dok traje komunikacija između servera i klijenta.

Parametar server!keepalive_max_requests je dosta bitan i poslije će doći do izražaja kada budemo govorili o raspoloživosti ovog servera, a on označava koliko je najviše moguće zahtjeva u jednoj prije spomenutoj konekciji.

server!panic_action je ustvari putanja do skripte u Pythonu koja handla eventualno neželjene događaje, možemo ju nazvati skriptom za obradu pogrešaka. Parametar server!timeout predstavlja vrijeme koje server daje klijentu za treći korak u three-way-handshake-u, konkrento ACK poruci kojom će se uspostaviti TCP konekcija. Ukoliko se to ne dogodi u navedenom intervalu, server podrazumijeva da je klijent odustao od uspostave veze.

MIME označava dozvoljene ekstenzije koje server podržava ili bolje rečeno dozvoljava manipulaciju istima, a mogu biti: aplikacijske, slikovne, zvučne i tekstualne.

Virtualni host

Cherokee omogućuje dodavanje virtaulnog servera unutar vlastitog admin panela. Izbornik “vServers” nudi intuitivno sučelje u kojemu je potrebno navesti osnovne informacije o serveru kojeg kreiramo. To su “Virtual Server nickname” odnosno naziv servera po kojem ćemo ga prepoznati (u primjeru 'alen'), zatim je potrebno odrediti “Document Root” iz kojeg će server čitati file, te naravno index.html ili file po izboru u formi “Directory Indexes”. Sljedeća opcija je “Host Match” gdje možemo izabrati metode po kojima ćemo pristupiti virtualnom serveru, to su:

Match Nickname
Wildcards
Regular Expressions
Server IP 

Za potrebe ovoga projekta koristit ćemo prvu opciju, dakle pristup preko ranije unesenog Virtual Server nickname-a. Opcije u formi Behavior su izrazito bitne.

Behavior cherokee Alpek.jpg


Ovdje definiramo sva potrebna “pravila ponašanja” sa svim objektima koje se nalaze na serveru. Možemo i dodati sve elemente koje smatramo bitnima i koje su nam u radu potrebne. Za potrebe ovog projekta dodana su prva 2 pravila vidljiva na slici te se po njima se virtualni server razlikuje od standardnog.

Konkretno, pravila označavaju kako se handlaju .php ekstenzije, te kako se radi redirekcija sa eksterne domene na internu pomoću regularnih izraza. Još bi naveli obrazac za obradu pogrešaka, odnosno kako se definira što će se dogoditi ako dođe do određene pogreške.


Drugadruga handl alpek.jpg

Iz prikaza se vidi path do skripte za obradu navedenih tipova pogrešaka.

Nakon definiranja virtualnog hosta, konfiguracijski file izgleda ovako:

vserver!11!directory_index = index.html
vserver!11!document_root = /etc/cherokee/alen
vserver!11!error_handler = error_redir
vserver!11!error_handler!400!show = 0
vserver!11!error_handler!400!url = /etc/cherokee/alen/krivo.php
vserver!11!error_handler!403!show = 0
vserver!11!error_handler!403!url = /etc/cherokee/alen/zabrana.php
vserver!11!error_handler!404!show = 0
vserver!11!error_handler!404!url = /etc/cherokee/alen/obavijest_greska.php
vserver!11!error_writer!filename = /etc/cherokee/alen/greske_virtual.txt
vserver!11!error_writer!type = file
vserver!11!nick = alen
vserver!11!post_max_len = 20000
vserver!11!rule!30!document_root = /usr/share/cherokee/themes
vserver!11!rule!30!match = header
vserver!11!rule!30!match!complete = 0
vserver!11!rule!30!match!directory = /etc/cherokee/alen/
vserver!11!rule!30!match!header = Host
vserver!11!rule!30!match!match = ^alen.com
vserver!11!rule!30!match!type = regex
vserver!11!rule!20!document_root = /usr/share/cherokee/icons
vserver!11!rule!20!handler = file
vserver!11!rule!20!match = directory
vserver!11!rule!20!match!directory = /icons
vserver!11!rule!10!handler = common
vserver!11!rule!10!match = default
vserver!11!ssl_certificate_file = /etc/ssl/server.crt
vserver!11!ssl_certificate_key_file = /etc/ssl/server.key

Iz njega je jednostavno očitati promjene. Parametri vserver!11!ssl_certificate_file i vserver!11!ssl_certificate_key_file će biti pojašnjeni u nastavku kada bude govora o SSL/TLS-u.

Raspoloživost

Load Balancing

Load balancing podrazumijeva raspodjelu request-ova, a samim time I opterećenje servera na više istih. Samim time, LB daje sljedeće prednosti:

• Povećava skalabilnost

• Povećava performance cjelokupnog sustava

• Povećava raspoloživost I mogućnosti recovery-a u slučaju nepovoljnog događaja

GANGnAM sTYLE cherokee.jpg

Na slici iznad je prikazana ilustracija load balancinga uz pomoću posredničkih uređaja na 3. sloju. Kako se ne bismo previše zadržali da teoretskom dijelu, slijedi prikaz na primjeru, konkretno Cherokee serveru. Naravno bez posredničkih uređaja, već virtualno što Cherokee omogućava.

Cherokee omogućava sljedeće strategije balansiranja:

Round Robin

IP hash

FAilover

Dobra stvar (i jedina takva) jest to što Cherokee omogućuje kreiranje virtualnih servera za potrebe testiranja i komunikaciju između njih pod određenim pravilima, tako da nije potrebno dizati virtualne mašine. Uzima u obzir lokacije foldera, a ne IP adrese. To ipak ne može nadoknaditi dokumentaciju koja je najblaže rečeno - katastrofalna. Nekoliko definicija i to je to, prepušteni ste sami sebi. Postupak je sljedeći:

1. Kreiramo željeni broj virtaulnih servera (u primjeru 3)
2. Definiramo pravila, na primjer: ukoliko imaju više od 5 zahtjeva u sekundi, moraju pokrenuti handler na temelju definiranog pravila
3. Handler postavljamo na “Redirection” i odabiremo lokaciju gdje će se request preusmjeriti
4. U primjeru sa 3 servera Round Robin realiziramo kružno: server1 → server2 → server3 → server1

Na slici ispod vidimo primjer konfiguracije servera 1 na kojem definiramo preusmjeravanje na server 2 za metodu GET (zahtjev prema serveru).

Redirekcija cherokeeeee alpek.jpg

Mogućnosti Cherokee-a vezano za raspoloživost su poprilično skromne. Ne sadrži klasične module kao što je to kod ostalih servera i daleko je od fleksibilnosti ugradnje modula koje imaju ostali serveri. Većinu stvari treba na neki način improvizirati i to na dosta čudan i nelogičan način. Ukoliko nešto ne radi, teško je shvatiti zašto jer su logovi nejasni i neupotrebljivi, te se tu gubi dosta vremena. Na kraju većinom bude greška tipa: nešto nevezano je enableano/disableano i zbog toga ne radi. U dokumentaciji o tome ni riječi, kao niti na forumima na kojima Cherokee konfiguracija baš i nije tema.

Sigurnost

SSL

Prije same instalacije servera nužno je instalirati OpenSSL library sljedećom naredbom:

sudo apt-get install libcherokee-mod-libssl

Preporuka je da se navedena biblioteka instalira na ovaj način zbog potpunosti intalacije i dodatnih biblioteka:

sudo add-apt-repository ppa:cherokee-webserver/ppa
sudo apt-get update
sudo apt-get install libcherokee-mod-libssl

Ova biblioteka (libcherokee-mod-libssl) je potrebna kako bi za SSL/TLS back-end opciju unutar admin panela mogli dobiti na izbor OpenSSL/libss kao na slici ispod:

Enable alpek cherokee.jpg

Nakon toga slijedi klasično generiranje ključeva. Postupak je ranije opisan pa ga nema smisla više ponavljati (nije specifičan samo za ovaj server). Uglavnom, potrebno je generirati ključeve i potpisati certifikat (za potrebe testiranja potpisano vlastito). Zanimljivo je kako Cherokee ne prihvaća default-ne ključeve kao što je to slučaj sa ostalim serverima, već je nužno generirati nove.

Certifikati alpek cherokee.jpg

Iznad vidimo postavljeni certifikat zajedno sa ključem u pripadajućim formama. Nakon postavljenih certifikata, možemo omogućiti SSL/TLS protokol (HTTPS) na odabranom portu (standardno 443). Ta završna aktivnost prikazana je na slici ispod.

Ssltls Alpek cherokee.jpg

"Zanimljiva" stvar je to da ukoliko je omogućen IPv6, HTTPS možete zaboraviti. Izrazito velika zamjerka na dokumentaciju gdje to nije spomenuto niti u tragovima, kao niti valjani razlozi za takvo nešto. Nakon što je IPv6 onemogućen, moguće je preko HTTPS-a pristupiti željenoj stranici, u ovom slučaju zbog generiranih certifikata nema razlika u pristupu stranicama:

http://localhost/alen/

i

https://localhost/alen/

HTTP -> HTTPS redirection

Ukoliko pristup stranicama zahtjeva veću sigurnost te korisnik toga najčešće nije svjestan, potrebno je automatski preusmjeriti sa standardnog HTTP-a na sigurniji HTTPS. To se na Cherokee serveru može napraviti relativno jednostavno na sljedeći način:

1. Dodajemo pravilo u kojem postavljamo vrijednost SSL / TLS na logičku istinu

2. Dodajemo operator NOT ispred toga izrada

3. Definiramo operaciju koja će se dogoditi ako vrijedi izraz (konkretno ako vrijedi NOT is SSL/TLS )

4. Operaciju postavljamo na "Redirection"

5. Unosimo REGEX pravilo sljedećeg oblika:

Regular Expression:   /(.*)$

Substitution:         https://${host}/$1


čime smo definirali da se koristi HTTPS ukoliko to nije pretpostavljeni slučaj. A admin-panelu Cherokee-a to izgleda kao na slici ispod.


Redirekcija cherokee alpek.jpg


Restricting traffic by IP

Ograničavanje prometa sa određenih adesa hostova ili mreža je poprilično jednostavno. Važno je samo dodati "non-final" pravilo na vrh liste pravila za server. Koraci su sljedeći:


1. Dodajemo pravilo tipa "Incoming IP/Port" i definiramo ulaznu adresu i broj porta koju želimo onemogućiti

2. U novostvorenom pravilu dodajemo logički NOT, te time definiramo u slobodnom govoru sljedeće :"Ne puštaj ništa sa adrese X.X.X.X na portu Y"

3. Dodajemo handlere koji će obrađivati requestove sa zabranjenih adresa, npr. "Drop connesction" ili "Redirection"

Dgdgdfaasfsadllooo cherokee.jpg


NAPOMENA: Valja biti oprezan sa logičkim operatorima, jer krivom upotrebom možemo u potpunosti promijeniti željene uvjete.

Rezime

Cherokee je sve samo ne jednostavan server za konfiguraciju kako razvijatelji navode. Najveći problem je loša dokumentacija iz koje je teško išta shvatiti jer su navedene teorijske osnove (općenite) bez konkretnih stvari za samu konfiguraciju. Prvi pogled na ušminkanu dokumentaciju možda daje drukčiji dojam, ali već pri pokušaju realiziranja nečega ozbiljnijeg dolazi do problema. Problem je i u maloj raširenosti servera tako da je izostavljen i iz većeg broja klasičnih forum rasprava.

Sljedeća stvar je nelogičnost i nepotrebno kompliciranje u postavljanju same konfiguracije. Na primjer, ranije navedeni HTTPS ne radi ukoliko je IPv6 enable-an. Čudno je da nema konverter adresa iz jednog oblika u drugi ili nešto slično, a u najmanju ruku to je moglo pisati i u dokumentaciji ili u obliku mini forme sa upozorenjem.

Najveća zamjerka ide nedostatku modula klasičnih za druge servere, što znatno utječe na mogućnosti servera. Neke se stvari mogu improvizirati kroz postojeću konfiguraciju, što pak uvelike otežava posao konfiguriranja.

Pohvala ide serveru zbog brzine, kao i intuitivnom grafičkom sučelju.

Finalna usporedba i zaključak

Nakon iscrpnog testiranja ova četiri servera dobili smo zanimljive zaključke. Što se tiče količine dostupnih modula apache je definitivno pobjednik, jer se široko koristi i ima veliki "community" koji pridonosi razvoju modula za ovaj server. Posebno se ističe "mod_security" koji uvelike može unaprijediti sigurnost sustava na kojem se isti nalazi. Spomenut ćemo još da isti postoji i za NGINX no on je još u beta fazi pa mu to još uvijek nećemo navoditi kao veliku prednost. Što se tiče same arhitekture servera nginx, lighttpd i cherokee imaju sličnu arhitekturu jer su svi asinkroia serveri, za razliku od apache-a koji je "process based" što u konačnici rezultira većim zauzećem resursa računala na kojem se nalazi apache server. Što se tiče modula za visoku raspoloživost sustava ovdje smo za svaki server naveli po jedan takav, no za nginx i lighttpd ne postoji puno modula mimo ovih navedenih, dok bi se za apache moglo i pronaći. Za cherokee ih gotovo i nema. Prednost svih je da ih se može lako integrirati sa nekim drugim serverima koji su namjenjeni za poboljšanje visoke raspoloživosti sustava, npr HaProxy. HeartBeat i sl..

Napravili smo i neke testove na defaultnim postavkama servera. Koristili smo "ab" odnosno "Apache HTTP server benchmarking tool", i na svaki server smo pustili 30000 zahtjeva sa razinom konkurentnosti od 100. Naredba kojom se ovakav jedan test provodi je:

ab -n 30000 -c 100 http://localhost/

Rezultati testiranja su sljedeći:

NGINX

Server Software:        nginx/1.2.1
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        151 bytes

Concurrency Level:      100
Time taken for tests:   3.782 seconds
Complete requests:      30000
Failed requests:        0
Write errors:           0
Total transferred:      10830000 bytes
HTML transferred:       4530000 bytes
Requests per second:    7932.65 [#/sec] (mean)
Time per request:       12.606 [ms] (mean)
Time per request:       0.126 [ms] (mean, across all concurrent requests)
Transfer rate:          2796.57 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    6   1.0      6      10
Processing:     2    7   1.7      6      18
Waiting:        1    5   1.5      5      17
Total:          7   13   1.4     12      25

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     13
  75%     13
  80%     13
  90%     14
  95%     14
  98%     17
  99%     19
 100%     25 (longest request)

Lighttpd

Server Software:        lighttpd/1.4.28
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        177 bytes

Concurrency Level:      100
Time taken for tests:   3.752 seconds
Complete requests:      30000
Failed requests:        0
Write errors:           0
Total transferred:      13020000 bytes
HTML transferred:       5310000 bytes
Requests per second:    7996.29 [#/sec] (mean)
Time per request:       12.506 [ms] (mean)
Time per request:       0.125 [ms] (mean, across all concurrent requests)
Transfer rate:          3389.05 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        2    6   0.7      5      11
Processing:     3    7   1.1      7      13
Waiting:        2    5   1.2      5      11
Total:          8   12   0.9     12      19
WARNING: The median and mean for the initial connection time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     13
  75%     13
  80%     13
  90%     14
  95%     14
  98%     14
  99%     15
 100%     19 (longest request)

Apache

Server Software:        Apache/2.2.22
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        177 bytes

Concurrency Level:      100
Time taken for tests:   7.983 seconds
Complete requests:      30000
Failed requests:        0
Write errors:           0
Total transferred:      13590000 bytes
HTML transferred:       5310000 bytes
Requests per second:    3757.78 [#/sec] (mean)
Time per request:       26.611 [ms] (mean)
Time per request:       0.266 [ms] (mean, across all concurrent requests)
Transfer rate:          1662.38 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0      12
Processing:     4   26   4.6     28      52
Waiting:        3   26   4.6     28      52
Total:         10   27   4.3     28      52

Percentage of the requests served within a certain time (ms)
  50%     28
  66%     29
  75%     29
  80%     30
  90%     30
  95%     31
  98%     34
  99%     37
 100%     52 (longest request)

Cherokee

Server Software:        Cherokee/1.2.101
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        177 bytes

Concurrency Level:      100
Time taken for tests:   3.877 seconds
Complete requests:      30000
Failed requests:        0
Write errors:           0
Total transferred:      11370000 bytes
HTML transferred:       5310000 bytes
Requests per second:    7737.58 [#/sec] (mean)
Time per request:       12.924 [ms] (mean)
Time per request:       0.129 [ms] (mean, across all concurrent requests)
Transfer rate:          2863.81 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    5   1.5      5      12
Processing:     1    8   6.5      7      58
Waiting:        1    6   5.0      5      57
Total:          2   13   6.7     12      64

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     13
  75%     14
  80%     15
  90%     18
  95%     24
  98%     36
  99%     45
 100%     64 (longest request)

Vidljivo je da apache server pri ovom broju zahtjeva daleko najsporiji, dok se kao pobjednik istakao lighttpd, no NGINX i Cherokee ne zaostaju puno. Proveli smo i testiranja sa većim brojem zahtjeva i tada se rezultati malo mijenjaju, gdje NGINX pokazuje svoju moc ;).

Da zaključimo, Apache se ističe velikim brojem modula i mogućnostima nadogradnje, no zbog malo drugačije arhitekture sporiji je nego ostali serveri. NGINX i Lighhttpd su po nama odličan izbor ukoliko se traže dobre performanse, no imaju manjak modula ukoliko se uspoređuju sa Apache-om. Cherokee je opet priča za sebe, poprilično brz i efikasan ali sa izrazito skromnom dokumentacijom po pitanju bitnijih stvari i manjkom modula.

NAPOMENA: U izradi zaključka su sudjelovali svi članovi tima.

Osobni alati
Imenski prostori
Inačice
Radnje
Orijentacija
Traka s alatima