まず、これらのリクエストがどこから来たのかを調べます。これはローカル プロセスである必要があり、最新の Linux プラットフォームで TCP ハンドシェイクをスプーフィングできる可能性が高いものは他にありません (つまり、無駄 に進むものは何もありません) ランダムな画像をリクエストするという偉業です)。
繰り返される URL がある場合は、RewriteRule
の背後にそれらを隠すことができます そのようなリクエストが実際にスクリプトをトリガーするように .スクリプトでは、追加のチェックを実行して、リクエストが正当であるかどうか (そして、正当なクライアントが期待する画像であるかのように適切なヘッダーを出力するかどうか)、またはそれが偽のリクエストの 1 つであるかどうかを確認できます。偽のリクエストに対して、たとえばログに記録できます。着信ポート。それを武器に、 netstat
をクエリできます そしてその過程を知る。 ps
を実行することもできます 偽のリクエストの瞬間にすべてのアクティブなプロセスを検査します。
犯人はApache自体であることが証明されると確信しています(vhostの変更により、「キャッシュプライミング」スクリプトが不正になったことがあります-スクリプトをcrontabに入れるのを忘れていました-そして、非常に奇妙な症状が発生しました。すべてが私に戻ってくるまでは、あなたのものでしたが、あなたのケースは違うように感じます)。
コストを抑えながらシーンをさらに洗練するには、PID/TID を Apache の CustomLog
に追加できます。 .その後、不正な Apache の子から受け取ったリクエストをクロスチェックできます。
別の可能性は、方法を正確に決定することです これらの要求が行われます。 Apache 経由の場合、これは fopen_wrappers、cURL、ソケット関数、またはシェル ユーティリティを意味します (これらは両方とも ps
に表示されます)。 出力し、はるかに大規模なサーバーの過負荷になります)。次のような一連のスクリプトを準備できます:
- Apache を正常に再起動します。何も変更せずに
- " "、無効にする 一時的にこれらの関数の 1 つ
- " " , 再有効化 同じ
再起動がしないことを(念のため)確認した後 問題を修正する (修正された場合、ワームのまったく別の缶詰になります)、一時的に無効にすることができます - 数十秒ごとに、それ以上ではありません - 次々と機能を無効にします。 curl を無効にすると、システムがすぐに正常に戻るとします。その場合、調査を cURL を使用するスクリプトに制限することができます。 ロギング ラッパーを使用した cURL 関数。
有罪の当事者がApacheではないことが判明した場合でも、何があるかを判断することができます これを行っています。次に、影響を受けるプログラムを再インストールするか (ランダムな異常によってプログラムがリピート HTTP GET リクエスターに変わる可能性は低いと思いますが)、その構成、補助データ ファイル、スクリプトなどを調べて、探します。既知のクリーン インストールとの違いについて。私は通常、グレムリンを信じていないので、最終的に何らかの違いが際立つことを期待しています.
Unix (および Linux) には、このようなものを分析するための豊富なツールがあります。私の最初の停止は、 netstat -nap の出力を取得することです。ローカル マシンで...
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
...
ここで、chrome (pid 32588) がポート 80 / httpd (pid 5281) に接続されていることがわかります。これは apache のフォーク前のインストールであるため、%P をログに記録するか、/proc/5281/fd を参照することで、httpd プロセスに関する詳細情報を取得できます (後者では、リクエスト時にデータを取得するためのスクリプトが必要になる可能性があります)。 ).
これにより、クライアント プロセスを特定できます。
最も可能性の高い候補は、正しく構成されていないプロキシまたはバグのあるコードです。
これが私のサーバーなら、strace
を実行します。 アパッチで。これをすべての子プロセスで prefork モードで実行すると、特にサーバーがすでに過負荷になっている場合に、かなりディスクを集中的に使用する可能性があります。ディスク容量が不足すると、Apache はリクエストの処理を停止するため、ディスク容量にも注意する必要があります。
リクエスト全体をキャプチャするのに十分な長さの snaplength を使用してください:-s 400
Apache が自分自身にリクエストを送信している場合、GET 文字列は 2 つの異なる PID の strace ダンプに表示されます。1 つはリクエストを作成し、もう 1 つはリクエストを受信しました。リクエストを行ったもので、自分自身にリクエストを行ったときに受信して処理していたリクエストを見つけたいと考えています。
私は通常、次のようなことをします:
for x in `ps -ef | grep apache | awk '{print $2}'`; do strace -s 2000 -p $x -o trace.$x & done
パフォーマンス上の理由から Apache の子のサブセットに制限したい場合は、 head
を追加してください そこに:
for x in `ps -ef | grep apache | head | awk '{print $2}'`; do strace -s 2000 -p $x -o trace.$x & done
ただし、これにより、何が起こっているのかを把握する可能性が低くなることに注意してください。
これらのバックグラウンド タスクはすべてセッションに書き込むことができるため、2 つの SSH セッションが開いていることを確認してください。トレースを停止したい場合は、Apache を再起動するか、別の Apache でこれを実行してください:
for x in `ps -ef | grep strace | awk '{print $2}'`; do kill $x; done
これについての私の直感は、クライアントに送信する前に画像を前処理する (たとえば、サイズ変更する) PHP で記述された "静的" モジュールであり、 include($image)
でこれを行います。 . $image
の場合 ローカル ファイル システムからのファイル パスではなく、自分のサイトからの画像 URL が含まれていると、再帰的なリクエストが発生します。
curl()
を使用している可能性があります include()
ではなく関数 .