Dokumentacija
Blokirajte javni dostop do .git in .env
Blokirajte javni dostop do .git in .env
Ko se https://example.com/.git/HEAD ali https://example.com/.env odpre v brskalniku, stran izdaja nekaj, kar strežnika ne bi smelo nikoli zapustiti. Datoteka .env hrani geslo baze, ključe za pošto in plačila ter šifrirni ključ aplikacije. Mapa .git hrani celotno izvorno kodo z zgodovino, vključno z vsakim geslom, ki je bilo kdaj zapisano v commit in pozneje "odstranjeno". Brezplačna orodja javno mapo .git prenesejo v nekaj minutah, roboti pa obe poti vsak dan iščejo po celem internetu.
To je edina postavka na kontrolnem seznamu strani, ki ne sme čakati do jutri. Če je rdeča, predpostavite, da datoteke nekdo že ima.
To je uhajanje podatkov, ne nastavitev
Blokada ustavi naslednji prenos, ne tistih, ki so se že zgodili. Ukrepajte v tem vrstnem redu:
- Takoj blokirajte dostop. Najhitreje s pravilom na spletnem strežniku ali v Cloudflaru (glejte zavihke spodaj). Vzame minuto.
- Zamenjajte vse skrivnosti, ki so bile v
.env: geslo baze, ključe za SMTP in API-je za pošto, ključe ponudnikov plačil (Stripe, PayPal), ključe za shranjevanje v oblaku, skrivnosti OAuth odjemalcev, žetone API-jev. Pri vsakem ponudniku ustvarite nove in stare prekličite. - Enako naredite s skrivnostmi v zgodovini gita, če je bila javna mapa
.git. Šteje vse, kar je bilo kdaj v commitu, tudi če ga je poznejši commit izbrisal. - Preglejte dnevnike, da vidite, ali je kdo datoteke prenesel in od kdaj.
Opozorilo: V Laravelu
APP_KEYšifrira seje, piškotke in podatke, shranjene sCryptali šifriranimi casti. Nov ključ odjavi vse uporabnike, šifriranih podatkov v bazi pa samo z novim ključem ni več mogoče prebrati. Laravel 11 in novejši zna med prehodom na nov ključ brati stare podatke: stari ključ vpišite vAPP_PREVIOUS_KEYS.
Kdo je datoteke prenesel, poiščite v dnevnikih dostopa (tudi v arhiviranih):
sudo zgrep -hE '"GET /\.(env|git)' /var/log/nginx/access.log* /var/log/apache2/access.log* 2>/dev/null | grep '" 200 '
Vsaka vrstica s statusom 200 je uspešen prenos. Na deljenem gostovanju iste poti poiščite v surovih dnevnikih dostopa v nadzorni plošči.
Preverite sami
Namesto example.com vpišite svojo stran:
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/.git/HEAD
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/.env
403 ali 404 pomeni blokirano. 200 pomeni, da je datoteka javna; če želite videti, kar vidi obiskovalec, poženite isti ukaz brez -o /dev/null -w …. .git/HEAD, ki se začne z ref: refs/heads/, je pravi repozitorij.
Preverite tudi http:// in različico naslova z www, če ju morda streže drugačna konfiguracija.
Kako popraviti
Obstajata dve ravni. Pravilo, ki blokira poti z začetno piko, je hitro in uhajanje ustavi že danes. Trajna rešitev je, da obe stvari ostaneta zunaj korenske mape strani: spletni strežnik naj vidi samo mapo, namenjeno javnosti (public/, public_html/), objava kode pa naj .git tja sploh ne kopira.
nginx
To dodajte v vsak blok server { … } strani, nad druge bloke location: na Debianu in Ubuntuju v /etc/nginx/sites-available/example.com, na Rocky, Alma in CentOS v /etc/nginx/conf.d/example.com.conf:
# Vse poti, ki se začnejo s piko, razen /.well-known/.
location ~ /\.(?!well-known/) {
deny all;
}
nginx uporabi prvi location z regularnim izrazom, ki se ujema, zato mora biti ta pred pravili, kot je location ~ \.php$.
sudo nginx -t && sudo systemctl reload nginx
Apache in LiteSpeed
To dodajte na vrh .htaccess v korenski mapi strani ali v <VirtualHost> strani, če upravljate strežnik:
# Vse poti, ki se začnejo s piko, razen /.well-known/.
RedirectMatch 404 /\.(?!well-known/)
Odgovori z 404, kot da datoteke ne obstajajo. Deluje na Apachu in na LiteSpeedu. <FilesMatch "^\.env"> ni dovolj: ujema se samo z imeni datotek, datoteke v .git pa se imenujejo HEAD, config in podobno.
Z dostopom do strežnika po spremembi znova naložite konfiguracijo:
sudo apachectl configtest && sudo systemctl reload apache2
(Na Rocky, Alma in CentOS httpd namesto apache2.)
Laravel
Korenska mapa spletnega strežnika (document root) mora biti mapa public/, nikoli mapa projekta. Takrat so .env, .git, vendor/ in storage/ zunaj tistega, kar strežnik lahko streže, in dodatno pravilo ni potrebno. Laravel Forge, Ploi in Laravel Cloud to nastavijo privzeto.
Na deljenem gostovanju, kjer je korenska mapa fiksno public_html, celega projekta ne nalagajte v public_html. Naložite ga poleg (na primer v ~/example-app) in v nadzorni plošči korensko mapo usmerite v njegovo mapo public (glejte zavihka cPanel in Plesk). Če plošča tega ne dovoli, public_html prek SSH zamenjajte s povezavo nanjo:
mv ~/public_html ~/public_html.old
ln -s ~/example-app/public ~/public_html
Če niste prepričani, da so povezave dovoljene, najprej vprašajte gostitelja. Dokler selitev ni končana, je pravilo .htaccess iz zavihka Apache začasna rešitev.
cPanel
Hitra blokada: vrstico RedirectMatch iz zavihka Apache dodajte v .htaccess v public_html (File Manager, z vklopljenim Show Hidden Files).
Premik korenske mape za dodatno domeno (addon) ali poddomeno: Domains → Domains, Manage ob domeni, New Document Root spremenite v mapo z javnimi datotekami (na primer example-app/public) in kliknite Update. Korenska mapa glavne domene je fiksno public_html; zanjo uporabite povezavo iz zavihka Laravel ali vprašajte gostitelja.
Objava z Git Version Control: repozitorij klonirajte zunaj public_html in vanj kopirajte samo javne datoteke z datoteko za objavo .cpanel.yml. Repozitorij, kloniran neposredno v public_html, objavi svojo mapo .git.
Plesk
Hitra blokada: Websites & Domains → example.com → Apache & nginx Settings, v Additional nginx directives dodajte:
location ~ /\.(?!well-known/) {
deny all;
}
Premik korenske mape: v Hosting Settings domene (v novejših različicah Pleska Hosting & DNS → Hosting) nastavite Document root na javno mapo, na primer httpdocs/public za Laravel ali Bedrock, in shranite.
Če kodo objavljate z razširitvijo Git v Plesku, ji kot pot objave nastavite korensko mapo, sam repozitorij pa naj ostane zunaj nje.
Cloudflare
Če stran teče za Cloudflarom (oranžen oblak), pravilo WAF obe poti blokira v minuti, tudi na brezplačnem paketu:
- Odprite domeno, pojdite na Security → WAF → Custom rules (v novejši nadzorni plošči Security → Security rules) in ustvarite pravilo.
- Poimenujte ga Block .git and .env, kliknite Edit expression in prilepite:
(http.request.uri.path contains "/.git" or http.request.uri.path contains "/.env")
- Izberite dejanje Block in kliknite Deploy.
To ščiti samo promet, ki gre skozi Cloudflare. Kdor pozna IP naslov strežnika, ga lahko še vedno vpraša neposredno, zato popravite tudi strežnik.
IIS in ASP.NET
IIS zna skriti cele dele poti. V datoteki web.config strani:
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment=".git" />
<add segment=".env" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
Zahtevki za te poti dobijo 404. IIS privzeto zavrne tudi datoteke brez znane vrste MIME, zato javen .env običajno pomeni, da je nekdo dodal splošen mimeMap; odstranite ga.
Node.js in Next.js
Next.js streže samo mapo public/, zato .env in .git uideta samo, kadar nekaj pred njim (nginx, Apache) kaže na mapo projekta. Popravite korensko mapo tistega strežnika ali dodajte pravilo iz njegovega zavihka.
V Expressu stregite namensko mapo in nikoli korena projekta:
app.use(express.static(path.join(__dirname, 'public')));
express.static(__dirname) objavi vse, kar je poleg kode, tudi .env in .git.
Objava kode brez .git
Tudi s pravilom je najvarnejši .git tisti, ki ga na spletnem strežniku sploh ni. Namesto git pull v korenski mapi strani datoteke izvozite:
# Samo datoteke iz zadnjega commita, brez .git:
git archive --format=tar HEAD | ssh deploy@example.com 'tar -x -C /var/www/example.com'
# Ali rsync, brez .git in lokalnega .env:
rsync -az --delete --exclude='.git' --exclude='.env' ./ deploy@example.com:/var/www/example.com/
--delete na strežniku odstrani datoteke, ki jih ni v vaši mapi, zato ciljno pot preverite dvakrat. .env na strežniku hranite zunaj mape, ki jo sinhronizirate, ali ga izključite kot zgoraj.
Nikoli ne blokirajte /.well-known
Zgornja pravila /.well-known/ namenoma pustijo odprto. Let's Encrypt jo preveri ob izdaji in podaljšanju certifikatov, tam pa so tudi datoteke, kot so security.txt in povezave za aplikacije za iOS in Android. Pravilo, ki blokira vse poti s piko, ustavi tudi podaljševanje certifikata, in stran pade, ko certifikat poteče.
Potrdite popravek
Znova poženite oba ukaza curl iz razdelka Preverite sami, nato v PulseKeeperju odprite tarčo in na zavihku Kontrolni seznam kliknite Preveri zdaj. Postavka se v nekaj minutah obarva OK, ne šele ob naslednjem dnevnem preverjanju. Blokada uhajanja ne izbriše: skrivnosti zamenjajte do konca, tudi ko je postavka zelena.