Nginx
Davor Tomala
Luka Rajčević
Uvod
Nginx je Web server i reverse proxy server otvorenog koda. Protokoli koje podržava su HTTP, SMTP, POP3 i IMAP. Razvijen je (i još uvijek se razvija) u Rusiji 2002. godine. Razvio ga je Igor Sysoev. Ovaj web server ima kvalitete koje ga izdižu iznad konkurencije (Apache/IIS) i koje ćemo prikazati u daljnjem tekstu. Iako je trenutno tek treći po broju web stranica koje ga koriste, njegova popularnost i korištenje svakodnevno rastu pogotov na stranicama na kojima se odvija velik promet, tj. na kojima se generira velik broj zahtjeva prema serveru. Zašto je to tako, objasniti ćemo u slijedećim odlomcima.
Na slici se može vidjeti statistika korištenja web servera. Slika je preuzeta sa [1] i prikazuje postotak web stranica koje koriste određeni web server. Ovi podaci su novi (statistika je napravljena 16. 01. 2013.). Na njima nginx zauzima treće mjesto, a najkorišteniji je Apache web server. Međutim kada bi pogledali popis stranica koje koriste nginx za posluživanje svojih stranica vidjeli bi da su to neke od najpoznatijih stranica/aplikacija poput facebook.com, hulu.com, tumblr.com, pinterest.com, wordpress.com, about.com ili cnn.com.
Karakteristike Nginx-a
Web Server je software čija je primarna funkcija "dostavljanje" web stranica na korisnički zahtjev korištenjem HTTP protokola. To uključuje HTML dokumente i svaki drugi dodatni sadržaj koji može biti uključen u dokument kao npr. slike, skripte i sl. Nginx je takav software te, kao (gotovo) svaki web server, između ostalih ima slijedeće bitne funkcionalnosti:
Posluživanje statičnih web stranica
kao i svakom web serveru, osnovna funkcionalnost nginx-a je posluživanje statičkih web stranica. Nginx je nakon instalacije već podešen za posluživanje običnih HTML stranica tako da nije potrebno dodatno podešavanje. Ukoliko ipak nismo zadovoljni samo s HTML-om i statičkim stranicama, nginx podržava CGI / FastCGI za posluživanje dinamičkog sadržaja korisnicima. U ovom projektu će biti prikazano kako je moguće iskoristiti nginx za kreiranje dinamičkih stranica u PHP programskom jeziku.
Podrška za SSL/TLS
SSL i TLS su kriptografski protokoli koji omogućavaju sigurnu komunikaciju preko mreže (interneta). Nginx ima modul koji omogućuje korištenje tih protokola za sigurniji pristup podacima, HttpSslModule. U tom modulu se mogu podesiti sve pojedinosti SSL-a kao što je generiranje i potpisivanje certifikata.
Podrška za virtualne hostove
pojam korištenja virtualnih hostova je metoda kojom se na jednom serveru u isto vrijeme nalaze stranice s različitim nazivima domena. Korištenje virtualnih hostova omogućava serveru da dijeli vlastite resurse (memoriju i procesorsku snagu) među servisima koji ne moraju nužno imati isti hostname. Takve usluge su puno jeftinije od npr. dedicated web servera jer se više koristnika može nalaziti na istom serveru i međusobno koristiti iste resurse. To se još naziva i shared web hosting. U nastavku ovog rada će također biti objašnjeno na koji način se jednostavno može dodati novi virtualni host.
Mogućnost kompresije response-a sa servera
nginx sadrži module za kompresiju odgovora klijentima. Za kompresiju se koristi gzip metoda. Prednost kompresije je očita, omogućava smanjenje podataka koje treba prenijeti ali u isto vrijeme je potrebno duže čekati na odgovor jer se na serverskoj strani mora obaviti kompresija. Modul koji omogućava takvu on-the-fly kompresiju je HttpGzipModule.
Fault tolerance
Nginx je dizajniran tako da prilikom otkazivanja nekog dijela sustava, nastavlja s radom (najčešće sa smanjenim kapacitetom).
Jednostavna kontrola pristupa
nginx omogućava jednostavno postavljanje pravila za kontrolu pristupa. Na vrlo jednostavan način je moguće dozvoliti ili zabraniti pristup serveru za pojedine korisnike ili mreže. Za to postoji modul nginx_http_access_module kojim se na vrlo jednostavan način blokira ili dozvoljava pristup pojedinim IP adresama. Primjer konfiguracije bi mogao biti npr. ovakav:
location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; allow 2620:100:e000::8001; deny all; }
Reverse proxy
Izvor: [4]
Nginx služi i kao reverse proxy server. Reverse proxy je tip proxy servera koji se, za razliku od standardnog (forward) proxy-ja postavlja "ispred" web servera. Na taj način se svaki zahtjev prema web serveru ustvari preusmjerava na reverse proxy server. Razloga za to je više.
- Recimo da posjedujemo web stranicu za kojom vlada velika "potražnja", i milijuni korisnika ju žele posjetiti. Sam web server bi jako teško izdržao toliki promet. Kako bi se ipak osigurao pristup stranici svim korisnicima, na web se postavljaju mnogi serveri sa reverse proxy-jem. Tada sav primet ide na te novopostavljene servere, koji svaki korisnički zahtjev šalju na "pravi" web server koji je njima najbliži. Taj koncept se naziva Content delivery network (CDN).
- Korištenjem reverse proxy-ja je olakšan proces osiguravanja "unutarnjih" HTTP servera. Svi zahtjevi idu preko jedne točke i upravo tu je moguće postaviti prava i privilegije za pojedine korisnike te na taj način kontrolirati cijelu mrežu servera sa jednog mjesta.
- Prilikom postavljanja reverse proxy servera, dovoljno je samo njegovu IP adresu učiniti javnom i dostupnom. IP adrese "pravih" HTTP servera ne moraju biti javne te se i na taj način povećava sigurnost servera. Naravno, na reverse proxy-ju je potrebno napraviti URL mapiranje kako bi se zahtjev prema reverse proxy serveru preveo u zahtjev prema pravom HTTP serveru.
Arhitektura
Klasični web serveri koriste procese ili dretve za obradu konkurentnih konekcija, gdje se svaka konekcija obrađuje u zasebnom procesu ili dretvi. Ovisno o aplikaciji, može biti vrlo neefikasno u smislu korištenja memorijskih i procesorskih resursa. Razlog tome su vrijeme i resursi potrebni za kreiranje novog procesa ili dretve, odnosno njegove radne okoline, alociranje memorije (stoga i hrpe), te izvršnog konteksta, čime se smanjuju performanse servera.
Razlog nastanka nginx-a bila je upravo ta potreba da se postignu veće performanse, gustoća i ekonomično iskorištavanje serverskih resursa, čime bi se omogućio dinamički rast web stranica. Inspiracija za ovaj model servera je došla od tadašnjeg razvoja naprednih mehanizama temeljenih na događajima (event-based mechanisms) kod raznih operacijskih sustava. Rezultat razvoja je modularna, asinkrona, jedno-dretvena arhitektura temeljena na eventima.
Konekcije su procesirane u visoko efikasnom „run-loop“-u s ograničenim brojem jedno-dretvenih procesa koji se nazivaju workeri, i svaki od njih može obrađivati i po nekoliko tisuća konkurentnih konekcija i zahtjeva po sekundi.
Struktura koda
nginx-ov worker uključuje jezgrene i funkcionalne module, čiji dijelovi koda se izvršavaju prilikom svakog procesiranje zahtjeva. Moduli čitaju iz i pišu u memoriju i na mrežu, transformiraju sadržaj, izvršavaju izlazno filtriranje, izvršavaju serverske include akcije i prosljeđuju zahtjeve unutarnjim serverima kada se server koristi kao proxy.
Modularna arhitektura generalno omogućava developerima da prošite skup serverskih funkcionalnosti bez potrebe za modificiranjem nginx-ove jezgre. Moduli dolaze u različitim inkarnacijama, core modules, event modules, phase handlers, protocols, variable handlers, filters, upstreams i load balancers. Nginx trenutno ne podržava dinamičko učitavanje modula, oni se kompiliraju zajedno s jezgrom u fazi izgradnje; no podrška za ovakvo učitavanje modula se planira implementirati u budućim većim izdanjima.
Worker
Worker proces prihvaća zahtjeve s dijeljenog „listen socket“-a, nakon čega izvršava „run-loop“ unutar svakog workera. Nema specijalizirane raspodijele konekcija između workera u nginx-u, već to obavljaju jezgreni mehanizmi operacijskog sustava. Prilikom pokretanja se stvara inicijalni skup socketa za slušanje preko kojih onda workeri neprestano prihvaćaju, čitaju iz i zapisuju u socket, te procesiraju HTTP zahtjeve i odgovore.
Spomenuti „run-loop“ je najkompliciraniji dio nginx-ovog worker koda. Uključuje opsežne unutarnje pozive i oslanja se na rukovanje asinkronim taskovima. Asinkrone operaciju su implementirane preko modularnosti, notifikacija događaja, opsežno korištenje callback funkcija, te timera. Unatoč svemu, nginx može zablokirati kada nema dovoljno diskovnih resursa za worker procese.
Kako nginx koristi nekoliko workera za obradu konekcija dobro se skalira s višebrojnim jezgrama. Po jedan worker na svakoj jezgri omogućava potpuno iskorištenje više-jezgrene arhitekture, nema izgladnjivanja resursa, te su mehanizmi kontrole resursa izolirani unutar jedno-dretvenog worker procesa. Ovaj model omogućava veću skalabilnost fizičkih uređaja za pohranu, olakšava bolju iskoristivost diska te obilazi mogućnost blokiranja na diskovnom I/O-u. Rezultat toga je bolja iskoristivost serverskih resursa te efikasna raspodjela opterećenja na nekoliko workera.
Broj nginx workera bi se trebao podesiti ovisno o opterećenju procesora ili diska. Ovdje postoje neka jednostavna pravila, i sistem administrator bi trebao isprobati nekoliko konfiguracija i vidjeti koja najbolje odgovara pojedinom opterećenju.
Neke od preporuka su:
- ako se opterećenje odnosi na CPU (rukovanje s TCP/IP-om, SSL, kompresija) - broj nginx workera bi trebao biti jednak broju jezgri CPU-a
- ako se opterećenje odnosi na I/O diska (posluživanje različitog skupa sadržaja iz spremišta, ili proxiranje) – broj workera bi mogao biti jedan i pol do dva puta broj jezgri procesora
- no neki odabiru broj workera ovisno o broju pojedinačnih spremničkih jedinica, no efikasnost ovakvog pristupa ovisi o tipu i konfiguraciji diskovnih spremnika
Uloge procesa
nginx vrti nekoliko procesa u memoriji, jedan glavni (master) proces i nekoliko workera, no postoji i nekoliko procesa posebne namjene kao što je cache loader i cache manager. Svi procesi su jedno-dretveni (nginx v1.x). Komunikacija između procesa je ostvarena shared-memory mehanizmima. Master proces je pokrenut kao root user, dok su cache loader, cache manager i workeri pokrenuti kao neprivilegirani korisnik.
Master proces obavlja sljedeće zadatke:
- čitanje i validiranje konfiguracije
- kreiranje, spajanje i zatvaranje socketa
- pokretanje, gašenje i održavanje konfiguriranog broja worker procesa
- rekonfiguriranje bez prekidanja servisa
- kontroliranje neprekidnih binarnih nadogradnji (pokretanje nove ili rollback)
- ponovno otvaranje log-ova
- kompiliranje ugrađenih Perl skripti
Worker procesi prihvaćaju, obrađuju i procesiraju konekcija od klijenata, pružaju reverzno proxiranje i funkcionalnost filtriranja, te odrađuju gotovo sve što je nginx u mogućnosti ponuditi. Za praćenje ponašanja nginx instance, sistem administrator treba paziti na workere jer oni zapravo reflektiraju svakodnevne operacije web servera.
Cache loader proces je odgovoran za provjeru cachea na disku te popunjavanje nginx-ove in-memory baze podataka s cache meta podacima. Cache loader zapravo priprema nginx instancu za rad s podacima koji su već spremljeni na disku u posebno alociranoj direktorijskoj strukturi. Zaobilazi direktorije, provjerava se sadržaj meta podataka cachea, ažuriraju se važni unosi u dijeljenoj memoriji te izlazi kada je sve čisto i spremno za korištenje.
Cache manager je uglavnom odgovoran za istek i poništenje cachea. Ostaje u memoriji tokom normalnih nginx operacija, a master proces ga ponovno pokreće ukoliko se dogodi neka pogreška u radu.
Instalacija nginx-a
Instalacija nginx-a je vrlo jednostavna. Ukoliko se nalazimo na linux operacijskom sustavu, potrebno je unijeti samo par naredbi. Instalacija koju ćemo prikazati se obavljala na Ubuntu 12.04 verziji linuxa. Za instalaciju paketa u ubuntu okruženju koristimo standardni način, tako se nginx instalira slijedećom naredbom:
sudo apt-get install nginx
Naravno, za instalaciju je potrebno imati administratorske ovlasti. Nakon što je instalacija završena, nginx se ne pokreće automatski nego ga je potrebno pokrenuti ručno. Da bi to napravili moramo otići u slijedeći direktorij:
cd etc/init.d/
te nakon toga pokrenuti slijedeću naredbu
> sudo ./nginx start Starting nginx: nginx.
Nginx nam odgovara da je pokrenut. Kako bi se i zbilja uvjerili u to jednostavno otvorimo browser te navigiramo na
http://localhost/
tu bi nas trebao dočekati slijedeći prizor,
što bi značilo da je nginx uspješno instaliran i pokrenut na našem računalu. Dokument koji nam se prikazuje je defaultni html dokument za nginx servere. Taj dokument se nakon instalacije nalazi na slijedećoj putanji.
/usr/share/nginx/www
To je defaultna putanja s koje nginx poslužuje dokumente te se nakon instalacije u tom direktoriju nalaze samo datoteke
50x.html index.html
Još jedna stvar koju možemo napraviti je postaviti da se nginx pokreće skupa s računalom, tj. da ga ne moramo svaki put ručno pokretati.
sudo update-rc.d nginx defaults
Ukoliko je to već automatski postavljeno, naredba nam odgovara da je nginx već postavljen da se pokreće na startupu.
System start/stop links for /etc/init.d/nginx already exist.
Konfiguracija PHP-a na nginxu
Nakon instalacije nginxa smo u mogućnosti samo posluživati html datoteke te na taj način imati web stranice koje bi se sastojale samo od html dokumenata. Međutim, u većini slučajeva nam html i statičke web stranice nisu dovoljni te bi htjeli iskoristiti i neke programske jezike da kreiramo dinamičke web aplikacije. Jedan od najpoznatijih i najviše korištenih programskih jezika za kreiranje web aplikacija je zasigurno PHP. Konfiguracija PHP-a na nginx-u zahtjeva određene promjene defaultnih postavki kao i instalaciju dodatnog softwarea.
CGI i FastCGI
Kratica CGI označava Common Gateway Interface, sučelje koje specificira način prijenosa informacija između CGI programa i web servera. Pod CGI programom smatramo svaki program koji je dizajniran na način da prihvaća i vraća podatke prema CGI specifikacijama. Takav program može biti napisan u bilo kojem programskom jeziku kao npr. C, Perl, Java i sl. Korištenje CGI programa je jedan od najkorištenijih načina dinamičke komunikacije web servera i korisnika. HTML stranice koje imaju web forme u većini slučajeva komuniciraju s CGI programima koji obrađuju proslijeđene podatke. Međutim, CGI ima nekoliko nedostataka. Svakim zahtjevom prema web serveru i pozivanjem nove komande kreira se novi proces na serveru. Pokretanje procesa može biti vremenski i memorijski zahtjevno pogotovo u slučajevima kada program (skripta) još treba biti kompajliran ili interpretiran. Ukoliko se poveća broj zahtjeva, web server bi mogao biti preplavljen njima i moglo bi doći do pada sustava što nam svakako nije u cilju. Jedan od načina ublažavanja ovog problema je korištenje tzv. FastCGI-a. FastCGI je, kao što sam naziv i kaže, implementacija CGI-a koja je - brža. FastCGI uključuje određene dodatne funkcionalnosti koje CGI nema. Neke od osnovnih osobina FastCGI-ja su:
- neovisan je o programskom jeziku
- kao i CGi, FastCGI pokreće aplikacije u procesima koji su izolirani od jezgre web servera. To osigurava veću sigurnost web servera.
- umjesto kreiranja novog procesa za svaki zahtjev prema web serveru, FastCGI koristi perzistentne procese za rukovanje nizom zahtjeva. Znači da će jedan proces obavljati više zahtjeva, a neće se za svaki zahtjev stvarati novi proces. Na taj način se štedi na vremenu ali i memoriji. Bitno je napomenuti da se ti procesi obavljaju na FastCGI serveru, a ne web serveru. Dakle, pokretanje i odvijanje programa (skripti) se odvija na FastCGI serveru.
Instalacija i podešavanje PHP-a
Upravo iz tog razloga, te kako bi uspješno postavili i konfigurirali PHP na nginx, koristiti ćemo PHP-FPM (PHP FastCGI Process Manager). To je jedna od PHP FastCGI implementacija i njena instalacija na ubuntu sustavu je jednostavna:
sudo apt-get install php5-fpm
PHP-FPM je daemon proces koji pokreće FastCGI server na portu 9000. Nakon što smo uspješno instalirali i pokrenuli FastCGI server, potrebno je dodati virtualni host. Za ovaj primjer ćemo pokrenuti jednog na lokalnom računalu, tj. na localhost-u. Podešavanje virtualnih hostova se obavlja na slijedećoj putanji:
etc/nginx/sites-available/
U tom direktoriju se nalazi datoteka
default
koja u sebi sadrži osnovnu konfiguraciju virtualnih hostova. Ta datoteka izgleda ovako (direktive objašnjene u komentarima u kodu):
# You may add here your # server { # ... # } # statements for each of your virtual hosts to this file ## # You should look at the following URL's in order to grasp a solid understanding # of Nginx configuration files in order to fully unleash the power of Nginx. # http://wiki.nginx.org/Pitfalls # http://wiki.nginx.org/QuickStart # http://wiki.nginx.org/Configuration # # Generally, you will want to move this file somewhere, and start with a clean # file but keep this around for reference. Or just disable in sites-enabled. # # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. ## #definicija virtualnog hosta (servera) se radi unutar server namespace-a. Unutar svakog namespace-a se nalaze direktive. Direktive su uglavnom u obliku: naziv vrijednost [vrijednost2, vrijednost3]; Objašnjenje većine direktiva će biti učinjeno kroz komentare u kodu. server { #direktive za postavljanje porta na kojemu će server osluškivati zahtjeve #postoji direktiva za IPv4 kao i za IPv6 #listen 80; ## listen for ipv4; this line is default and implied #listen [::]:80 default ipv6only=on; ## listen for ipv6 # postavljanje foldera u kojem se nalazi sadržaj kojem klijenti mogu pristupati root /usr/share/nginx/www; # postavlja defaultni file koji će biti poslužen na zahtjev ukoliko se zahtjevom zatraži folder # može imati više datoteka. Ukoliko prva nije dostupna, server će pokušati pronaći drugu. index index.html index.htm; # postavljanje naziva servera. Način na koji ova direktiva radi je slijedeći: # nakon što se dobije HTTP zahtjev na serveru, pregledava se host header u zahtjevu. # zatim se dolazi do ove datoteke i pregledava se svaki server {} namespace. Kao odgovor se vraća prvi pronađeni # server (host). Na taj način i rade virtualni hostovi. server_name localhost; # omogućava postavljanje različitih konfiguracija ovisno o URL-u koji je poslan kao zahtjev # za pregled URL-a može se koristiti regex ili obični stringovi # primjer konfiguracije koja se obavlja nakon poziva linka u obliku # http://localhost/file.html location / { # First attempt to serve request as file, then # as directory, then fall back to index.html try_files $uri $uri/ /index.html; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } # primjer konfiguracije koja se obavlja nakon poziva linka u obliku # http://localhost/doc/file.html location /doc/ { alias /usr/share/doc/; autoindex on; allow 127.0.0.1; deny all; } # Samo za nginx-naxsi (Nginx Anti Xss & Sql Injection) # To je third party module za nginx koji provjerava dolazeće linkove u potrazi za mogućim # XSS ili SQL injection napadima. Ukoliko pronađe dijelove URL-a koji to ne bi smjeli biti ( '<', '|' ili 'drop') # ovdje se može definirati što bi se trebalo vratiti korisniku #location /RequestDenied { # For example, return an error code #return 418; #} # ova direktiva definira koja stranica će se prikazati korisniku ukoliko dođe do greške #error_page 404 /404.html; #error_page 500 502 503 504 /50x.html; # definira se lokacija za stranicu 50x.html. Ona se defaultno nalazi u www/ folderu i služi za prikaz # problema koji se dogodio prilikom obavljanja zahtjeva # ovm direktivom se definira gdje se nalazi ta stranica #location = /50x.html { # root /usr/share/nginx/www; #} # definiranje PHP postavki, tj. načina na koji će se pretraživati .php datoteke #location ~ \.php$ { # # definira se izgled php datoteka iz url-a uz pomoć regexa # fastcgi_split_path_info ^(.+\.php)(/.+)$; # # osim toga, potrebno je definirati i adresu FastCGI servera te broj porta na kojemu on očekuje zahtjeve # fastcgi_pass 127.0.0.1:9000; # # po defaultu je odabrana adresa i broj porta FastCGI-ja međutim moguće je i ručno postaviti da # # se koristi i unix socket. Korištenje unix socketa je nešto brže jer se ne koristi TCP overhead. # fastcgi_pass unix:/var/run/php5-fpm.sock; # # definira se početna stranica # fastcgi_index index.php; # include fastcgi_params; #} # onemogućava se pristu .htaccess fajlovima #location ~ /\.ht { # deny all; #} } # primjer još jednog virtualnog hosta #server { # broj porta na kojemu se osluškuje # listen 8000; # host # listen somename:8080; # naziv servera i njegov alias # server_name somename alias another.alias; # definira root dokument za prikaz # root html; # definira početne stranice koje se poslužuju u slučaju da zahtjev nema naziv dokumenta kojeg traži # index index.html index.htm; # #definiranje lokacije # location / { # try_files $uri $uri/ /index.html; # } #} # HTTPS server # primjer definicije HTTPS servera #server { # listen 443; # server_name localhost; # # root html; # index index.html index.htm; # # korištenje ssl-a # ssl on; # # definiranje dokumenta koji predstavlja certifikat # ssl_certificate cert.pem; # # definiranje dokumenta koji predstavlja ključ certifikata # ssl_certificate_key cert.key; # #definiranje timeouta za sesiju na web stranici # ssl_session_timeout 5m; # # definiranje verzija SSL i TLS protokola koje se koriste # ssl_protocols SSLv3 TLSv1; # # definiranje algoritama koji su omogućeni za autentikaciju i sl. # ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; # # definira da su algoritmi (cipher_suite) koji se nalazi na serveruispred onih definiranih na klijentskoj strani # ssl_prefer_server_ciphers on; # #definiranje lokacije # location / { # try_files $uri $uri/ /index.html; # } #}
Ova datoteka služi za konfiguriranje virtualnih hostova. Novi hostovi se dodaju, kao što je to opisano u komentaru unutar odjeljka
server { ... }
inače, ova datoteka je jako dobro dokumentirana i lako je prepoznati što koja linija koda radi te kako ju je moguće konfigurirati da radi ono što želimo. Također, dani su nam i neki linkovi koji prikazuju neke standardne konfiguracije koje su dobre za početnike koji se ne žele malo više pozabaviti konfiguracijom. Trenutna konfiguracija nam omogućuje da samo poslužujemo standardni html, tj. početnu nginx stranicu koju smo vidjeli ranije. Za dinamičko posluživanje stranica uz pomoć PHP-a potrebno je napraviti određene promjene u ovoj konfiguraciji. Promjene su slijedeće: kao prvo, potrebno je odkomentirati slijedeće linije:
listen 80; ## listen for ipv4; this line is default and implied listen [::]:80 default ipv6only=on; ## listen for ipv6
kojima se nginx postavlja da osluškuje na portu 80 (HTTP port) i to za IPv4 i Ipv6. Nakon toga mijenjamo index polje kojemu dodajemo jos jedan oblik indeksne datoteke
index.php
dok root ostavljamo isti. Kao root je definiran folder u kojem se nalazi sadržaj kojem klijenti mogu pristupati. Lokacija je:
root /usr/share/nginx/www;
I naposlijetku najvažniji dio, konfiguriranje PHP-a. Nginx u svojem config fajlu za virtualne hostove ima direktivu koja upravlja php instalacijom. Nju jepotrebno promijeniti na slijedeći način kako bismo omogućili rad s PHP-om na našoj web stranici (na nginx-u):
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # With php5-cgi alone: fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; }
Omogućili smo pokretanje PHP skripti te smo stavili putanju do FastCGI servera. Kao što je ranije napomenuto, taj server radi kao daemon proces na lokalnom hostu na portu 9000. Upravo tu konfiguraciju smo naveli i ovdje. Nakon što je sve konfigurirano, potrebno je restartati nginx server. To se radi slijedećom naredbom:
sudo ./etc/init.d/nginx reload Reloading nginx configuration: nginx.
U root folderu koji smo naveli ranije sada je moguće kreirati PHP skripte i na taj način razvijati dinamičke web stranice. Kao primjer napraviti ćemo jednostavnu PHP skriptu koja pokazuje informacije o PHP-u koji je instaliran na računalu. Skripta je slijedeća:
<?php phpinfo(); ?>
Pokretanjem stranice na lokalnom hostu localhost/index.php učitava nam se standardni ekran sa informacijama o php verziji instaliranoj na računalu. Također, u polju Server API možemo vidjeti da se aplikacija izvodi uz pomoć FPM/FastCGI kojeg smo installirali ranije.
Sigurnost (najbolja praksa)
Config fileovi i portovi
- /usr/local/nginx/conf/ - konfiguracijski direktorij nginx servera u koje se nalazu konfiguracijska datoteka pod nazivom nginx.conf
- /usr/local/nginx/html/ - lokacija na kojoj se nalaze dokumenti
- /usr/local/nginx/logs/ - lokacija na kojoj se nalazi log dokument
- HTTP port: TCP 80
- HTTPS port: TCP 443
Testiranje promjena u konfiguraciji nginx-a se provodi na sljedeći način:
# /usr/local/nginx/sbin/nginx -t
Primjer izvođenja:
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok configuration file /usr/local/nginx/conf/nginx.conf test is successful
Za učitavanje konfiguracijskih promjena koristimo:
# /usr/local/nginx/sbin/nginx -s reload
Za zaustavljanje servera:
# /usr/local/nginx/sbin/nginx -s stop
SELinux
Security-Enhanced Linux (SELinux) je dodatak za Linux kernel koji pruža mehanizme za podršku za sigurnosne politike kontrole pristupa i time sprječavaju mnoge napade na sustav.
Boolean zaključavanje Pokrenite getsebool –a naredbu i zaključajte sustav:
getsebool -a | less getsebool -a | grep off getsebool -a | grep o
Da bi osigurali sustav, pogledajte postavke koje su postavljene na 'on' te ih promijenite u 'off' ako vam nisu potrebne koristeći getsebool naredbu. Pravilnim postavljanjem boolean vrijednosti SELinux-a osigurava se održavanje funkcionalnosti i zaštite.
Minimalne privilegije preko Mount opcija
Posluživanje svih web stranica / html / php fileova preko odvojenih particija. Na primjer, kreirajte particiju pod /dev/sda5 i mountajte /nginx sa sljedećim dozvolama: noexec, nodev, nosetuid. Ovako bi mogao izgledati /etc/fstab za mountanje /nginx-a:
LABEL=/nginx /nginx ext3 defaults,nosuid,noexec,nodev 1 2
(Potrebno je kreirati novu particiju s fdisk i mkfs.ext3 naredbama)
Linux /etx/sysctl.conf Hardening
Kontrola i konfiguracija Linux kernela i mrežnih postavki se može podesiti pomoću /etc/sysctl.conf filea.
# Avoid a smurf attack net.ipv4.icmp_echo_ignore_broadcasts = 1 # Turn on protection for bad icmp error messages net.ipv4.icmp_ignore_bogus_error_responses = 1 # Turn on syncookies for SYN flood attack protection net.ipv4.tcp_syncookies = 1 # Turn on and log spoofed, source routed, and redirect packets net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 # No source routed packets here net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 # Turn on reverse path filtering net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # Make sure no one can alter the routing tables net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 # Don't act as a router net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Turn on execshild kernel.exec-shield = 1 kernel.randomize_va_space = 1 # Tuen IPv6 net.ipv6.conf.default.router_solicitations = 0 net.ipv6.conf.default.accept_ra_rtr_pref = 0 net.ipv6.conf.default.accept_ra_pinfo = 0 net.ipv6.conf.default.accept_ra_defrtr = 0 net.ipv6.conf.default.autoconf = 0 net.ipv6.conf.default.dad_transmits = 0 net.ipv6.conf.default.max_addresses = 1 # Optimization for port usefor LBs # Increase system file descriptor limit fs.file-max = 65535 # Allow for more PIDs (to reduce rollover problems); may break some programs 32768 kernel.pid_max = 65536 # Increase system IP port limits net.ipv4.ip_local_port_range = 2000 65000 # Increase TCP max buffer size setable using setsockopt() net.ipv4.tcp_rmem = 4096 87380 8388608 net.ipv4.tcp_wmem = 4096 87380 8388608 # Increase Linux auto tuning TCP buffer limits # min, default, and max number of bytes to use # set max to at least 4MB, or higher if you use very high BDP paths # Tcp Windows etc net.core.rmem_max = 8388608 net.core.wmem_max = 8388608 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_window_scaling = 1
Micanje svih neželjenih nginx modula
Želimo minimalizirati broj modula koji su kompilirani direktno u nginx binary. Smanjivanjem mogućnosti koje su dozvoljene na web serveru smanjujemo i rizik. Možemo konfigurirati i instalirati nginx koristeći samo potrebne module. Ukoliko želimo onemogućiti SSI i autoindx module, upisati ćemo sljedeće:
# ./configure --without-http_autoindex_module --without-http_ssi_module # make # make install
Sljedeća naredba omogućava pregled modula koji mogu biti uključeni/isključeni prilikom kompiliranja nginx-a:
# ./configure --help | less
Onemogućite nginx module koji vam nisu potrebni.
(Opcionalno) promjena nginx Version Header-a Uredite src/http/ngx_http_header_filter_module.c:
# vi +48 src/http/ngx_http_header_filter_module.c
Pronađite linije:
static char ngx_http_server_string[] = "Server: nginx" CRLF; static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
te ih proizvoljno promijenite, npr:
static char ngx_http_server_string[] = "Server: Ninja Web Server" CRLF; static char ngx_http_server_full_string[] = "Server: Ninja Web Server" CRLF;
Spremite i zatvorite file, te nakon toga kompilirajte server. Dodajte sljedeće u nginx.conf kako bi ugasili prikaz nginx verzije na svima automatski generiranim error stranicama.
server_tokens off
Instalacija SELinux Policy za zaštitu nginx webservera
SELinux s početnim postavkama neće zaštititi nginx web server, no moguće je instalirati i kompilirati zaštitu na sljedeći način: Najprije instalirajte:
# yum -y install selinux-policy-targeted selinux-policy-devel
Skinite ciljane SELinux politike za zaštitu nginx webservera na Linux server s početne stranice projekta:
# cd /opt # wget 'http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc'
Otpakirajte skinuti file:
# tar -zxvf se-ngix_1_0_10.tar.gz
Kompilirajte isti:
# cd se-ngix_1_0_10/nginx # make
Primjer outputa:
Compiling targeted nginx module /usr/bin/checkmodule: loading policy configuration from tmp/nginx.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 6) to tmp/nginx.mod Creating targeted nginx.pp policy package rm tmp/nginx.mod.fc tmp/nginx.mod
Instalirajte kreirani nginx.pp SELinux modul:
# /usr/sbin/semodule -i nginx.pp
Restriktivan firewall temeljen na iptables-ima
Sljedeća firewall skripta blokira sve i dopušta samo:
- Dolazne HTTP (TCP port 80) zahtjeve
- Dolazne ICMP ping zahtjeve
- Odlazne ntp (port 123) zahtjeve
- Odlazne smtp (TCP port 25) zahtjeve
#!/bin/bash IPT="/sbin/iptables" #### IPS ###### # Get server public ip SERVER_IP=$(ifconfig eth0 | grep 'inet addr:' | awk -F'inet addr:' '{ print $2}' | awk '{ print $1}') LB1_IP="204.54.1.1" LB2_IP="204.54.1.2" # Do some smart logic so that we can use damm script on LB2 too OTHER_LB="" SERVER_IP="" [[ "$SERVER_IP" == "$LB1_IP" ]] && OTHER_LB="$LB2_IP" || OTHER_LB="$LB1_IP" [[ "$OTHER_LB" == "$LB2_IP" ]] && OPP_LB="$LB1_IP" || OPP_LB="$LB2_IP" ### IPs ### PUB_SSH_ONLY="122.xx.yy.zz/29" #### FILES ##### BLOCKED_IP_TDB=/root/.fw/blocked.ip.txt SPOOFIP="127.0.0.0/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 169.254.0.0/16 0.0.0.0/8 240.0.0.0/4 255.255.255.255/32 168.254.0.0/16 224.0.0.0/4 240.0.0.0/5 248.0.0.0/5 192.0.2.0/24" BADIPS=$( [[ -f ${BLOCKED_IP_TDB} ]] && egrep -v "^#|^$" ${BLOCKED_IP_TDB}) ### Interfaces ### PUB_IF="eth0" # public interface LO_IF="lo" # loopback VPN_IF="eth1" # vpn / private net ### start firewall ### echo "Setting LB1 $(hostname) Firewall..." # DROP and close everything $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP # Unlimited lo access $IPT -A INPUT -i ${LO_IF} -j ACCEPT $IPT -A OUTPUT -o ${LO_IF} -j ACCEPT # Unlimited vpn / pnet access $IPT -A INPUT -i ${VPN_IF} -j ACCEPT $IPT -A OUTPUT -o ${VPN_IF} -j ACCEPT # Drop sync $IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP # Drop Fragments $IPT -A INPUT -i ${PUB_IF} -f -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP # Drop NULL packets $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " NULL Packets " $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # Drop XMAS $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " XMAS Packets " $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # Drop FIN packet scans $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " Fin Packets Scan " $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP # Log and get rid of broadcast / multicast and invalid $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type broadcast -j LOG --log-prefix " Broadcast " $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type broadcast -j DROP $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type multicast -j LOG --log-prefix " Multicast " $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type multicast -j DROP $IPT -A INPUT -i ${PUB_IF} -m state --state INVALID -j LOG --log-prefix " Invalid " $IPT -A INPUT -i ${PUB_IF} -m state --state INVALID -j DROP # Log and block spoofed ips $IPT -N spooflist for ipblock in $SPOOFIP do $IPT -A spooflist -i ${PUB_IF} -s $ipblock -j LOG --log-prefix " SPOOF List Block " $IPT -A spooflist -i ${PUB_IF} -s $ipblock -j DROP done $IPT -I INPUT -j spooflist $IPT -I OUTPUT -j spooflist $IPT -I FORWARD -j spooflist # Allow ssh only from selected public ips for ip in ${PUB_SSH_ONLY} do $IPT -A INPUT -i ${PUB_IF} -s ${ip} -p tcp -d ${SERVER_IP} --destination-port 22 -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -d ${ip} -p tcp -s ${SERVER_IP} --sport 22 -j ACCEPT done # allow incoming ICMP ping pong stuff $IPT -A INPUT -i ${PUB_IF} -p icmp --icmp-type 8 -s 0/0 -m state --state NEW,ESTABLISHED,RELATED -m limit --limit 30/sec -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -p icmp --icmp-type 0 -d 0/0 -m state --state ESTABLISHED,RELATED -j ACCEPT # allow incoming HTTP port 80 $IPT -A INPUT -i ${PUB_IF} -p tcp -s 0/0 --sport 1024:65535 --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -p tcp --sport 80 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT # allow outgoing ntp $IPT -A OUTPUT -o ${PUB_IF} -p udp --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p udp --sport 123 -m state --state ESTABLISHED -j ACCEPT # allow outgoing smtp $IPT -A OUTPUT -o ${PUB_IF} -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT ### add your other rules here #### ####################### # drop and log everything else $IPT -A INPUT -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " DEFAULT DROP " $IPT -A INPUT -j DROP exit 0
Kontrola Buffer Overflow napada
Uredite nginx.conf i postavite ograničenje veličine buffera za sve korisnike:
# vi /usr/local/nginx/conf/nginx.conf
Postavite sljedeće:
## Start: Size Limits & Buffer Overflows ## client_body_buffer_size 1K; client_header_buffer_size 1k; client_max_body_size 1k; large_client_header_buffers 2 1k; ## END: Size Limits & Buffer Overflows ##
Također je potrebo kontrolirati timeout za poboljšanje performansi servera:
## Start: Timeouts ## client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; ## End: Timeouts ##
Kontrola istovremenih konekcija
Koristiti ćemo NginxHttpLimitZone modul za ograničavanje broja istovremenih konekcija za određenu sesiju ili u posebnom slučaju s jedne IP adrese. Uredite nginx.conf:
### Directive describes the zone, in which the session states are stored i.e. store in slimits. ### ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ### limit_zone slimits $binary_remote_addr 5m; ### Control maximum number of simultaneous connections for one session i.e. ### ### restricts the amount of connections from a single ip address ### limit_conn slimits 5;
Gore navedena ograničenja će limitirati udaljene klijente na ne više od pet konkurentnih „otvorenih“ konekcija po IP adresi.
Dopuštanje pristupa samo vlastitoj domeni
Ukoliko bot skenira sve domene na nekom serveru, potrebno se je zaštiti. Moramo omogućiti samo konfigurirane virtualne domenske ili reverse proxy zahtjeve. Ne želimo prikazati zahtjeve koristeći IP adresu:
## Only requests to our Host are allowed i.e. nixcraft.in, images.nixcraft.in and www.nixcraft.in if ($host !~ ^(nixcraft.in|www.nixcraft.in|images.nixcraft.in)$ ) { return 444; } ##
Ograničenje dostupnih metoda
GET i POST su najpoznatije metode na Internetu. Ukoliko web server ne zahtjeva implementaciju svih ostalih dostupnih metoda, one bi trebale biti onemogućene. Sljedeći blok će filtrirati i omogućiti samo GET, HEAD i POST metode:
## Only allow these request methods ## if ($request_method !~ ^(GET|HEAD|POST)$ ) return 444; } ## Do not accept DELETE, SEARCH and other methods ##
Odbijanje pojedinih „User-Agent“-a
Blokiranje user-agenata kao što su skeneri, botovi i spameri koji bi iskorištavali server:
## Block download agents ## if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; } ##
Blokiranje msnbot i scrapbot robota:
## Block some robots ## if ($http_user_agent ~* msnbot|scrapbot) return 403; } ##
Blokiranje upućenog spama
Upućeni spam može biti opasan iz razloga što može narušiti rating web stranice preko web-logova (ukoliko su objavljeni) kao mjesto s kojega se preusmjerava na stranice sa spamom. Blokiranje pristupa spamerima se može realizirati pomoću:
## Deny certain Referers ### if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { # return 404; return 403; } ##
Zaustavljanje „Image Hotlinking“-a
Image ili HTML hotlinking znači da netko postavlja link do vaše stranice, odnosno do jedne od slika i prikazuje je na vlastitoj stranici. Rezultat toga je nepotrebno trošenje bandwitha, te će sadržaj izgledati kao dio otimačeve stranice. Ova tehnika se većinom koristi na forumima i blogovima. Preporuča se blokiranje i zaustavljanje hotlinkanja slika na razini servera.
# Stop deep linking or hot linking location /images/ { valid_referers none blocked www.example.com example.com; if ($invalid_referer) { return 403; } }
Primjer: prepisivanje i prikazivanje slike (link do bannane slike):
valid_referers blocked www.example.com example.com; if ($invalid_referer) { rewrite ^/images/uploads.*\.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last }
Restrikcije direktorija
Moguće je postaviti kontrolu pristupa određenom direktoriju. Svi web direktoriji bi trebali biti konfigurirani na „case-by-case“ bazi, dozvoljavajući pristup samo kada je to potrebno. Ograničenje pristupa po IP adresi Ograničavanje pristupa direktoriju /docs/directory po ip adresi:
location /docs/ { ## block one workstation deny 192.168.1.1; ## allow anyone in 192.168.1.0/24 allow 192.168.1.0/24; ## drop rest of the world deny all; }
Zaštita direktorija lozinkom
Najprije kreiramo file s lozinkom te dodajemo korisnika zvanog sisuser:
# mkdir /usr/local/nginx/conf/.htpasswd/ # htpasswd -c /usr/local/nginx/conf/.htpasswd/passwd sisuser
Uređujemo nginx.conf i zaštićujemo potrebne direktorije na sljedeći način:
### Password Protect /personal-images/ and /delta/ directories ### location ~ /(personal-images/.*|delta/.*) { auth_basic "Restricted"; auth_basic_user_file /usr/local/nginx/conf/.htpasswd/passwd; }
Jednom kada se generira file s lozinkom, naredni korisnici se mogu dodavati naredbom:
# htpasswd -s /usr/local/nginx/conf/.htpasswd/passwd userName
nginx SSL konfiguracija
HTTP je plain text protokol što ga čini otvorenim za pasivno praćenje, no tu dolazi SSL koji kriptira sadržaj za korisnike.
Kreiranje SSL certifikata:
# cd /usr/local/nginx/conf # openssl genrsa -des3 -out server.key 1024 # openssl req -new -key server.key -out server.csr # cp server.key server.key.org # openssl rsa -in server.key.org -out server.key # openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Uredite nginx.conf i ažurirajte na sljedeći način:
server { server_name example.com; listen 443; ssl on; ssl_certificate /usr/local/nginx/conf/server.crt; ssl_certificate_key /usr/local/nginx/conf/server.key; access_log /usr/local/nginx/logs/ssl.access.log; error_log /usr/local/nginx/logs/ssl.error.log; }
te naposljetku ponovno pokrenite nginx:
# /usr/local/nginx/sbin/nginx -s reload
Više o „NginxHttpSslModule“ modulu možete pročitati na: http://wiki.nginx.org/NginxHttpSslModule
nginx i PHP sigurnosni savjeti
PHP je jedan od poznatijih skriptnih jezika na strani poslužitelja.
Editirajte /etc/php.ini:
# Disallow dangerous functions disable_functions = phpinfo, system, mail, exec ## Try to limit resources ## # Maximum execution time of each script, in seconds max_execution_time = 30 # Maximum amount of time each script may spend parsing request data max_input_time = 60 # Maximum amount of memory a script may consume (8MB) memory_limit = 8M # Maximum size of POST data that PHP will accept. post_max_size = 8M # Whether to allow HTTP file uploads. file_uploads = Off # Maximum allowed size for uploaded files. upload_max_filesize = 2M # Do not expose PHP error messages to external users display_errors = Off # Turn on safe mode safe_mode = On # Only allow access to executables in isolated directory safe_mode_exec_dir = php-required-executables-path # Limit external access to PHP environment safe_mode_allowed_env_vars = PHP_ # Restrict PHP information leakage expose_php = Off # Log all errors log_errors = On # Do not register globals for input data register_globals = Off # Minimize allowable PHP post size post_max_size = 1K # Ensure PHP redirects appropriately cgi.force_redirect = 0 # Disallow uploading unless necessary file_uploads = Off # Enable SQL safe mode sql.safe_mode = On # Avoid Opening remote files allow_url_fopen = Off
nginx u Chroot Jail-u (kontejneru)
Ukoliko je moguće, postavite nginx u chroot jail, time se minimizira šteta kod potencijalnog upada u sustav, na način da se web server izolira na malom dijelu filesystema. Detaljnije upute se nalaze na: http://www.cyberciti.biz/faq/howto-run-nginx-in-a-chroot-jail/ . Ako je moguće koristiti FreeBSD jail, XEN, ili OpenVZ virtualizacije koje koriste koncept kontejnera.
Ograničavanje konekcija po IP-u na razini firewall-a
Web server mora pripaziti na konekcije i ograničiti njihov broj po sekundi, iptables može prigušiti broj krajnjih korisnika prije pristupanja nginx serveru.
Linux Iptables
Sljedeći primjer prikazuje kako će server dropati dolazne konekcije ukoliko s istog IP-a bude više od 15 pokušaja spajanja na port 80 unutar 60 sekundi:
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set /sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 15 -j DROP service iptables save
Sve vrijednosti podesite u ovisnosti o vašim potrebama i prometu, te imajte na umu da preglednik može otvoriti više veza prema vašoj stranici. Primjer Iptables firewall skripte može se naći na : http://bash.cyberciti.biz/firewall/linux-iptables-firewall-shell-script-for-standalone-server/ .
Konfiguriranje operacijskog sustava kako bi štitio web server
Uključiti SELinux kako je prethodno opisano, postaviti ispravne dozvole na korijen nginx dokumenta. nginx se izvodi kao korisnik imena nginx, no fileovi u korijenskom dokumentu (/nginx ili /usr/local/nginx/html) ne bi trebali biti u posjedu ili pisani od strane tog korisnika.
Za pronalazak fileova s krivim dozvolama, koristi se:
# find /nginx -user nginx # find /usr/local/nginx/html -user nginx
Promijenite vlasništvo filea na root ili nekog drugog korisnika. Tipični skup dozvola za /usr/local/nginx/html/:
# ls -l /usr/local/nginx/html/
Primjer outputa:
-rw-r--r-- 1 root root 925 Jan 3 00:50 error4xx.html -rw-r--r-- 1 root root 52 Jan 3 10:00 error5xx.html -rw-r--r-- 1 root root 134 Jan 3 00:52 index.html
Potrebo je obrisati neželjene backup fileove koje kreira vi ili neki drugi text editor:
# find /nginx -name '.?*' -not -name .ht* -or -name '*~' -or -name '*.bak*' -or -name '*.old*' # find /usr/local/nginx/html/ -name '.?*' -not -name .ht* -or -name '*~' -or -name '*.bak*' -or -name '*.old*'
Dodajte –delete opciju naredbi find za brisanje tih fileova.
Zabrana odlaznih nginx konekcija
Crackeri će pokušati skinuti file lokalno na server koristeći alate kao što je wget. Korištenjem iptable-sa moguće je blokirati odlazne konekcije nginx korisnika. ipt_owner modul će pokušati usporediti razne karakteristike kreatora paketa, za lokalno generirane pakete. Ovo vrijedi samo u izlaznom lancu (output chain).
U ovom primjeru dozvoliti ćemo korisniku sisuser da ostvari konekciju prema van koristeći port 80:
/sbin/iptables -A OUTPUT -o eth0 -m owner --uid-owner vivek -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
Dodajte gore navedeno pravilo u iptables shell skriptu. Ne dozvolite nginx web server korisniku da ostvaruje konekcija prema van.
PREPORUKA: Pratite logove Praćenjem log fileova može se doći do informacija koje mogu pomoći pri shvaćanju koji vrsta napada se pokušala izvesti na server i time omogućiti provjeru da li je realizirana određena (potrebna) razina zaštite.
# grep "/login.php??" /usr/local/nginx/logs/access_log # grep "...etc/passwd" /usr/local/nginx/logs/access_log # egrep -i "denied|error|warn" /usr/local/nginx/logs/error_log
Audit servis omogućava nadgledanje sustava, uključite ga za SELinux evente, autentifikacijske evente, izmjenu datoteka, izmjenu korisničkih računa, itd. Onemogućite sve servise te pratite preporuke s: http://www.cyberciti.biz/tips/linux-security.html .
Literatura
- Nginx HTTP Server - Clement Nedelcu; 2010.
- http://wiki.nginx.org/Main
- http://www.aosabook.org/en/nginx.html
- http://www.cyberciti.biz/tips/linux-unix-bsd-nginx-webserver-security.html
Podjela rada
- Luka Rajčević
- Uvod
- Karakteristike Nginx-a
- Reverse proxy
- Instalacija nginx-a
- Konfiguracija PHP-a na nginxu
- Davor Tomala
- Arhitektura
- Struktura koda
- Worker
- Uloge procesa
- Sigurnost (najbolja praksa)