nustatymų yra daug, kurie ne tik leidžia sistemai būti lanksčiai, bet ir dažnai priverčia pasimesti programuotojus ar administratorius, juolab, kad nebūtinai default reikšmė yra geriausia ar saugiausia, taigi tęsiame kelionę po nustatymus.

Apribokime sistemos resursus
max_execution_time, standartiškai yra nustatytas 30 (sekundžių). Tai reiškia, kad skriptui bus leista naudotis procesoriumi iki 30 sekundžių vieno paleidimo metu. Šis nustatymas yra naudingas hostingo paslaugų teikėjams, kadangi apsaugo nuo piktai nusiteikusių vartotojų, norinčių pakenkti, taip pat ir dedicated serveriams - apsisaugoti nuo kreivai parašytų savų ar trečios šalies skriptų. Dažnai šis nustatymas yra interpretuojamas klaidingai - “skriptas negali suktis ilgiau nei 30 sekundžių“. Iš tiesų, gali. Laikas skaičiuojamas tik tada, kai skriptas naudoja CPU, nors veikti skriptas gali valandų valandas. Pavyzdžiui:

while (true)
{
sleep(100);
}

Toks skriptas naudoja itin mažai CPU, todėl miegodamas gali veikti net ir ištisą mėnesį. Jeigu serveryje naudojate tik web puslapius, protinga apriboti šį nustatymą į kur kas mažesnę reikšmę, pvz., 5. Jei puslapis serveryje generuojamas ilgiau nei 1 sekundę, tai jau laikoma ilgai. Kuo mažesniu laiku jį apribosim, tuo daugiau laiko liks kitoms užduotims. Šį nustatymą galima keisti ir skripto išorėje, ir viduje, su set_time_limit() funkcija.
max_input_time yra skirtas nustatyti, kiek laiko skirti vartotojo įvedimui. Jis default’u būna 60 sekundžių. Taip pat, kaip ir vykdymo nustatymas, jis įskaičiuoja tik tą laiką, kurį naudoja CPU savo skaičiavimams. Didelio failo upload’o laukimas nepaveiks šio limito. Šis nustatymas skirtas apsisaugoti nuo daugiamačių masyvų perdavimo, kurie gali itin paveikti sistemos resursus. Nepaisant to, 60 sekundžių yra ryškiai per daug, joks skriptas neturėtų švaistyti tiek daug savo laiko vartotojo įvedimui apdirbti. Nustatymą siūloma apriboti iki 2-5 sek. Šis nustatymas gali būti keičiamas tik skripto išorėje, kadangi vartotojo įvedimas apdirbamas dar prieš skripto pradžią.
Memory_limit - dar vienas nustatymas, apribojantis sistemos skiriamą atmintį. Šis nustatymas yra prieinamas tik tuo atveju, jei sukompiliuotas su atminties ribojimo palaikymu. Lengvai tai patikrinsite, kadangi memory_get_usage funkcija prieinama tik jei atminties ribojimas yra :

if (function_exists('memory_get_usage'))    echo 'Ok!';
else 'Ne Ok!'

Atminties limitas yra default’u nustatytas iki 8MB. Šis nustatymas dauguma atvejų yra tinkamas ir paprastai nereikia jo keisti. Sistemai pakenkti gali būti naudojami skriptai, pasiimantys didelę dalį atminties ir nueinantys miegoti. Pavyzdžiui:

$a = str_repeat('a', 100000000);
ignore_user_abort(true);
sleep(1000000);

Šis skriptas bando nugriebti ~100MB atminties ir nueiti miegoti, ignoruodamas vartotojo veiksmus, t. y. net jei uždaroma naršyklė, jis ir toliau būna vykdomas. Memory_limit neišsprendžia problemos iki galo, kadangi su tokiu skriptu galima paleisti kelias jo instancijas, kurių kiekviena pasiims maksimalų atminties kiekį. Be abejo, tokie įvykiai negali praeiti nepastebėti sistemos administratorių, taigi problemą anksčiau ar vėliau reikia išspręsti. Kitiems atvejams, kai kenkia ne žmogus, o kreivai parašytas skriptas, arba, pavyzdžiui, siunčiamas didelis duomenų kiekis iš išorinio šaltinio, tai, be abejo, yra naudingas nustatymas.
Default_socket_timeout - leidžia apriboti laiką, skirtą inicijuoti sujungimui. Default’u ši reikšmė yra 60 sekundžių. Dažnai sistema, atidarydama socketą praleidžia daug laiko prisijungdama prie lėtų serverių, todėl kenkėjas gali efektyviai išnaudoti sistemos resursus, atidaręs keletą tokių prisijungimų. Kol sistema eikvos laiką beprasmiams sujungimams, neliks resursų tikrų vartotojų užklausoms. Reikia atminti, kad šis nustatymas galioja tik prisijungimo inicializavimo procesui ir neturi efekto skaitymui ir rašymui jau atidarytame sockete, taigi verta naudoti ir stream_set_timeout() jei reikia apsisaugoti nuo gaišimo laukiant skaitymo ar rašymo veiksmų. Default_socket_timeout gali būti pakeistas bet kurioje vietoje, protinga jį būtų sumažinti iki 5-10 sekundžių.

URL includinimas
Viena iš streams galimybių yra elgtis su išoriniais URL lygiai taip pat, kaip ir su vietiniais failais. Pavyzdžiui, fopen() gali būti taip pat sėkmingai panaudota nuskaityti “http://www..net”, kaip ir “/etc/passwd”. Tai sukelia nemažai saugumo spragų, kaip, pvz., kodo injekcija per išorinį šaltinį, naudojant tokias funkcijas, kaip fopen(), file_get_contents(), readfile(), taip pat didelių duomenų arba lėtai veikiančių URL įkėlimas. Taip pat, gali būti sukuriamas amžinas ciklas, skriptui nuskaitant patį save. Kartais net web serverio perkrovimas neišgelbsti, kadangi keletas užklausų lieka buferyje ir jie vėl toliau sėkmingai ryja sistemos resursus. Serveris turi būti sustabdomas keletui sekundžių ir tada paleidžiamas iš naujo.

Į pagalbą ateina allow_url_fopen nustatymas, kurį nustačius į false, skriptas galės pasiekti išorinius šaltinius tik su curl arba socketais. Blogiausia, kad stream’ai suteikia priėjimą prie išorinių šaltinių ir tokioms funkcijoms, kaip require ar include. Jei tokių funkcijų parametruose pasitaiko vartotojo įvedamų duomenų, kenkėjas gali nesunkiai paleisti savo rašytus skriptus. Tai dar viena rimta priežastis išjungti default’u įjungtą allow_url_fopen. Nepaisant visko, su fopen() atidarinėti išorinius URL yra pakankamai saugu (arba/ir reikalinga), ir dabartinėje versijoje (5.2) jau galima pasinaudoti nauju nustatymu allow_url_include, kuris išjungtas default’u. Jis atskiria URL apdirbimo funkcionalumą, kadangi leidžia kontroliuoti ar leisti tik nuskaitymus, ar ir include/require. Abu šie nustatymai gali būti keičiami tik skripto išorėje, dėl saugumo sumetimų.
Funkcijų ir klasių draudimas
Jei galvojate, kad turi daug nustatymų, pasidomėkite, kiek yra funkcijų. :) Be abejo, visos funkcijos yra naudingos vienais ar kitais atvejais, tačiau kai kuriomis iš jų paslaugų teikėjai nenori leisti naudotis vartotojams. Tokios funkcijos, kaip exec() leidžia apeiti safe_mode ir open_basedir nustatymus, arba mail() - gali būti panaudota išsiųsti dideliems kiekiams spam’o. Tam yra skirti nustatymai disable_functions ir disable_classes, kurioms galima pateikti kableliais atskirtą sąrašą draudžiamų funkcijų ar klasių. Skriptui bandant naudoti uždraustą funkciją ar klasę bus grąžintas fatal error. Šis nustatymas, nors ir labai naudingas, deja, turi vieną apribojimą. Jis gali būti keičiamas tik .ini faile, o tai reiškia, kad negalima vieniems vartotojams leisti, o kitiems apriboti tam tikrų funkcijų. Visiems bus vienodi draudimai. Po šio nustatymo keitimo taip pat būtina perkrauti web serverį.
Modulių dinaminis įkrovimas
Enable_dl - leidžia pasirinkti ar leisti skriptui įkrauti modulį dinamiškai. Default’u šis nustatymas įjungtas, todėl suteikia gan patogų dalyką - skripto metu galima įkrauti extension’ą, tačiau tai yra didelė saugumo spraga. Nėra būdo žinoti, ką daro įkraunamas modulis, jis gali suteikti priėjimą vartotojui prie to, kas šiaip yra uždrausta ar atlikti bet kokias sistemos operacijas. Net ir be vartotojo piktų kėslų, modulis gali būti parašytas prastai, nekokybiškai, o tai taip pat gali paveikti visą sistemą. Rekomenduojama šį nustatymą išjungti .ini arba virtual host’o lygmenyje.

Pabaiga
Sėkmės, būkite saugūs! Greitai pasirodys dar viena viso šio romano dalis. :)

Straipsnio originalas čia.

Panašūs straipsniai


Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.