どのプロセスがゾンビプロセスになったかを識別する方法はありますか?

どのプロセスがゾンビプロセスになったかを識別する方法はありますか?

Ubuntuサーバーの1つには82のゾンビプロセスがあります。すべてのプロセスは、プロセスコマンドとして「[sh]defunct」と表示されます。どのプロセスがゾンビプロセスになるかを調べる方法はありますか?

/proc/PID/私はゾンビプロセスの手がかりを得るためにディレクトリをチェックしてみましたが、すべてのファイルは空です。誰がこのプロセスをゾンビにしたかを調べる方法...他の方法を見つけることができますか?

アップデート/解決方法:質問をより明確にし、andcozが提案したように私の質問に答えました。

ベストアンサー1

Linuxカーネルの監査サブシステムは、どのプロセスがゾンビになっているかを調べるのに非常に役立ちます。次のような状況が発生しました。

server ~ # ps -ef --forest
[...]
root     16385     1  0 17:04 ?        00:00:00 /usr/sbin/apache2 -k start
root     16388 16385  0 17:04 ?        00:00:00  \_ /usr/bin/perl -T -CSDAL /usr/lib/iserv/apache_user
root     16389 16385  0 17:04 ?        00:00:00  \_ /usr/bin/perl -T -CSDAL /usr/lib/iserv/apache_user
www-data 16415 16385  0 17:04 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 18254 16415  0 17:23 ?        00:00:00  |   \_ [sh] <defunct>
www-data 18347 16415  0 17:23 ?        00:00:00  |   \_ [sh] <defunct>
www-data 22966 16415  0 18:18 ?        00:00:00  |   \_ [sh] <defunct>
www-data 16583 16385  0 17:05 ?        00:00:01  \_ /usr/sbin/apache2 -k start
www-data 18306 16583  0 17:23 ?        00:00:00  |   \_ [sh] <defunct>
www-data 18344 16583  0 17:23 ?        00:00:00  |   \_ [sh] <defunct>
www-data 17561 16385  0 17:12 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 22983 17561  0 18:18 ?        00:00:00  |   \_ [sh] <defunct>
www-data 18318 16385  0 17:23 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 19725 16385  0 17:43 ?        00:00:01  \_ /usr/sbin/apache2 -k start
www-data 22638 16385  0 18:13 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 22659 16385  0 18:14 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 25102 16385  0 18:41 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 25175 16385  0 18:42 ?        00:00:00  \_ /usr/sbin/apache2 -k start
www-data 25272 16385  0 18:44 ?        00:00:00  \_ /usr/sbin/apache2 -k start

これらのゾンビプロセスの原因はPHPスクリプトである可能性が高いですが、これらのApacheサブプロセスは多数のHTTPリクエストとさまざまなPHPスクリプトを処理しているため、どのプロセスが原因であるかを理解するのは困難です。 Linuxはこれらのゾンビプロセスに関する重要な情報も公開しているため、どのスクリプトやコマンドが/proc/<pid>/cmdline実行されているかを知る必要さえありません。-c/bin/sh

server ~ # cat /proc/18254/cmdline 
server ~ # 

これを理解するために、以下をインストールしましたauditdhttps://linux-audit.com/configuring-and-auditing-linux-systems-with-audit-daemon/

次の監査ルールを設定しました。

auditctl -a always,exit -F arch=b32 -S execve -F path=/bin/dash
auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/dash

これらのルールは、/bin/dashバイナリのすべてのプロセス生成を監査します。/bin/shこれはシンボリックリンクなので、これはうまくいかず、監査では明らかにターゲットファイル名のみを見ることができます。

server ~ # ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Nov  8  2014 /bin/sh -> dash*

これで簡単なテストで監査ログが生成されます/var/log/audit/audit.log(読みやすくするために多くの改行を自由に追加しました)。

server ~ # sh -c 'echo test'
test

server ~ # tail -f /var/log/audit/audit.log
[...]
type=SYSCALL msg=audit(1488219335.976:43871): arch=40000003 syscall=11 \
  success=yes exit=0 a0=ffdca3ec a1=f7760e58 a2=ffdd399c a3=ffdca068 items=2 \
  ppid=27771 pid=27800 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 \
  fsgid=0 tty=pts7 ses=7532 comm="sh" exe="/bin/dash" key=(null)
type=EXECVE msg=audit(1488219335.976:43871): argc=3 a0="sh" a1="-c" \
  a2=6563686F2074657374
type=CWD msg=audit(1488219335.976:43871):  \
  cwd="/var/lib/iserv/remote-support/iserv-martin.von.wittich"
type=PATH msg=audit(1488219335.976:43871): item=0 name="/bin/sh" inode=10403900 \
  dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PATH msg=audit(1488219335.976:43871): item=1 name=(null) inode=5345368 \
  dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PROCTITLE msg=audit(1488219335.976:43871): \
  proctitle=7368002D63006563686F2074657374

ほとんどの情報はエンコードされていますが、ausearch次のように翻訳できます-i

server ~ # ausearch -i -x /bin/dash | tail                                      
[...]
----
type=PROCTITLE msg=audit(27.02.2017 19:15:35.976:43871) : proctitle=sh 
type=PATH msg=audit(27.02.2017 19:15:35.976:43871) : item=1 name=(null) \
  inode=5345368 dev=08:01 mode=file,755 ouid=root ogid=root rdev=00:00 \
  nametype=NORMAL 
type=PATH msg=audit(27.02.2017 19:15:35.976:43871) : item=0 name=/bin/sh \
  inode=10403900 dev=08:01 mode=file,755 ouid=root ogid=root rdev=00:00 \
  nametype=NORMAL 
type=CWD msg=audit(27.02.2017 19:15:35.976:43871) :  \
  cwd=/var/lib/iserv/remote-support/iserv-martin.von.wittich 
type=EXECVE msg=audit(27.02.2017 19:15:35.976:43871) : argc=3 a0=sh a1=-c \
  a2=echo test 
type=SYSCALL msg=audit(27.02.2017 19:15:35.976:43871) : arch=i386 \
  syscall=execve success=yes exit=0 a0=0xffdca3ec a1=0xf7760e58 a2=0xffdd399c \
  a3=0xffdca068 items=2 ppid=27771 pid=27800 auid=root uid=root gid=root \
  euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts7 \
  ses=7532 comm=sh exe=/bin/dash key=(null) 
----

ausearchフィルタリングをに制限したくない場合は、完全なログ翻訳を使用することも/bin/dashできます。この場合、もう一つの良いフィルタはです。ausearch -i -m ALLausearch -i -p <PID of a zombie process>ausearch -i -p 27800

新しいゾンビプロセスが表示されるまでこのルールを維持し、プロセス生成のゾンビPIDを検索します。

ausearch -i -p <PID>

これはゾンビプロセスの根本的な原因を特定するのに非常に役立ちます。私の場合、proc_open.NET Frameworkを使用せずにPerlスクリプトを生成するのはPHPスクリプトでしたproc_close

おすすめ記事