LinuxでUDPトラフィックを生成しているプロセスを特定するにはどうすればよいですか?


39

私のマシンは継続的にudp dnsトラフィックリクエストを行っています。私が知る必要があるのは、このトラフィックを生成するプロセスのPIDです。

TCP接続の通常の方法は、netstat / lsofを使用して、pidに関連付けられたプロセスを取得することです。

UDPは接続がステートレスであるため、netastat / lsofを呼び出すと、UDPソケットが開かれ、トラフィックを送信している場合にのみ表示されます。

で試してみましたがlsof -i UDPnestat -anpueUDPデータグラムが送信される前/後にlsof / netstatを呼び出すと、udpトラフィックが送信されたときにlsof / netstatを正確に呼び出す必要があるため、プロセスがそのリクエストを実行していることがわかりません開かれたUDPソケットを表示できません。

3/4 udpパケットが送信されたときに正確にnetstat / lsofを呼び出してください。

悪名高いプロセスを特定するにはどうすればよいですか?パケットのコンテンツから送信されたPIDを特定しようとするためにトラフィックをすでに検査しましたが、トラフィックの接続からそれを特定することはできません。

誰でも私を助けることができますか?

私はこのマシンのルートですFEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64#1 SMP Wed Jul 7 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

回答:


48

Linux監査が役立ちます。少なくとも、データグラムネットワーク接続を行うユーザーとプロセスを特定します。UDPパケットはデータグラムです。

まず、auditdプラットフォームにフレームワークをインストールし、auditctl -lルールが定義されていないと言っていても、それが何かを返すようにします。

次に、システムコールを監視するルールを追加し、socket()後で簡単に見つけられるようにタグを付けます(-k)。64ビットアーキテクチャを使用していると想定する必要がありますがb32b64そうでない場合は、代わりに使用できます。

auditctl -a exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET

これを構築するには、マニュアルページとヘッダーファイルを選択する必要がありますが、キャプチャされるのは基本的にこのシステムコールですsocket(PF_INET, SOCK_DGRAM|X, Y)。3番目のパラメーターは指定されていませんが、多くの場合ゼロです。 PF_INETは2でSOCK_DGRAMあり、2です。TCP接続は、SOCK_STREAMどちらを設定するかを使用しますa1=1。(SOCK_DGRAM2番目のパラメーターではOR SOCK_NONBLOCKまたはORでORされるSOCK_CLOEXECため、&=比較されます。)-k SOCKETは、後で監査証跡を検索するときに使用するキーワードです。それは何でも構いませんが、私はそれをシンプルに保つのが好きです。

しばらくして、監査証跡を確認してください。必要に応じて、ネット上でホストをpingすることでいくつかのパケットを強制できます。これにより、DNSルックアップが発生し、UDPが使用され、監査アラートがトリップされます。

ausearch -i -ts today -k SOCKET

そして、以下のセクションのような出力が表示されます。重要な部分を強調するために省略しています

type=SYSCALL ... arch=x86_64 syscall=socket success=yes exit=1 a0=2 a1=2 ... pid=14510 ... auid=zlagtime uid=zlagtime ... euid=zlagtime ... comm=ping exe=/usr/bin/ping key=SOCKET

上記の出力では、pingコマンドによってソケットが開かれたことがわかります。strace -p 14510プロセスがまだ実行されている場合は、実行できます。ppid(親プロセスID)も、それがスポーン問題児多いというスクリプトである場合に表示されます。

さて、UDPトラフィックが多い場合、これでは十分ではなく、OProfileまたはSystemTapに頼る必要があります。どちらも現在、私の専門知識を超えています。

これは一般的な場合に物事を絞り込むのに役立つはずです。

完了したら、作成に使用したのと同じ行を使用して監査ルールを削除-a-dます。

auditctl -d exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET

試してみますが、正しい答えだと思います。
ブーイング

これは、少なくとも私にとっては、iptablesによってドロップされるトラフィックを拾っていません。
2rs2ts

1
systemtapメソッド(より分析的ですが、カーネル
開発

23

netstatを使用できますが、正しいフラグが必要であり、データを送信しているプロセスがまだ生きている場合にのみ機能します。少しの間、命が吹き込まれ、UDPトラフィックを送信してから消えたものの痕跡を見つけることはできません。また、ローカルルート権限も必要です。それは言った:

ローカルホストでncatを起動し、UDPトラフィックを(存在しない)マシン10.11.12.13のポート2345に送信します。

[madhatta@risby]$ ncat -u 10.11.12.13 2345 < /dev/urandom

次に、トラフィックが進行していることを証明するtcpdump出力を示します。

[root@risby ~]# tcpdump -n -n port 2345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:41:32.391750 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.399723 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.401817 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.407051 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.413492 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192
12:41:32.417417 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192

netstatに-aフラグ(ポートの詳細を表示)と-pフラグを使用してプロセスIDの詳細を表示すると、便利なビットがあります。ルート権限が必要なのは-pフラグです。

[root@risby ~]# netstat -apn|grep -w 2345
udp        0      0 192.168.3.11:57550          10.11.12.13:2345            ESTABLISHED 9152/ncat     

ご覧のとおり、pid 9152は、指定されたリモートホストのポート2345への接続が開いているとフィンガーされています。また、Netstatはpsを介して実行し、プロセス名がであると教えてくれますncat

うまくいけば、それはいくつかの用途のです。


本当に素晴らしい!:thumbup:
ThorstenS

2
しかし、キャッチがあります。DNSルックアップを行うサブプロセスを生成するシェルスクリプトによって問題が発生し、そのプロセスがすぐに終了する場合、ソースポート(上記の57550)は常に変更されます。この場合、手法は機能せず、より抜本的な対策を講じる必要があります。さらに、grep -w 57550複数のプロセスが同じサーバーに対してDNSルックアップを実行している可能性があるため、netstatで実行する必要があります。あなたの方法はそれらを区別しません。
zerolagtime

1
私はあなたの両方の異論、zerolagtimeに同意します(しかし、とにかく優しい言葉をありがとう、ThorstenS!)。
MadHatterは、

17

私はまったく同じ問題を抱えていましたが、残念なことにauditd私にはあまり何もしませんでした。

一部のサーバーからGoogle DNSアドレスに向かうトラフィックが8.8.8.8ありました8.8.4.4。現在、私のネットワーク管理者は軽度のOCDを使用しており、インターンDNSキャッシュがあるため、不必要なトラフィックをすべて削除したかったのです。彼は、これらのキャッシュサーバーを除くすべてのユーザーに対して送信ポート53を無効にしたいと考えていました。

だから、で失敗した後auditctl、私はに掘るsystemtap。次のスクリプトを思い付きます。

# cat >> udp_detect_domain.stp <<EOF
probe udp.sendmsg {
  if ( dport == 53 && daddr == "8.8.8.8" ) {
    printf ("PID %5d (%s) sent UDP to %15s 53\n", pid(), execname(), daddr)
  }
}
EOF

次に、単に実行します:

stap -v udp_detect_domain.stp

これは私が得た出力です:

PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3501 (python) sent UDP to  8.8.8.8 53
PID  3506 (python) sent UDP to  8.8.8.8 53

それでおしまい!resolv.confそれらのPIDを変更した後、変更は反映されませんでした。


お役に立てれば :)


5

以下は、stap verson 1.8以降で使用可能なnetfilterプローブを使用したsystemtapオプションです。も参照してくださいman probe::netfilter.ip.local_out

# stap -e 'probe netfilter.ip.local_out {
  if (dport == 53) # or parametrize
      printf("%s[%d] %s:%d\n", execname(), pid(), daddr, dport)
}'
ping[24738] 192.168.1.10:53
ping[24738] 192.168.1.10:53
^C

4

DNS要求を表示するには、tcpdumpやwiresharkのようなネットスニファーを使用します。クエリの内容は、どのプログラムがそれらを発行しているのかを知ることができます。


トラフィックの情報はスニフドしていません。
ブーイング

情報がありませんか?空のパケット?私が意味したのは、updates.java.sun.comまたはrss.cnn.comを解決しようとするものがあれば、そこから何かを推測できることです。
RedGrittyBrick

内部プロキシを検索するDNSクエリ。今、私はそのプロセスを見つけましたが、テクニクスを解決する一般的な問題のための質問はまだ生きています
ブーイング

lsof -i | awk '/ UDP /'
c4f4t0r 14

3

autitctlを使用する場合、nscdは、たとえばDNSクエリを実行するときに、ソケットシステムコールでわずかに異なるパラメーターを使用することに注意してください。

socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP)

したがって、上記のクエリに加えてこれらのクエリを確実にキャッチするために、必要に応じて同じ名前の追加のフィルタを追加できます。

auditctl -a exit,always -F arch=b64 -F a0=2  -F a1=2050 -S socket -k SOCKET

ここで、2050はSOCK_DGRAM(2)とSOCK_NONBLOCK(2048)のビット単位のORです。

次に、検索は同じキーを持つ両方のフィルターを見つけますSOCKET

ausearch -i -ts today -k SOCKET

ここで見つけたソケット定数の16進値:https : //golang.org/pkg/syscall/#pkg-constants

コメントする評判ポイントがないので、これを追加しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.