文章目录

  • 前言
  • 一、forkstat
  • 1.1 简介
  • 1.2 参数
  • 1.3 forkstat 源码
  • 二、Netlink connector
  • 2.1 Netlink简介
  • 2.2 Kernel connector

前言

监控进程的创建目前初步调研准备采用 Linux netlink connector 机制(Kernel Connector),该机制可以用来实时获取进程启动和退出的事件。

一、forkstat

1.1 简介

最近需要在应用层监控进程的创建行为(fork + exec),了解到了 forkstat 命令 :

NAME
       forkstat - a tool to show process fork/exec/exit activity

forkstat是一个记录进程fork()、exec()、exit()、coredump和进程名称更改活动的程序。它对于监视系统行为和跟踪派生进程并可能滥用系统的恶意进程非常有用。

注意,forkstat使用 Linux netlink connector 来收集进程活动,如果系统太忙,这可能会错过事件。Netlink connector 需要root权限。

Netlink Connector可以用来实时获取进程启动和退出的事件。

forkstat将显示多列与进程相关的信息:

Title      Description

Time       When the fork/exec/exit event occurred.
Event      Type of event.
PID        Process or thread ID.
Info       Parent or child if a fork, or process exit(2) value.
Duration   On exit, the duration the command ran for in seconds.
Process    The  process  name. The name will be in [ ] brackets if it is a kernel thread.

1.2 参数

使用默认参数,forkstat 将报告fork、exec和exit事件,但-e选项允许指定一个或多个fork、exec、exit、core、comm、clone、ptrce、uid、sid或所有事件。当发生fork事件时,forkstat将报告父进程和子进程的PID和进程名称,从而可以轻松地识别进程的起源。forkstat 试图跟踪进程的生命周期,并在可能的情况下记录进程退出时的持续时间。

这里主要介绍 -e 选项:

-e     specify events to trace as a comma separated list. By default the fork, exec and exit events are traced. Available events are:

              Event   Description
              fork    forks
              exec    execs
              exit    exits
              core    core dumps
              comm    process name changes in comm field
              clone   clone (normally on thread creation)
              ptrce   ptrace attach or detach
              uid     uid/gid events
              sid     sid events
              all     all the events above

示例(监控进程的 exec 系统调用行为):

~$ sudo apt install forkstat
~$ sudo forkstat -e exec -D 3
Time     Event     PID Info   Duration Process
14:28:09 exec  1849907                 head -v -n 8 /proc/meminfo
14:28:09 exec  1849908                 head -v -n 2 /proc/stat /proc/version /proc/uptime /proc/loadavg /proc/sys/fs/file-nr /proc/sys/kernel/hostname
14:28:09 exec  1849909                 tail -v -n 16 /proc/net/dev
14:28:09 exec  1849910                 df -l
14:28:09 exec  1849911                 who
14:28:09 exec  1849912                 sleep 1
14:28:10 exec  1849913                 head -v -n 8 /proc/meminfo
14:28:10 exec  1849914                 head -v -n 2 /proc/stat /proc/version /proc/uptime /proc/loadavg /proc/sys/fs/file-nr /proc/sys/kernel/hostname
14:28:10 exec  1849915                 tail -v -n 16 /proc/net/dev
14:28:10 exec  1849916                 df -l
14:28:10 exec  1849917                 who
14:28:10 exec  1849918                 sleep 1
14:28:11 exec  1849919                 head -v -n 8 /proc/meminfo
14:28:11 exec  1849920                 head -v -n 2 /proc/stat /proc/version /proc/uptime /proc/loadavg /proc/sys/fs/file-nr /proc/sys/kernel/hostname
14:28:11 exec  1849921                 tail -v -n 16 /proc/net/dev
14:28:12 exec  1849922                 df -l
14:28:12 exec  1849923                 who
14:28:12 exec  1849924                 sleep 1

1.3 forkstat 源码

forkstat 源码 请参考:https://github.com/ColinIanKing/forkstat

二、Netlink connector

2.1 Netlink简介

Netlink 主要是用来进行内核和用户空间进程之间的通信,用户空间进程之间的进程间通信 (IPC)一般不用 Netlink。

Netlink 支持双工通信,是一种异步通信机制,采用数据报信息(SOCK_DGRAM)格式传送数据。在内核与用户态应用之间传递的消息保存在socket缓存队列中,发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息。

2.2 Kernel connector

Kernel connector 是一种 Netlink ,它的 Netlink 协议号是 NETLINK_CONNECTOR:

NETLINK_CONNECTOR
              Kernel connector.

Kernel connector:新的基于netlink的用户空间<->内核空间易于使用的通信模块。

connector 驱动程序使使用基于网络链接的网络连接各种代理变得容易。必须注册回调和标识符。当驱动程序接收到具有适当标识符的特殊网络链接消息时,将调用适当的回调。

从用户空间的角度来看,这非常简单:

socket();
	bind();
	send();
	recv();

但是,如果内核空间想要使用这种连接的全部功能,驱动程序必须创建特殊的套接字,必须了解结构sk_buff处理等。Connector 驱动程序允许任何内核空间代理以一种明显更容易的方式使用基于netlink的网络进行进程间通信。
Connector 驱动程序具体请参考:

Documentation/connector/: in the Linux kernel source tree for further information.
samples/connector/

Kernel connector 能够获取的事件在用户空间的 /usr/include/linux/cn_proc.h 文件中定义:

事件类型

描述

PROC_EVENT_FORK

forks

PROC_EVENT_EXEC

execs

PROC_EVENT_UID

uid events

PROC_EVENT_GID

gid events

PROC_EVENT_SID

sid events

PROC_EVENT_PTRACE

ptrace attach or detach

PROC_EVENT_COMM

process name changes in comm field

PROC_EVENT_COREDUMP

core dumps

PROC_EVENT_EXIT

exits

对于监控进程的行为,我们感兴趣的事件有:PROC_EVENT_FORK、PROC_EVENT_EXEC 和 PROC_EVENT_EXIT 。

在这里我们是监控进程的创建,每当有新进程创建就立马收到一个事件,那么只关注 PROC_EVENT_FORK 和 PROC_EVENT_EXEC这两个事件(只监控 PROC_EVENT_EXEC 好像也可以 )即可。

这样通过该机制我们可以获取到进程创建时的 pid 号,然后在通过在 /proc/pid/文件下获取该进程的信息即可,比如:

/proc/pid/exe
/proc/pid/cmdline