První věc:zjistěte, odkud tyto požadavky pocházejí. Musí to být lokální proces, nic jiného pravděpodobně nedokáže zfalšovat TCP handshake na moderní linuxové platformě (nic, co by se pak ztratilo takový výkon při vyžádání náhodných obrázků).
Pokud existují opakující se adresy URL, můžete je zastínit za RewriteRule
takže každý takový požadavek skutečně spustí skript . Ve skriptu můžete spustit další kontroly, abyste zjistili, zda je požadavek legitimní (a poté vypíšete správné hlavičky, jako by to byl obrázek, který legitimní klient očekává), nebo zda jde o jeden z falešných požadavků. Proti falešné žádosti se můžete přihlásit např. příchozí port. Vyzbrojeni tím můžete dotazovat netstat
a zjistit postup. Můžete také spustit ps
a zkontrolovat všechny aktivní procesy v okamžiku falešného požadavku.
Jsem si docela jistý, že viníkem bude samotný Apache (jednou se mi stalo, že se mi skript "vyrovnávací paměti" pokazil kvůli úpravě vhost - zapomněl jsem dát skript do crontab - a dostal jsem opravdu divné příznaky, trochu jako tvůj, dokud se mi to všechno nevrátilo; ale tvůj případ je jiný).
Chcete-li scénu dále vylepšit a zároveň omezit náklady, můžete do CustomLog
Apache přidat PID/TID . Poté budete moci zkontrolovat požadavky přijaté od dítěte Apache, které je pryč.
Další možností je přesně určit jak tyto požadavky jsou vzneseny. Pokud přes Apache, znamená to fopen_wrappers, cURL, funkce socketů nebo možná nástroje shellu (oba by se měly objevit v ps
výstup a výsledkem je však mnohem masivnější přetížení serveru). Můžete připravit sérii skriptů, které:
- klidně restartujte Apache bez jakýchkoli změn
- " ", deaktivace dočasně jednu z těchto funkcí
- " ", znovu aktivace stejné
Po ověření (jen pro jistotu), že restart není opravte problém (pokud ano, byla by to docela jiná plechovka červů), můžete přistoupit k dočasné deaktivaci – každá na pár desítek sekund, ne více – jednu funkci za druhou. Předpokládejme, že deaktivace curl vede k okamžitému návratu systému k normálu:pak byste mohli omezit vyšetřování na skripty používající cURL a možná dokonce zabalit funkce cURL s logovacím obalem.
V případě, že se ukáže, že viníkem není Apache, stále budete moci určit, co dělá to; pak buď přeinstalujte postižený program (i když považuji za nepravděpodobné, aby jakákoli náhodná anomálie změnila program na žadatele repeat-HTTP-GET-requestor), nebo zkontrolujte jeho konfiguraci, pomocné datové soubory, skripty a tak dále a tak dále a podívejte se pro jakýkoli rozdíl od známé čisté instalace. Protože na gremliny obvykle nevěřím, očekávám, že nějaký rozdíl nakonec vynikne.
Unix (a Linux) má spoustu nástrojů pro analýzu takových věcí. Moje první zastávka by byla chytit výstup netstat -nap např. na mém místním počítači...
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
...
tcp 0 0 192.168.0.2:80 192.168.0.2:59875 ESTABLISHED 5281/httpd
...
tcp 0 0 192.168.0.2:59875 192.168.0.2:80 ESTABLISHED 32588/chrome
...
Zde vidím, že chrome (pid 32588) je připojen k portu 80 / httpd (pid 5281). Protože se jedná o instalaci apache před rozvětvením, mohu získat více informací o procesu httpd přihlášením %P nebo pohledem do /proc/5281/fd (poslední bude pravděpodobně vyžadovat skriptování k zachycení dat v době požadavku ).
To vám umožní identifikovat klientský proces.
Nejpravděpodobnějšími kandidáty jsou špatně nakonfigurovaný proxy nebo chybný kód.
Kdyby to byl můj server, spouštěl bych strace
na Apache. Spuštění tohoto na každém podřízeném procesu v režimu prefork může být poměrně náročné na disk, zvláště když je váš server již přetížen. Musíte také dávat pozor na místo na disku, protože pokud dojde, Apache přestane obsluhovat požadavky.
Ujistěte se, že používáte dostatečně dlouhou délku pro zachycení celého požadavku:-s 400
by měl udělat.
Pokud Apache zadává požadavky sám sobě, jakýkoli řetězec GET se objeví ve výpisech strace pro dva různé PID:jeden, který požadavek odeslal, a jeden, který jej přijal. V tom, který podal požadavek, chcete najít požadavek, který obdržel a zpracovával, když si požadavek podal.
Normálně dělám něco takového:
for x in `ps -ef | grep apache | awk '{print $2}'`; do strace -s 2000 -p $x -o trace.$x & done
Pokud se chcete z důvodu výkonu omezit na podmnožinu dětí Apache, přidejte head
tam:
for x in `ps -ef | grep apache | head | awk '{print $2}'`; do strace -s 2000 -p $x -o trace.$x & done
Uvědomte si však, že to snižuje pravděpodobnost, že zachytíte, co se děje.
Ujistěte se, že máte otevřené dvě relace SSH, protože všechny tyto úlohy na pozadí mohou stále zapisovat do vaší relace. Když chcete zastavit trasování, restartujte Apache nebo spusťte toto v druhém:
for x in `ps -ef | grep strace | awk '{print $2}'`; do kill $x; done
Můj vnitřní pocit z tohoto je "statický" modul napsaný v PHP, který předběžně zpracovává obrázky (například mění jejich velikost) před jejich odesláním klientovi, a to pomocí include($image)
. Pokud $image
náhodou obsahuje adresu URL obrázku z vašeho vlastního webu místo cesty k souboru z místního souborového systému, výsledkem jsou rekurzivní požadavky.
Může to být pomocí curl()
funkce spíše než include()
.