BLOGS

Nginx PHP-FPM uzstādīšana un daži triki

Nginx logo

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


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.

Resursi internetā