Apacheサーバーへのローカル接続でtcpdump
を実行すると、TCP接続が2秒ごとにすぐに確立されて閉じられることがわかりました。これらの原因となっているプロセスを見つけるにはどうすればよいですか?netstat -ctp
は役に立ちませんでした。接続が速すぎ、プロセス識別子はTIME_WAITのものには表示されません。
それらはhaproxyプローブであることがわかりました。これはstrace
で確認できましたが、そもそもhaproxyを正確に特定する方法はまだわかりません。
このようなことには、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
を削除してみてください。ただし、マシンの使用率が高い場合は、詳細なログ記録に注意してください。必要に応じて変更してください!
「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