Nginx PHP-FPM uzstādīšana un daži triki
Pēdējo gadu laikā Krievijas programētāja Igor Sysoev radītais Nginx (Engine X), kas nodrošina web servera/atgriezeniskā starpniekservera (reverse proxy) un IMAP/POP3 starpniekservera funkcionalitāti, ir kļuvis ievērojami populārs. Tīmeklī lasāmas neskaitāmas sajūsminātu cilvēku atsauksmes par Nginx lielisko darbību izturot lielu slodzi un ērto konfigurāciju. Tāpat Nginx taupīgāk lieto sistēmas resursus salīdzinājumā ar Apache.
Šinī rakstā apskatīsim, kā uzstādīt un nokonfigurēt Nginx (1.0.6) webserveri lietojot Ubuntu 10.04 LTS, kā arī dažas interesantas iespējas, ko Nginx mums piedāvā.
- Nginx uzstādīšana
- Kā pievienot jaunu virtuālo hostu
- PHP-FPM atbalsta pievienošana
- SSL atbalsta pievienošana
- Trafika samazināšana izmantojot Gzip
- Trafika samazināšana un lapas ielādes ātruma palielināšana izmantojot pārlūku pagaidu atmiņu (cache)
- Kā izveidot direktoriju ar paroles aizsardzību
- Kā atļaut piekļuvi lapai tikai no noteiktām IP adresēm
- Kā aizliegt pieeju slēptajie failiem un direktorijām
- Problēma ar neeksistējošu favicon.ico un/vai robots.txt
- Atļaut tikai GET, POST un HEAD pieprasijumus
- Kā aizliegt noteiktiem pārlūkiem apmeklēt lapu
- Neļaut noteiktus failus no jūsu servera izmantot citās lapās (hotlinking)
- Kā aizliegt apmeklēt lapu lietotājiem, kas sūta noteiktus referer paziņojumus
- Kā pārsūtīt visus lapas apmeklētājus uz www.domēns.lv vai otrādāk
- Wordpress SEO draudzīgie linki priekš Nginx rewrite
Nginx uzstādīšana
Pievienojam Nginx Launchpad paku repozitoriju, lai vienmēr būtu pieeja jaunākajām Nginx pakām. Failā /etc/apt/sources.list ierakstam šīs rindiņas.
deb http://ppa.launchpad.net/nginx/stable/ubuntu lucid main
deb-src http://ppa.launchpad.net/nginx/stable/ubuntu lucid main
Uzstādam Nginx no Ubuntu pakām izmantojot šīs komandas
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C
sudo apt-get update
sudo apt-get install nginx
Noklusēti uzstādot šo paku automātiski tiek pievienots startēšanas skripts, lai servera pārstartēšanas gadījumā Nginx tiktu automātiski palaists. Lai būtu pavisam droši, palaižam šo komandu.
sudo update-rc.d nginx defaults
Nginx konfigurācijas faili atrodas /etc/nginx direktorijā. Fails /etc/nginx/nginx.conf atbild par servera konfigurāciju. Direktorijā /etc/nginx/sites-available atrodas visu pieejamo lapu konfigurācijas faili, lai tos būtu ērtāk pārvaldīt. Lai kādu no šīm lapām aktivizētu priekš Nginx webservera, nepieciešamas izveidot linku (symlink) /etc/nginx/sites-enabled direktorija. To iespējams izdarīt palaižot šo komandu
sudo ln -s /etc/nginx/sites-available/lapas_konfigurācija.lv /etc/nginx/sites-enabled/lapas_konfiguracija.lv
Atveram failu /etc/nginx/nginx.conf, un sadaļā http pievienojam šīs rindas
http {
server_tokens off;
index index.php index.html index.htm;
client_max_body_size 50M;
...
}
server_tokens off norādā, lai webserveris nerāda precīzu versijas numuru, bet tikai nosaukumu. Respektīvi tikai nginx.
index norāda failus, kas noklusēti tiks servēti pieprasījumiem, kas nevaicās precīzus failus. Tradicionāli tie ir index.php/index.html/index.htm.
client_max_body_size norādā izmēru, cik lielus failus serveris pieņems no lietotāja. Šinī gadijumā 50 megabaitu lielu failu.
Pirmais patīkamais sīkums ir iespēja uzstādīt, lai tas neatbildētu pieprasījumiem, kas netiek sūtīti kādai uz servera izvietotajai lapai, bet pa taisno uz IP adresi. Šis ir ērts veids, kā tikt vaļā no neskaitāmiem web robotiem, kuri meklē web ievainojamības skanējot IP adrešu apgabalus. Lai to izdarītu atveram failu /etc/nginx/sites-available/default un izlabojam noklusētā servera ierakstu šādi
server {
listen 80 default_server;
server_name _;
return 444;
}
Šis ieraksts liks Nginx neatbildēt neatpazītiem pieprasijumiem atgriežot 444 kļūdas paziņojumu.
Kā pievienot jaunu virtuālo hostu
Izveidojam jaunu konfigurācijas failu adresei testalapa.lv iekš /etc/nginx/sites-available/testalapa.lv
server {
listen 80;
server_name testalapa.lv www.testalapa.lv;
root /srv/testalapa.lv;
access_log /var/log/nginx/testalapa_lv_access;
error_log /var/log/nginx/testalapa_lv_error;
}
listen direktīva norāda, ka lapa tiks servēta pieprasījumiem uz visām webserverim pieejamajām IP adresēm.
server_name direktīva norāda, uz kādiem domēniem sūtītiem pieprasījumiem atbildēt, šinī gadījumā testalapa.lv un www.testalapa.lv.
root norāda, kur uz servera tiek glabāti attiecīgās lapas faili.
access_log un error_log norāda, kur glabāt lapas apmeklējumu un kļūdu ierakstus.
Izveidojam linku uz sites-enabled direktoriju ar komandu
sudo ln -s /etc/nginx/sites-available/testalapa.lv /etc/nginx/sites-enabled/testalapa.lv
Un pārlādējam Nginx konfigurāciju
/etc/init.d/nginx reload
PHP-FPM atbalsta pievienošana
Nākamais solis ir pievienot PHP atbalstu. Tam izmantosim PHP-FPM (PHP FastCGI Process Manager) metodi, kas tika radīta kā aizstājējs SpawnCGI. PHP-FPM piedāvā vairāk iespējas un darbojas stabilāk. Sākot no PHP 5.3.3 versijas, FPM atbalts ir iekļauts PHP kodā. Iepriekšējām versijām izejas kodu bija nepieciešams pačot. Lai dabūtu jaunākās PHP 5.3.x pakas, atveram failu /etc/apt/sources.list, un pievienojam šīs rindas ar Launchpad repozitorija adresi.
deb http://ppa.launchpad.net/nginx/php5/ubuntu lucid main
deb-src http://ppa.launchpad.net/nginx/php5/ubuntu lucid main
Uzstādam PHP pakas ar šīm komandām
sudo apt-get update
sudo apt-get install php5-fpm php5-mysql php5-gd php-apc
Tad atveram lapas konfigfigurācijas failu, šinī gadījumā /etc/nginx/sites-available/testalapa.lv un pievienojam šīs rindas
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_intercept_errors on;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location /404.html {
internal;
}
location /50x.html {
internal;
}
Pārlādējam Nginx
/etc/init.d/nginx reload
Lai Nginx atbildētu lapas apmeklētājam ar kļūdas paziņojumu, fastcgi konfigurācijas gadījumā ir jānodefinē lapas atrašanās vietu, kas satur kļūdas paziņojumu. Pretējā gadījumā tiks atgriezta balta lapa. Ierakstam šīs rindas server sadaļā lapai, kurai uzstādīts fastcgi.
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
Šīs papildus rindas atļaus piekļūt kļūdu paziņojumu lapām tikai webserverim.
location /404.html {
internal;
}
location /50x.html {
internal;
}
SSL atbalsta pievienošana
Pirmkārt veidojam ierakstu noklusētajam serverim. Norādot, ka visi pieprasījumi uz IP adresi tiks ignorēti. Šī metode ar vairākiem SSL sertifikātiem uz vienas IP adreses strādā ar jaunākajiem pārlūkiem, kas atbalsta SNI (Server Name Indication).
Atveram /etc/nginx/sites-available/default un pašā apakšā ierakstām šīs rindas
server {
listen 443;
server_name _;
ssl on;
ssl_certificate /etc/nginx/tmp.crt;
ssl_certificate_key /etc/nginx/tmp.key;
return 444;
}
Uzģenerējam atslēgu un sertifikātu šim noklusētajam serverim ar komandām
openssl genrsa -out /etc/nginx/tmp.key 1024
openssl req -new -key /etc/nginx/tmp.key -out /tmp/tmp.csr
openssl x509 -req -days 1825 -in /tmp/tmp.csr -signkey /etc/nginx/tmp.key -out /etc/nginx/tmp.crt
Tālāk atveram konfigurācijas failu lapai, kurai vēlamies pievienot SSL atbalstu. Šinī gadījumā /etc/nginx/sites-available/testalapa.lv un veicam šādus ierakstus.
server {
listen 443;
server_name testalapa.lv;
ssl on;
ssl_certificate /etc/nginx/testalapa.crt;
ssl_certificate_key /etc/nginx/testalapa.key;
root /srv/testalapa.lv;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/testalapa_lv_ssl_access;
error_log /var/log/nginx/testalapa_lv_ssl_error;
}
Ja izmantosim pašparakstītu SSL sertifikātu, tad uzģenerējam to ar šīm komandām.
openssl genrsa -out /etc/nginx/testalapa.key 2048
openssl req -new -key /etc/nginx/testalapa.key -out /tmp/tmp.csr
openssl x509 -req -days 1825 -in /tmp/tmp.csr -signkey /etc/nginx/testalapa.key -out /etc/nginx/testalapa.crt
Trafika samazināšana izmantojot Gzip
Liela daļa no katras weblapas satur HTML, Javascript, XML, vai vienkāršu tekstu. Lai ietaupītu informācijas apjomu, ko lejupielādē lapas apmeklētājs, šo saturu iespējams saspiest izmantojot Gzip. Tādejādi tiek samazināts lejupielādējamās informācijas apjoms. Satura saspiešana daudz nepalīdzēs dažādu attēlu vai mūzikas formātu failiem, jo tie noklusēti tiek veidoti paturot prātā kompresiju. Jāņem vērā, ka weblapas satura saspiešana patērēs nedaudz vairāk servera procesora resursus. Satura saspiešanu iespējams uzstādīt visam serverim, noteiktai lapai vai konkrētam direktorijam. Šinī gadījumā uzstādīsim visam serverim.
Atveram Nginx konfigurācijas failu /etc/nginx/nginx.conf, un atkomentējam vai ierakstam šādas direktīvas.
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip on ieslēdz saspiešanas iespēju.
gzip_disable "msie6" iespējams norādīt useragent, kuru gadījumā nelietot saspiešanu (Šinī gadijumā vecie IE pārlūki).
gzip_vary on pievieno servera atbildei Vary: Accept-Encoding tādejādi norādot apmeklētāja pārlūkam, ka ir iespēja datus lejupielādēt saspiestā veidā.
gzip_proxied any norāda kādus pieprasījumus saspiest, ja klients pie lapas slēdzās izmantojot starpniekserveri. Šinī gadījumā visus.
gzip_min_length norāda izmēru baitos, par kuru mazāki faili netiks saspiesti. Šinī gadijumā faili mazāki par 1kb netiks saspiesti.
gzip_comp_level 6 norāda saspiešanas līmeni. Tas iespējams no 1 (visvājākais) līdz 9 (vislielākais).
gzip_buffers 16 8k norāda cik daudz un kāda izmēra buferus nodot Nginx lietošanā, priekš pagaidu saspiesto datu glabāšanas. Šinī gadijumā 16 8kb lielus buferus.
gzip_http_version 1.1 norādā kādām HTTP pieprasījumu versijām piegādāt datus saspiestā veidā. Lielākais vairums web pārlūku lieto HTTP 1.1 kā noklusēto standartu.
gzip_types iespējams norādīt kādiem failu tipiem tiks piemērota saspiešana, pirms tie tieks padoti lapas apmeklētājām. Noklusēti tiek saspiests tikai html.
Trafika samazināšana un lapas ielādes ātruma palielināšana izmantojot pārlūku pagaidu atmiņu (cache)
Mūsdienu pārlūki visi kā viens uztur savu pagaidu atmiņu uz lietotāja cietā diska, kurā glabā bildes, html failus un daudz ko citu. Nākamreiz apmeklējot lapu, klienta pārlūks pārbauda, vai kāds no failiem, kas atrodas pagaidu atmiņā, ir mainījies uz servera. Izmantojot šo metodi, mēs varam norādīt serverim, lai izvēlētajiem failu tipiem papildus tiek sūtīta atbilde, cik ilgi tos var ielādēt no pārlūka pagaidu atmiņas. Šādas norādes var uzstādīt visam serverim, noteiktai lapai vai direktorijam. Šinī piemērā uzstādīsim norādes noteiktai lapai.
Atveram lapas konfigurācijas failu /etc/nginx/sites-available/testalapa.lv un pievienojam location direktīvu server sadaļā.
server {
....
location ~* \.(gif|jpg|jpeg|png)$ {
expires 30d;
access_log off;
}
}
location ~* norāda ka failu paplašinājumi var būt gan ar lielajiem, gan mazajiem burtiem. Ja nepieciešams norādīt precīzi (case sensitive), tad lietojam ~
expires 30d liek webserverim atbildēt uz norāditajiem pieprasijumiem ar papildus lauku, kurā norādīt, ka šis fails netiks mainīts 30 dienas.
access_log off norāda šo failu pieprasijumus nerakstīt logfailā.
Kā izveidot direktoriju ar paroles aizsardzību
Lapas konfigurācijas faila server sadaļā pievienojam šīs rindas.
location ^~ /slepens/ {
auth_basic "Slepens";
auth_basic_user_file /etc/nginx/testalapa_passwd;
}
Paroli var uzģenerēt ar htpasswd rīku (htpasswd -b htpass lietotājs parole), kas nāk līdzi Apache, vai kādu no daudzajiem tiešsaistes ģeneratoriem. Kad parole veiksmīgi uzģenerēta, ierakstam to failā, kas norādīts auth_basic_user_file direktīvā. Šinī gadījumā /etc/nginx/testalapa_passwd.
Kā atļaut piekļuvi lapai tikai no noteiktām IP adresēm
Lapas konfigurācijas faila server sadaļā pievienojam šīs rindas. x.x.x.x aizstājam ar IP adresi, kurai atļausim piekļuvi. Visiem pārējiem piekļuve būs liegta
location ^~ / {
allow x.x.x.x;
deny all;
}
Kā aizliegt pieeju slēptajiem failiem un direktorijām
Slēptie faili un direktoriji skaitās viss, kura nosaukums sākas ar ".". Tādi kā .htaccess, .svn un tamlīdzīgi. Lai aizliegtu tos aplūkot izmantojot weblapu pārlūku, atveram lapas konfigurācijas failu un server sadaļā pievienojam šīs rindas.
location ~ /\. {
deny all;
}
Problēma ar neeksistējošu favicon.ico un/vai robots.txt
Mūsdienās visi pārlūki noklusēti pieprasa favicon.ico, kas ir mazā lapas ikona weblapu pārlūka adrešu laukā. Savukārt robots.txt satur norādijumus meklētāju robotiem, kas regulāri pārlūko lapas un atjauno informāciju par to saturu dažādos meklētājos, kā, piemēram, Google. Ja lapai kāds no šiem failiem nav, tad servera logfaili tiek lieki piesārņoti ar ierakstiem, ka šie faili nav tikuši atrasti. Pastāv elegants risinājums šai miniproblēmai. Atveram lapas konfigurācijas failu un server sadaļā pievienojam šos ierakstus. Tie liks webserverim nerakstīt neveiksmīgos robots.txt un favicon.ico pieprasijums error logfailā.
location = /favicon.ico {
log_not_found off;
}
location = /robots.txt {
log_not_found off;
}
Atļaut tikai GET, POST un HEAD pieprasijumus
Atveram lapas konfigurācijas failu, un server sadaļā pievienojam šīs rindiņas.
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 444;
}
Kā aizliegt noteiktiem pārlūkiem apmeklēt lapu
Pievienojam šo direktīvu lapas konfigurācijas faila server sadaļā.
if ($http_user_agent ~* (python|php|libcurl|zmeu) ) {
return 444;
}
Visiem lapas apmeklētājiem, kuru pārlūkprogramas user-agent saturēs kādu no norādītajiem vārdiem, tiks aizvērta konekcija bez paskaidrojumiem.
Neļaut noteiktus failus no jūsu servera izmantot citās lapās (hotlinking)
Dažreiz gadās, ka citās lapās ieliek failus, kas glabājas uz jūsu servera. Ja vien neesam to atļāvuši, tad tas var kļūt diezgan kaitinoši. Visbiežāk tas gadās ar attēliem. Tādejādi tiek tērēts jūsu trafiks un noslogots serveris pašu lapu neapmeklējot. Visvieglākais risinājums ir filtrēt pieprasijumus pēc referer rindiņas. Visi pieprasijumi kas nākuši no jūsu lapas saturēs rindiņu ar iepriekšējās lapas adresi (referer). Ja pieprasītais fails tika pieprasīts no citas lapas, tad arī referer būs no svešās lapas un atļaus efektīvi atfiltrēt šādus pieprasījumus. Atveram lapas konfigurācijas failu un server sadaļā ierakstam šīs rindas.
location ~ \.(jpg|png|gif|jpeg)$ {
valid_referers server_names none;
if ($invalid_referer) {
return 403;
}
}
valid_referers rindiņa šajā variantā atļauj bildēm pieklūt apmeklētājiem, kuru referer saturēs adresi, kas norādītas kā virtualā servera adreses. Šinī gadījumā testalapa.lv un www.testalapa.lv (server_names), kā arī tukšu referer lauku (none).
Kā aizliegt apmeklēt lapu lietotājiem, kas sūta noteiktus referer paziņojumus
Viens no spameru trikiem ir veidot pieprasijumus web lapai, norādot ka viņi nākuši no kādas lapas. Kad lapas īpašnieks skatoties apmeklētāju statistiku pamana, ka daudzi apmeklētāji nākuši no kādas nezināmas lapas, tad ziņkāres vadīts iet to aplūkot. Un spameris iegūst papildus apmeklējumu savai lapai. To var labot lapas konfigurācijas faila server sadaļā pievienojot šīs rindas.
if ($http_referer ~* (dating|poker) ) {
return 444;
}
Tādejādi visiem apmeklētājiem, kuru sūtītais referer saturēs dating vai poker, webserveris atbildēs ar neko.
Kā pārsūtīt visus lapas apmeklētājus uz www.domēns.lv vai otrādāk
Atveram vajadzīgās lapas konfigurācijas failu un server sadaļā ierakstam šīs rindas. Ja domēnam pastāv arī subdomēni, tad (www) pārveidojam šādi (www|subdomens).
if ($host !~* ^(www)) {
rewrite ^/(.*)$ $scheme://www.$host/$1 permanent;
}
Ja vēlamies visus apmeklētājus pārsūtīt uz domens.lv adresi, tad veicam šādu ierakstu.
if ($host ~* ^www\.(.*)) {
set $host_without_www $1;
rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
}
Wordpress SEO draudzīgie linki priekš Nginx rewrite
Par cik šis ir ļoti izplatīts emuāru dzinējs, tad iekļāvām šo problēmu rakstā. Par cik Nginx neatbalsta .htaccess failus, un rewrite noteikumi ir nedaudz savādāki. Lai ieslēgtu SEO draudzīgos linkus, atveram lapas konfigurācijas failu un server sadaļā pievienojam šīs rindiņas.
location / {
try_files $uri $uri/ /index.php?$args;
}
Tās norādīs Nginx sākumā meklēt failu vai failu/ un neatrašanas gadījumā pārsūtīt pieprasījumu uz index.php.