Замонавий PHP ва Node.js лойиҳаларида барча махфий созламалар одатда битта .env файлида сақланади: маълумотлар базасининг логини ва пароли, почта сервери маълумотлари, тўлов тизимларининг калитлари, Telegram бот токени ва ҳоказо. Бу жуда қулай, чунки код ва созламалар бир-биридан ажралади. Аммо бу файл веб-сервернинг очиқ папкасида туриб қолса, уни браузерда https://example.uz/.env манзилини териб, оддий матн сифатида ўқиш мумкин бўлади. Битта шундай сўров ҳужумчига сайтингизнинг деярли барча калитларини беради.
Нега бу хато кўп учрайди
Laravel каби фреймворклар лойиҳани шундай тузадики, веб-сервернинг илдизи фақат public папкасига йўналтирилиши керак, .env эса ундан бир даража юқорида туради. Муаммо лойиҳа хостингга кўчирилганда пайдо бўлади: дастурчи бутун лойиҳани сайт илдизига ташлайди ва public/index.php га йўналтириш учун .htaccess қўшади. Натижада .env ҳам илдизда қолади ва сервер созламасига қараб уни тўғридан-тўғри бериб юборади. Худди шу ҳолат .env.backup, .env.old ёки таҳрирловчи қолдирган .env~ каби нусхалар билан ҳам юз беради, улар кўпинча унутилади.
Интернетда бундай файлларни қидирадиган ботлар тўхтовсиз ишлайди. Сайт кириш журналларини очсангиз, /.env, /api/.env, /laravel/.env каби сўровларни деярли ҳар куни кўрасиз. Бу сайт нишонга олинганини эмас, балки автоматик сканерлар барча манзилларни кетма-кет текшириб чиқаётганини билдиради, шунинг учун "менинг сайтим кичик, кимга керак" деган фикр бу ерда ишламайди.
Сайтингизни қандай текшириш мумкин
Энг оддий текширув терминалда curl буйруғи билан қилинади. Жавоб коди 403 ёки 404 бўлса ва саҳифа мазмунида DB_PASSWORD каби қаторлар бўлмаса, файл ёпиқ. Агар 200 коди қайтса ва файл мазмуни чиқса, зудлик билан чоралар кўриш керак. Текширувни асосий домен, www версияси ва субдоменлар учун алоҳида қилинг, чунки улар турли папкаларга қараши мумкин.
curl -s -o /dev/null -w "%{http_code}\n" https://example.uz/.env
curl -s https://example.uz/.env | head -5
# jurnalda kim so'raganini ko'rish
grep '"GET /.env' access.log | tail -20
Энг тўғри ечим: файлни веб-илдиздан ташқарига чиқариш
Ҳеч қандай қоида файлни веб-илдиздан ташқарида сақлашчалик ишончли эмас. Агар веб-сервер файлни умуман "кўрмаса", уни хато созлама билан ҳам бериб юбора олмайди. VPS'да ёки панел сайт папкасини ўзгартиришга рухсат берганда, илдизни лойиҳанинг public папкасига йўналтиринг. sayt.uz хостингида бу созлама ISPmanager панелида бўлади ва панелнинг ўзи sayt.uz кабинетидан очилади; аниқ қадамларни билмасангиз, техник ёрдамдан сўраш мумкин.
/home/user/example.uz/
├── .env # veb orqali ko'rinmaydi
├── app/
├── vendor/
└── public/ # veb-server ildizi shu yerda
└── index.php
Агар файл илдизда қолиши шарт бўлса
Баъзан хостинг тузилмаси илдизни ўзгартиришга имкон бермайди. Бундай ҳолда нуқта билан бошланадиган барча файлларга киришни веб-сервер даражасида тақиқлаш керак. Apache 2.4 учун қуйидаги қоида .htaccess файлига ёзилади ва .env ҳамда унинг барча нусхаларини ёпади. Nginx'да эса яширин файлларни ёпувчи location блоки қўшилади, лекин Let's Encrypt сертификати учун керак бўладиган .well-known папкаси истисно қилинади.
# .htaccess (Apache 2.4)
<FilesMatch "^\.env">
Require all denied
</FilesMatch>
# Nginx: server { } bloki ichida
location ~ /\.(?!well-known) {
deny all;
return 404;
}
Қоидани қўшгандан кейин юқоридаги curl текширувини қайта бажаринг. Nginx созламасини ўзгартиргач, аввал nginx -t билан синтаксисни текшириш ва кейин systemctl reload nginx қилиш керак, акс ҳолда янги қоида кучга кирмайди.
Файл ҳуқуқлари ва Git
Веб орқали ёпиш билан бирга файлнинг сервердаги ҳуқуқлари ҳам муҳим. .env фақат сайт эгаси бўлган фойдаланувчи томонидан ўқилиши керак, бошқа фойдаланувчилар учун эса бутунлай ёпиқ бўлиши лозим. Бундан ташқари, файл ҳеч қачон Git репозиториясига тушмаслиги керак: репозиторияга керакли ўзгарувчилар рўйхатини қийматларсиз сақлайдиган .env.example қўйилади.
chmod 600 .env
echo ".env" >> .gitignore
git rm --cached .env # agar avval tasodifan commit qilingan bo'lsa
Эътибор беринг, git rm --cached файлни фақат кейинги коммитлардан олиб ташлайди, тарихда эса у сақланиб қолади. Шунинг учун бир марта репозиторияга тушган паролларни сизган деб ҳисоблаш керак.
Файл сизиб чиққан бўлса нима қилиш керак
Агар текширувда .env очиқ экани аниқланса, уни ёпишнинг ўзи етарли эмас, чунки файл аллақачон кимдир томонидан юклаб олинган бўлиши мумкин. Қуйидаги ишларни шу тартибда бажаринг:
- Файлни юқоридаги усуллардан бири билан дарҳол ёпинг ва текширувни такрорланг.
- Маълумотлар базаси паролини ўзгартиринг ва янги паролни
.envга ёзинг. - Тўлов тизимлари, SMS хизмати, почта ва бот токенлари каби барча калитларни уларнинг кабинетида янгиланг.
- Laravel'даги
APP_KEYни ҳам алмаштиришни кўриб чиқинг, лекин бу шифрланган маълумотлар ва сессияларга таъсир қилишини олдиндан ўрганинг. - Кириш журналларидан файл қачон ва қайси IP'лардан сўралганини аниқланг ва база жадвалларида бегона фойдаланувчилар пайдо бўлмаганини текширинг.
Мисол: Бухородаги меҳмонхона сайти
Бухородаги кичик меҳмонхонанинг брон қилиш сайти Laravel'да ёзилган ва хостингга бутунлигича кўчирилган эди. Бир куни администратор почта орқали нотаниш манзилларга юзлаб хат кетганини пайқади: .env очиқ қолган, ундаги SMTP пароли билан спам юборилган эди. Дастурчи сайт илдизини public папкасига ўтказди, почта ва база паролларини алмаштирди ҳамда .htaccess га қўшимча тақиқ қўйди. Шундан кейин у янги лойиҳаларни ишга туширишдан олдин ҳар сафар curl текширувини бажаришни одат қилди.