Sysdig chisels 开发

Chisels

Sysdig 的 chisels 是通过分析sysdig 事件数据流去完成特定动作的小脚本。在Sysdig中,系统事件events 被高效地呈现在了用户空间,所以脚本能够直接被应用到处理事件上。好处如下:

  • 能使用普遍被使用的而不是定制的语言。sysdig的chisels 使用 Lua 脚本语言。
  • Chisels 能很方便地使用众多的Lua库
  • Chisels 在实时系统上工作情况良好,但也能和捕获的文件一起来完成离线的分析工作。

使用

  • 列出可所有使用的chisels
    $ sysdig -cl
  • 输出某个chisel 的详细描述和参数列表,使用 -i 命令行选项
    $ sysdig -i spy_ip
  • 运行某个chisel 工具,使用 -c 选项
    $ sysdig -c topfiles_bytes
  • chisel工具需要参数时,直接在后面补充
    $ sysdig -c spy_ip 192.168.1.157
  • 能够同时运行多个chisel工具
    $ sysdig -c stding -c stdout proc.name=cat
  • chisels 可以和过滤器filters 结合使用
# 不需要对 /dev 的访问
$ sysdig -c topfiles_bytes "not fd.name contains /dev"
# 只包含 /root 路径的访问
$ sysdig -c topfiles_bytes "fd.name contains /root"
# 进程 vi 访问的文件
$ sysdig -c topfiles_bytes "proc.name=vi"
# 用户 loris 访问的文件
$ sysdig -c topfiles_bytes "user.name=loris"

注意:
使用filters时,我们需要注意它是作为sysdig的还是chisels的参数传入

$ sysdig -i lsof
...
Args:
[filter] filter - A sysdig-like filter expression that allows r
                estricting the FD list. E.g. 'proc.name=foo and fd.name contain
                s /etc'.

当作为chisels参数传入时,如上面的lsof,当有多个筛选条件,如sysdig -c lsof "'user.name=phil or proc.name=sshd'",这里是需要双重引号的。
当作为sysdig参数传入,当有多个筛选条件,如:sysdig "fd.rip=54.165.81.189 and fd.port=6666",这时候是可加双引号的
更多规则使用可参考https://sysdig.com/blog/linux-troubleshooting-cheatsheet/#lsof

开发自定义Chisel

Sysdig chisels 使用Lua 语言编写,如果不熟悉,可以参考Programming in LuLua reference manual

Chisels 脚本结构
--[[
Lua 脚本如果要想被sysdig 识别,必须要定义以下几个全局变量
description
short_description
category
args:包含参数的列表,可为空
以上这些参数都会被sysdig识别并添加在chisels信息中(使用 sysdig -cl / sysdig -i chisels_name)
--]]
-- Chisel description
description = "counts how many times the specified system call has been called"
short_description = "syscall count"
category = "misc"

-- Chisel argument list
args =
{
    {
        name = "syscall_name",
        description = "the name of the system call to count",
        argtype = "string"
    },
}

--[[
当需要给chisels传递参数时,用参数信息补充arg 表和增加 on_set_arg()函数。sysdig收集到命令行参数时,接着传入并调用 on_set_arg函数。当有多个参数时,可使用不同的name来区分开来。
--]]
-- Argument notification callback
function on_set_arg(name, val)
    syscallname = val
    return true
end

--[[
chisel 初始化函数,在收到第一个事件前执行。
以下代码使用了chisel.request_field去提取需要的ftype和fdir字段的地址,方便后面根据这两个字段去筛选事件
--]]
-- Initialization callback
function on_init()

    -- Request the fields that we need
  -- 以下变量为userdata类型,猜测存储了c/c++中指针类型数据
    ftype = chisel.request_field("evt.type")
    fdir = chisel.request_field("evt.dir")

  -- set the filter
  -- 通过chisels使用sysdig引擎来优化筛选事件
    chisel.set_filter("evt.type=" .. syscallname .. " and evt.dir = >")

  --[[
  可以通过print()自定义事件通知,可以使用以下定义通知格式
  ""相当于"default"
  chisel.set_event_formatter("")
  --]]

    return true
end

count = 0

-- Event parsing callback
-- 每当一个事件到来都会触发该函数的执行
function on_event()
  count = count + 1
    return true
end

--[[
捕获结束时的动作,一般用于通知操作
结束的情况:
离线捕获中收到最后一个数据包
实时捕获中按下CTRL+C
--]]
-- End of capture callback
function on_capture_end()
    print(syscallname .. " has been called " .. count .. " times")
    return true
end

Chisels API

Chisels 通过以下三种独立的接口与sysdig 交流

  • Callbacks 回调函数的集合
  • sysdig library 与主程交互的函数库
  • evt library 用来从捕获的事件中提取信息
强制的变量

为了能被识别为Chisels,Lua 脚本中必须包含以下全局变量:

  • description: 对该chisel 详细的描述 字符串类型
  • short_description: 简略描述,字符串类型
  • category: chisel 所属的目录,如 IO,net,security,字符串类型
  • args: 描述每一个chisel参数,table表格类型
args =
{
    {
        name = "name1",
        description = "description1",
        argtype = "ipv4"
        optional = false
    },
    {
        name = "name2",
        description = "description2",
        argtype = "string"
        optional = true
    },
}

注意:

  • args 中 optional设为"false",sysdig 命令行的chisel 名字后面必须指定这个参数,否则执行失败
  • args 中的每一个参数都会生成一个对on_set_arg() 的调用
  • args 可为空
  • 参数列表中有不止一个参数时,可用 "" 概括。如 sysdig -c chisel_name "arg1 arg2 arg3"
Callbacks

Callbacks 是sysdig 用来通知chisel 事情发生时的方式。除了on_interval() 需要使用sysdig.set_interval_s() 或者 sysdig.set_interval_ns()注册,大多数callbacks 不需要注册。Callbacks 是可选的,不需要则不用加上。

on_set_arg(name, val)
args 表中的每一个参数都会调用该函数。name 是参数设置的名字,val 是用户在命令行给出的值。
参数无效时会返回false并导致sysdig退出。

on_init()
在所有参数的on_set_arg()都调用后但capture被配置前被调用。通常,用来初始化chisel工具。
chisel 初始化失败返回false并导致sysdig退出

on_capture_start()
在capture配置后、on_set_arg被调用后,但在事件的数据包被捕获之前调用。能在需要询问capture状态时的最终初始化chisel步骤中使用
chisel 初始化失败返回false并导致sysdig退出

on_event()
在没有设置set_filter() 或者通过set_filter()筛选后,每个被捕获的事件到达都会激活该函数。这个函数常用来写核心的chisel逻辑,需要保证代码是高效可用的。在这个回调函数中,开发者可以对evt library访问,从而从正在处理的事件中提取信息。
在指定了格式工具(set_event_formatter)的情况下,返回false会让工具忽略该次事件。

on_capture_end(ts_s,ts_ns,delta)
捕获结束时的动作,一般用于通知操作。结束的情况如下:

  • 离线捕获中收到最后一个数据包
  • 实时捕获中按下CTRL+C
    参数含义如下:
  • ts_s,ts_ns: 最后收到事件的时间戳的秒(以秒的单位表示当前时间)和纳秒部分
  • delta:捕获的第一个包到最后一个包的间隔时间,纳秒表示

on_interval(ts_s,ts_ns,delta)
周期性的超时的回调函数。可以用来以一定频率如每秒一次报告信息。使用chisel.set_interval_s() 或者 chisel.set_interval_ns()配置。参数含义如下:

  • ts_s, ts_ns:函数被调用的时间,秒+纳秒表示
  • delta:被调用的间隔时间
sysdig library

这个库里面的函数可以用来设置全局的sysdig配置

sysdig.end_capture()
这个调用会让sysdig停止接受事件,然后‘makes it initiate the end of capture cleanup’(不太理解),感觉就是准备结束sysdig,开始清理捕获动作的相关环境。

sysdig.get_machine_info()
返回一个带有产生事件的机器的信息的表(table类型),表有以下字段:

  • num_cpus: 机器上的CPU核心的编号
  • memory_size_bytes:机器RAM的大小
  • max_pid:机器允许的最大PID数值
  • hostname:机器主机名
    注意:这个调用对文件捕获也同样有效,因为机器信息存储在跟踪文件(sysdig -w output.scap)上。这种情况下,返回的机器信息是捕获发生的其中一个机器。

sysdig.get_filter()

返回在命令行传递给sysdig的包含filter的字符串
sysdig.get_evtsource_name()
返回包含事件源名字的字符串。跟踪文件名(如果事件来源于一份跟踪文件)或者""(如果是实时捕获)

sysdig.get_output_format()
返回用户在命令行规定的输出格式,返回值可以是"normal"或者"json"

sysdig.is_print()_container_data
返回Boolean类型,表示是否使用了-pc 或者 -pcontainer 选项。

sysdig.get_container_table(filter)
返回sysdig container table
filter可以选择性地作为输入参数传递,用来限制返回的元素。语法与常规sysdig filters相同,但仅限于fd,proc,user和group filter类型。
返回以下值:

  • id:容器id,唯一标识符
  • name:容器名字
  • images:容器镜像
  • type:容器类型(docker,lxc,& libvirt_lxc)
    注意:
    container.id==host 且/或者 container.name == host 表示是主机而不是容器

sysdig.get_thread_table(filter)
返回sysdig process table。filter使用与get_container_table 相同。
返回值过多,建议参考官网资料。

sysdig.is_tty()
返回是否sysdig运行在有ANSI功能的交互终端,能被chisel用来决定是否有可能在屏幕上显示颜色

sysdig.islive()
返回当前的捕获是否实时的,即事件是来自系统还是个跟踪文件

sysdig.run_sysdig(args)
从目前执行的sysdig退出,然后再启动一个新的,参数由args传递。chisel 能用它来运行另一个不同的捕获或者再一次启动sysdig去完成不同的任务(如 保存特定事件到文件中)

sysdig.set_fatfile_dump_mode(mode)
开启/禁用 fatfile 模式。mode 参数是个Boolean值。

sysdig.set_filter(filter)
在解析事件前,将filter过滤器配置到sysdig引擎中。和在命令行中设置filter的作用是一样的,且会覆盖命令行的参数。

sysdig.set_snaplen(snaplen)
设置I/O类型的系统调用(如 read,write,sendto,recvform)的buffers的字节数。

chisel library

这个库里面的函数与设置chisel环境最相关,经常在初始化的时候被调用,例如 on_init()

chisel.exec(chiselname, arg1, arg2, ...)
这个函数能被用来停止正在调用的chisel的执行,转而去运行一个不同的chisel

chisel.request_field(fld_name)
这个函数用来在事件被捕获的时候提取一个filter字段。fld_name 是将要去提取的sysdig filter 字段(sysdig 教程或者sysdig -l 可看所有可用的字段)。函数返回字段的句柄,该句柄能用在 evt.field() 以在on_event()回调函数中获得字段的值。

chisel.set_filter(filter)
设置sysdig 引擎,在chisel的on_event()调用处理事件前使用给出的filter过滤事件。
注意:

  • set_filter 设置的filter 只对当前的chisel有效
  • 每个chisel 只能设置一个,调用两次将会导致第一次被覆盖
  • 应该尽可能地使用filters。sysdig 引擎做了大量优化,所以尽可能地减少到达chisel 的on_event()前的事件能使chisels更高效

chisel.set_event_formatter(format)
配置事件的格式工具。format 变量是一个包含将要打印的字段列表的字符串,符号使用和命令行选项 -p 一致。
默认情况下,chisel 没有事件格式工具,它们可以使用Lua 的print() 函数任意输出。设置了格式工具,可以利用sysdig 的过滤字段系统(filter fields system)去替你格式化地输出信息。"default"或"", sysdig 添加它的默认格式到chisel。on_event() 返回true 的时候才会打印信息,且chisel 的输出不会被命令行-p 选项覆盖。

chisel.set_interval_s(interval)
为当前chisel 设置一个周期性的调用。使用这个函数,需要chisel 包含on_interval()函数,sysdig 引擎会以interval 秒的间隔循环调用

chisel.set_interval_ns(interval)
和set_interval_s 类似,不过更精细的时间设置

evt library

这个库的函数有关于正在被处理的事件,所以只能被 on_event() 函数调用

evt.get_cpuid()
返回捕获到事件的CPU的编号

evt.field(fld)
从事件中提取特定特定字段的值。参数fld是从上一个requet_field()调用中获得的字段句柄。函数返回字段的值,可能是个数字或者字符串。sysdig -lv 命令可以查看每个导出字段的类型。
注意:

  • 如果请求的字段没有被事件导出(例如非I/O事件不会导出fd.name 字段),返回值为 nil (Lua 中表示只有一个值的一种类型)
  • evt.rawarg 字段需要注意。它能用来提取任意系统调用的参数,如 evt.rawarg.res,所以它的类型取决于你询问的字段

evt.get_num()
返回递增的事件编号

evt.get_ts()
返回两个分别代表事件原始时间戳的秒和纳秒部分的时间戳

evt.get_type()
以数字形式返回事件类型。能用来事件过滤。事件类型编码可以在driver/ppm_event_events_public.h的ppm_event_type 枚举中查看
参考资料:
https://github.com/draios/sysdig/wiki/Chisels-User-Guide
https://github.com/draios/sysdig/wiki/Writing-a-Sysdig-Chisel%2C-a-Tutorial
https://github.com/draios/sysdig/wiki/Sysdig-Chisel-API-Reference-Manual

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,739评论 2 9
  • JavaScript语言精粹 前言 约定:=> 表示参考相关文章或书籍; JS是JavaScript的缩写。 本书...
    微笑的AK47阅读 578评论 0 3
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,374评论 0 5
  • 嗨,你好,我是邓淑丽,今天我们一起来学习“那”和“哪”的区别。不知道你会不会有这种感受,“那”和“哪”这两个字很简...
    邓小邓老师阅读 652评论 0 0
  • ​你家的门口应该铺满鲜花,我记得那个叫“易初”的莲花的名字… ​ ​道家园,延静东里,延静里,道家村,甜水园北里,...
    戌年可遇阅读 324评论 0 0