Search by

apex-advisory / upkeep-agent

apex-advisory

Agent za Upkeep — šalje činjenice o sajtu centralnoj aplikaciji za održavanje.

Package info

gitlab.com/apex-advisory/upkeep-agent

Homepage

Issues

pkg:composer/apex-advisory/upkeep-agent

Statistics

Installs: 14

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.4 2026-09-08 17:24 UTC

This package is not auto-updated.

Last update: 2026-09-09 10:34:32 UTC


README

Agent za Upkeep. Instalira se na klijentski Laravel sajt i šalje činjenice o njegovom stanju centralnoj aplikaciji.

Instalacija

Na hubu izdaj kod:

php artisan agent:code

Na klijentskom sajtu:

composer require apex-advisory/upkeep-agent
php artisan upkeep:install --hub=https://hub.apex-advisory.me --claim=UPKEEP-XXXX-XXXX

To je sve. Komanda upisuje ključeve u .env (uz snimak .env.upkeep.bak), prijavljuje sajt, pošalje probni potpisan izvještaj i pokrene dijagnostiku.

Raspored se registruje sam, iz booted() hooka service providera. Ne diraj Kernel.php ni routes/console.php — radi identično od Laravela 9 do 13.

Ako sajt još nema cron, upkeep:doctor ispiše tačan red za copy-paste.

Komande

KomandaŠta radi
upkeep:installprijava sajta i podešavanje
upkeep:reportšalje izvještaj (--dry ispiše bez slanja, --deep uključi skupe provjere)
upkeep:doctorprovjerava sve i kaže šta je pokvareno

Šta agent šalje

Verzije PHP-a i Laravela, SAPI, deployed commit (čitanjem .git/HEAD, ne kroz git), veličinu baze i pet najvećih tabela, broj migracija u redu, neuspjele poslove i zaostatak u redu, slobodan disk, otkucaj crona, brojače grešaka iz loga, sanity provjere okruženja, i spisak paketa iz composer.lock kao parove ime+verzija.

Uz --deep (podrazumijevano na svakih 6h) dodaje obilazak storage/app i sonde web-izloženosti.

Šta agent NIKAD ne šalje

  • Cijeli composer.lock — sadrži URL-ove privatnih repoa i nagovještaje autentifikacije. Šalju se samo parovi ime+verzija.
  • Pune stack traceove — redovno sadrže tokene, mejlove i vezivanja upita. Šalju se potpisi grešaka i, samo ako se eksplicitno uključi UPKEEP_LOG_SAMPLES=true, skraćene poruke.
  • Kredencijale baze, APP_KEY, sadržaj .env-a.

Načela

  • Agent šalje činjenice, hub drži mišljenja. Nigdje u ovom paketu nema EOL tabele, praga ni uparivanja CVE-ova. Sve to je na hubu, jer se mijenja — a novu EOL tabelu ne možeš progurati na 40 sajtova svaki put kad Laravel izda verziju. Zato se tanak prenosilac činjenica rijetko i mijenja.
  • Goli cURL, bez Guzzlea i bez Http fasade. Guzzle pravi sukobe verzija kroz šest Laravel majora, a Http fasada ne postoji prije Laravela 7.
  • composer.lock se čita kao fajl. Shared hosting rijetko ima composer na PATH-u, a composer audit traži Composer 2.4+ — što stari sajtovi nemaju. Zato CVE uparivanje radi hub, pa dobijaš audit i tamo gdje Composer ne možeš ni pokrenuti.
  • Nikad file_get_contents nad logom. laravel.log od dva gigabajta nije rijetkost. Čita se samo rep, sa tvrdim budžetom vremena.
  • Neuspio push ne obara scheduler. Izvještaj ide u lokalni red i šalje se uz sljedeći uspješan, pa ispad huba ne pravi rupu u podacima.
  • Agent se NIKAD ne ažurira sam. Kod koji sam sebe mijenja je botnet C2 i jedinstvena tačka kompromisa kroz cijeli portfelj. Ponašanje se mijenja kroz konfiguraciju koju hub vraća u odgovoru na push — samo allowlistovani ključevi, nikad putanje ni komande.

Potpis

Isti u oba smjera. Kanonski string:

v1\n{METOD}\n{HOST}\n{PUTANJA}\n{VRIJEME}\n{NONCE}\n{SHA256_TIJELA}

Potpisuje se heš tijela, ne tijelo: string ostaje ograničen bez obzira na veličinu payloada. Metod, host i putanja su uvezani, pa presretnut zahtjev ne može da se ponovi ni na drugom endpointu ni za drugi sajt.

Prozor je 300 sekundi, namjerno velikodušan — shared hostovi imaju stvarno loše satove. Odstupanje se umjesto toga mjeri i prijavljuje (upkeep:doctor ga ispisuje u sekundama).

Pull endpoint (/_upkeep/{token}/report) vraća 404 na nepotpisan zahtjev, nikad 401 — nikad ne potvrđuj da endpoint postoji. Payload je gotova lista meta za napadača.

Ista logika potpisa postoji i u hubu. Ne mogu da dijele kod, pa obje strane provjeravaju isti fiksni vektor u SignerVectorTest — ako neko promijeni kanonski string na jednoj strani, pukne test, a ne 40 sajtova u produkciji.

Shared hosting

Radi, ali jedna stvar se mora podesiti.

Cron na shared hostingu je često ograničen. HostGator, na primjer, dozvoljava cron najviše svakih 15 minuta. Ako agent misli da javlja svakih 5 minuta a stvarno javlja svakih 15, hub bi ga trajno vidio kao „ćuti".

Zato interval nije pretpostavka nego podatak: agent ga javlja u izvještaju, a hub iz njega izvodi prag za tišinu (tri puta interval, minimum 15 minuta).

php artisan upkeep:install --hub=… --claim=… --interval=900

Cron red tada:

*/15 * * * * cd /home/korisnik/sajt && php artisan schedule:run >/dev/null 2>&1

upkeep:doctor ispisuje koji je backup motor stvarno dostupan — na shared hostingu mysqldump i proc_open često nisu, pa se ide na čist PHP dumper.

Podrška po verzijama

Laravel 9–13, PHP 8.1+.

Za starije sajtove (Laravel 5.8–8) ovaj paket se namjerno ne koristi: composer require bi na njima povukao razrješavanje sukoba kroz Guzzle 6 i Symfony 4 na sajtu koji se niko ne usuđuje da dira. Za njih je predviđen zaseban jednofajlni drop-in.

Testovi

composer install
vendor/bin/phpunit