解決策 1:
Linux 監査が役立ちます。少なくとも、データグラム ネットワーク接続を行っているユーザーとプロセスを特定します。 UDP パケットはデータグラムです。
まず、auditd
をインストールします フレームワークをプラットフォームにインストールし、auditctl -l
であることを確認します ルールが定義されていないと言っている場合でも、何かを返します。
次に、システム コール socket()
を監視するルールを追加します。 後で簡単に見つけられるようにタグを付けます (-k
)。 64 ビット アーキテクチャを使用していると仮定する必要がありますが、b32
を置き換えることができます b64
の代わりに
auditctl -a exit,always -F arch=b64 -F a0=2 -F a1\&=2 -S socket -k SOCKET
これをビルドするには、man ページとヘッダー ファイルを選択する必要がありますが、キャプチャされるのは基本的に次のシステム コールです:socket(PF_INET, SOCK_DGRAM|X, Y)
、3 番目のパラメーターは指定されていませんが、多くの場合ゼロです。 PF_INET
は 2 で SOCK_DGRAM
は 2 です。TCP 接続は SOCK_STREAM
を使用します。 a1=1
を設定します . (SOCK_DGRAM
2 番目のパラメータは SOCK_NONBLOCK
と ORed することができます または SOCK_CLOEXEC
、したがって &=
比較。) -k SOCKET
は、後で監査証跡を検索するときに使用するキーワードです。何でもかまいませんが、私はシンプルにするのが好きです.
しばらく待って、監査証跡を確認します。必要に応じて、ネット上でホストに ping を実行することで、いくつかのパケットを強制的に送信できます。これにより、UDP を使用する DNS ルックアップが発生し、監査アラートがトリガーされます。
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
解決策 2:
netstat を使用できますが、適切なフラグが必要であり、データを送信しているプロセスがまだ生きている場合にのみ機能します。一時的に発生し、UDP トラフィックを送信してから消えたものの痕跡は見つかりません。また、ローカルの root 権限も必要です。つまり:
ここでは、ローカル ホストで ncat を開始し、(存在しない) マシン 10.11.12.13 のポート 2345 に UDP トラフィックを送信しています:
[[email protected]]$ ncat -u 10.11.12.13 2345 < /dev/urandom
以下は、トラフィックが進行中であることを証明する tcpdump の出力です:
[[email protected] ~]# 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
便利な機能はこちら -a フラグ (ポートの詳細を表示する) と -p フラグを指定して netstat を使用し、プロセス ID の詳細を表示します。 root 権限が必要なのは -p フラグです:
[[email protected] ~]# 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
であることを教えてくれます。 .
願わくば、それが役に立つことを願っています。
解決策 3:
私はまったく同じ問題を抱えていましたが、残念ながら 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 は変更を反映しませんでした。
これが役立つことを願っています:)
解決策 4:
これは、stap バージョン 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
解決策 5:
DNS 要求を表示するには、tcpdump や wireshark などのネット スニファを使用します。クエリの内容から、クエリを発行しているプログラムがわかります。