web-dev-qa-db-ja.com

存続期間の短いTCP接続所有者プロセスを見つける

Apacheサーバーへのローカル接続でtcpdumpを実行すると、TCP接続が2秒ごとにすぐに確立されて閉じられることがわかりました。これらの原因となっているプロセスを見つけるにはどうすればよいですか?netstat -ctpは役に立ちませんでした。接続が速すぎ、プロセス識別子はTIME_WAITのものには表示されません。

それらはhaproxyプローブであることがわかりました。これはstraceで確認できましたが、そもそもhaproxyを正確に特定する方法はまだわかりません。

15
pmezard

このようなことには、auditdフレームワークを使用できます。それらは、「ユーザーフレンドリー」または直感的ではないため、少し掘り下げる必要があります。

まず、auditdがインストールされ、実行されていること、およびカーネルがそれをサポートしていることを確認してください。
Ubuntuの場合、たとえばapt-get install auditdを使用してインストールできます。

次に、監査のポリシーを追加して、次のようにすべてのconnect syscallを監視します。

auditctl -a exit,always -F Arch=b64 -S connect -k MYCONNECT

Linuxの32ビットインストールを使用している場合は、b64をb32に変更する必要があります。

このコマンドはポリシーを監査フレームワークに挿入し、connect()システムコールは監査ログファイル(通常は/var/log/audit/audit.log)に記録されます。

たとえば、netcatを使用してnews.ycombinator.comのポート80に接続すると、次のようになります。

type=SYSCALL msg=audit(1326872512.453:12752): Arch=c000003e syscall=42 success=no exit=-115 a0=3 a1=24e8fa0 a2=10 a3=7fff07a44cd0 items=0 ppid=5675 pid=7270 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts4 ses=4294967295 comm="nc" exe="/bin/nc.openbsd" key="MYCONNECT"
type=SOCKADDR msg=audit(1326872512.453:12752): saddr=02000050AE84E16A0000000000000000

ここで、/ bin/nc.openbsdアプリケーションがconnect()呼び出しを開始したことがわかります。多数の接続呼び出しがあり、特定のIPまたはポートのみをgrepで出力したい場合は、変換を行う必要があります。 SOCKADDR行にはsaddr引数が含まれており、0200で始まり、その後に16進数のポート番号(0050)、つまり80を意味し、次に、news.ycombinator.comのIPである174.132.225.106である16進数のIP(AE84E16A)が続きます。

監査フレームワークは大量のログを生成する可能性があるため、ミッションを完了したらログを無効にしてください。上記のポリシーを無効にするには、-aを-dに置き換えます。

auditctl -d exit,always -F Arch=b64 -S connect -k MYCONNECT

Auditdフレームワークに関する適切なドキュメント:
http://doc.opensuse.org/products/draft/SLES/SLES-security_sd_draft/part.audit.html

IPアドレスを16進数、12進数、バイナリなどとの間で変換します。
http://www.kloth.net/services/iplocate.php

一般的なhex/decコンバーター:
http://www.statman.info/conversions/hexadecimal.html

IT Security Stack Exchangeによる、auditdの簡単な紹介。 http://security.blogoverflow.com/2013/01/a-brief-introduction-to-auditd/

編集1
これを行うもう1つの簡単な方法(スウェーデン語:fulhack)は、次のように、接続データをダンプする高速ループを作成することです。

while true;do
  ss -ntap -o state established '( dport = :80 )'
  sleep 1
done

このコマンドは、ssコマンド(ソケット統計)を使用して、ポート80への現在確立されている接続をダンプします。大量のデータがある場合は、完了後に| tee /tmp/outputを追加して、画面に出力を表示するだけでなく、/ tmp/outputに書き込んで、後で処理/掘り起こすことができます。高速なプロキシ接続をキャッチできない場合は、sleep 1を削除してみてください。ただし、マシンの使用率が高い場合は、詳細なログ記録に注意してください。必要に応じて変更してください!

20
Mattias Ahnberg

「ausearch -i」から取得した膨大なログをgrepして、インターネット上の別のホストに正常に接続されたソケットのみを表示することもできます。インターネット上のホストに接続するためのソケットを作成する各プロセスとコマンド、およびそのターゲットホストの接続アドレスと、ソケットが「作成された」現在の時刻を取得する単純なスクリプトを書きました。ここにあります:

#!/bin/bash

if [[ $EUID -ne 0 ]]; then

    echo "You must run this script as root boy!"
    exit 1  

fi

> proccessConnections.dat

connections=`ausearch -i | grep Host: | awk -F "msg=audit" '{print $2}' | awk -F ": saddr" '{print $1}'`

connectionsNumber=`echo "$connections" | wc -l`

echo "Number of connections: $connectionsNumber"

echo "$connections" > conTemp.dat

let counter=1
while read connectInfo; do

    success=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | grep success=yes`    
    addressInfo=`ausearch -i | grep "$connectInfo" | grep type=SOCKADDR | awk -F ': ' '{print $2}'`
    processInfo=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | awk -F 'comm=' '{print $2}' | awk -F 'key' '{print $1}'` 

    if [[ $success != "" ]]
    then    
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    else
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    fi

    let counter++


done < conTemp.dat
1
Marcelo Silva