falco 规则
tags: falco,安全
文章目录
falco 规则
1. 简介
2. 版本控制
2.1 Falco 引擎版本控制
2.2 Falco rule文件版本控制
3. 关键词
4. 语法
4.1 condition
4.2 rule operators
4.3 rule macro
4.4 rule list
4.4.1 附加到列表
4.4.2 附加到宏
4.4.3 附加到rule
4.5 rule output
4.6 rule priorities
4.7 rule tags
4.8 fd.sip.name
4.9 rule exceptions
4.9.1 Appending Exception Values
4.9.2 Exceptions Syntax Shortcuts
5. 转义特殊字符
6. rule 文件
6.1 默认 rule 文件
6.2 本地 rule 文件
7. rule 禁用默认
7.1 通过现有的宏
7.2 通过 Falco 参数
7.3 通过自定义rule定义
8. rule 陷阱
{% youtube %}
https://www.youtube.com/watch?v=M3f6-ioY9rs
{% endyoutube %}
上篇文章我们对falco 进行简单的入门,其中涉及到、架构、特点、安装、部署、运行等,接下来我们了解 falco 的 rules。
1. 简介
Falcorule文件是包含三种元素的YAML文件:
还有两个与版本控制相关的可选元素:
元素 | 描述 |
required_engine_version | 用于跟踪rule内容和 falco引擎版本之间的兼容性。 |
required_plugin_versions | 用于跟踪rule内容和插件版本之间的兼容性。 |
2. 版本控制
有时,我们会更改不向后兼容旧版本 Falco 的rule文件格式。类似地,libsinsp 和 libscap 可以定义新的 filtercheck 字段、操作符等。我们想要表示一组给定的rule依赖于这些库中的字段/操作符。从 Falco 版本0.14.0 开始,Falco rule支持 Falco 引擎和 Falco rule文件的显式版本控制。
2.1 Falco 引擎版本控制
falco可执行文件和falco_engineC++ 对象现在支持返回版本号。初始版本是 2(暗示之前的版本是 1)。每当我们对rule文件格式进行不兼容的更改或向 Falco 添加新的过滤检查字段/运算符时,我们都会增加此版本。
2.2 Falco rule文件版本控制
Falco 包含的 Falco rule文件包括一个新的顶级对象 ,required_engine_version: N它指定读取此rule文件所需的最低引擎版本。如果不包括在内,则在读取rule文件时不执行版本检查。这是一个例子:
# This rules file requires a falco with falco engine version 7. - required_engine_version: 7
如果rule文件的engine_version版本高于 Falco 引擎版本,则会加载rule文件并返回错误。
3. 关键词
4. 语法
4.1 condition
rule的关键部分是条件字段。条件是使用条件语法表示的布尔谓词。可以使用它们各自支持的字段来表达所有支持事件的条件。
这是一个在容器内运行 bash shell 时发出警报的条件示例:
container.id != host and proc.name = bash
第一个子句检查事件是否发生在容器中(其中container.id等于"host"事件是否发生在常规主机上)。第二个子句检查进程名称是否为bash. 由于此条件不包括带有系统调用的子句,它只会检查事件元数据。因此,如果 bash shell 确实在容器中启动,Falco 会为该 shell 执行的每个系统调用输出事件。
如果您只想在容器中每次成功生成 shell 时收到警报,请在条件中添加适当的事件类型和方向:
evt.type = execve and evt.dir=< and container.id != host and proc.name = bash
因此,使用上述条件的完整rule可能是:
- rule: shell_in_container desc: notice shell activity within a container condition: evt.type = execve and evt.dir=< and container.id != host and proc.name = bash output: shell in a container (user=%user.name container_id=%container.id container_name=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline) priority: WARNING
通常都以evt.type表达式或宏开头,安全rule通常一次只考虑一种系统调用类型。例如,您可能希望在打开文件时考虑open或openat捕获可疑活动、execve检查生成的进程等等。您不必猜测系统调用名称,因为您可以查看支持的系统调用事件的完整列表并了解您可以使用哪些事件。
每个系统调用都有一个进入事件和一个退出事件,它们显示在evt.dir字段中,也称为系统调用的“方向”。值>表示入口,在调用系统调用时触发,而<标记退出,表示调用已返回。事实上,通过查看支持的系统调用列表,您可以看到我们的事件有两个条目。例如:
> setuid(UID uid) < setuid(ERRNO res)
大多数情况下,引擎会通知您退出事件,因为您想了解事件执行完成后发生的情况。您可以通过使用与打开文件关联的事件来查看。
> open() < open(FD fd, FSPATH name, FLAGS32 flags, UINT32 mode, UINT32 dev) > openat() < openat(FD fd, FD dirfd, FSRELPATH name, FLAGS32 flags, UINT32 mode, UINT32 dev)
每个事件都有一个与之关联的参数列表,您可以使用evt.arg.<argname>
. 例如,要识别进程何时打开文件以覆盖它,您需要检查标志列表是否包含O_TRUNC
. 您可以使用上面显示的和退出事件的evt.arg.flags
字段,然后rule将如下所示:open
、openat
evt.type in (open, openat) and evt.dir = < and evt.arg.flags contains O_TRUNC
请注意,参数不一定与 Linux 内核中使用的原始参数匹配,而是由 Falco 解析以更容易编写rule。通过使用这些evt字段。
虽然evt字段允许您编写非常有表现力的条件,但参数和公共字段通常不足以编写完整的安全rule。很多时候,您希望根据事件发生的流程上下文添加条件,或者容器内是否正在发生某些事情,甚至将每个事件与集群、pod 等的相关 Kubernetes 元数据相关联。出于这个原因,Falco 用其他字段类丰富了许多事件。
4.2 rule operators
4.3 rule macro
如上所述,宏提供了一种以可重用方式定义rule的公共子部分的方法。通过查看上面的条件,它看起来像两者evt.type = execve and evt.dir=<,并且container.id != host会被其他rule使用很多,所以为了使我们的工作更容易,我们可以轻松地为两者定义宏:
- macro: container condition: container.id != host - macro: spawned_process condition: evt.type = execve and evt.dir=<
定义了这个宏后,我们可以将上述rule的条件重写为spawned_process and container and proc.name = bash
4.4 rule list
列表是可以包含在rule、宏甚至其他列表中的项目的命名集合。请注意,列表不能被解析为过滤表达式。每个列表节点都有以下键:
钥匙 | 描述 |
list | 列表的唯一名称(作为 slug) |
items | 值列表 |
以下是一些示例列表以及使用它们的宏:
- list: shell_binaries items: [bash, csh, ksh, sh, tcsh, zsh, dash] - list: userexec_binaries items: [sudo, su] - list: known_binaries items: [shell_binaries, userexec_binaries] - macro: safe_procs condition: proc.name in (known_binaries)
如果您使用多个 Falco rule文件,您可能希望将新项目附加到现有列表、rule或宏中。为此,请定义一个与现有项目同名的项目并将一个append: true属性添加到列表中。追加列表时,项目被添加到列表的末尾。附加rule/宏时,附加文本附加到条件:rule/宏的字段。
请注意,在附加到列表、rule或宏时,rule配置文件的顺序很重要!例如,如果您附加到现有的默认rule(例如Terminal shell in container),您必须确保您的自定义配置文件(/etc/falco/rules.d/custom-rules.yaml)在默认配置文件(/etc/falco/falco_rules.yaml )之后加载。这可以使用多个参数以正确的顺序配置,直接在 falco 配置文件 (falco.yaml ) 中通过,或者您使用官方 Helm charts。
4.4.1 附加到列表
/etc/falco/falco_rules.yaml
- list: my_programs items: [ls, cat, pwd] - rule: my_programs_opened_file desc: track whenever a set of programs opens a file condition: proc.name in (my_programs) and (evt.type=open or evt.type=openat) output: a tracked program opened a file (user=%user.name command=%proc.cmdline file=%fd.name) priority: INFO
/etc/falco/falco_rules.local.yaml
- list: my_programs append: true items: [cp]
每当打开文件时,该rulemy_programs_opened_file
都会触发。ls
、cat
、pwd
、cp
4.4.2 附加到宏
/etc/falco/falco_rules.yaml
- macro: access_file condition: evt.type=open - rule: program_accesses_file desc: track whenever a set of programs opens a file condition: proc.name in (cat, ls) and (access_file) output: a tracked program opened a file (user=%user.name command=%proc.cmdline file=%fd.name) priority: INFO
/etc/falco/falco_rules.local.yaml
- macro: access_file append: true condition: or evt.type=openat
该rule将在/使用/文件program_accesses_file时触发ls
、cat
、open
或者openat
4.4.3 附加到rule
/etc/falco/falco_rules.yaml
- rule: program_accesses_file desc: track whenever a set of programs opens a file condition: proc.name in (cat, ls) and evt.type=open output: a tracked program opened a file (user=%user.name command=%proc.cmdline file=%fd.name) priority: INFO
/etc/falco/falco_rules.local.yaml
- rule: program_accesses_file append: true condition: and not user.name=root
该rule将在/用于文件program_accesses_file
时触发,但如果用户是 root 则不会触发ls
、cat
、open
4.5 rule output
rule输出是一个字符串,它可以使用条件可以使用的相同字段%
来执行插值,类似于printf
. 例如:
Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
可以输出:
Disallowed SSH Connection (command=sshd connection=127.0.0.1:34705->10.0.0.120:22 user=root user_loginu
请注意,不必在特定事件中设置所有字段。正如您在上面的示例中看到的,如果连接发生在容器外部,则%container.image.repository
不会设置该字段,<NA>
而是显示该字段。
4.6 rule priorities
每条 Falco rule都有一个优先级,表明违反rule的严重程度。优先级包含在消息/JSON 输出/等中。以下是可用的优先级:
EMERGENCY
ALERT
CRITICAL
ERROR
WARNING
NOTICE
INFORMATIONAL
DEBUG
用于为rule分配优先级的一般准则如下:
如果rule与写入状态(即文件系统等)有关,则其优先级为ERROR.
如果一条rule与未经授权的状态读取有关(即读取敏感文件等),则其优先级为WARNING.
如果rule与意外行为(在容器中生成意外 shell、打开意外网络连接等)相关,则其优先级为NOTICE.
如果rule与违反良好实践的行为(意外的特权容器、具有敏感挂载的容器、以 root 身份运行交互式命令)有关,
则其优先级为INFO.
4.7 rule tags
从 0.6.0 开始,rule具有一组可选标签,用于将rule集分类为相关rule组。这是一个例子:
- rule: File Open by Privileged Container desc: Any open by a privileged container. Exceptions are made for known trusted images. condition: (open_read or open_write) and container and container.privileged=true and not trusted_containers output: File opened for read/write by privileged container (user=%user.name command=%proc.cmdline %container.info file=%fd.name) priority: WARNING tags: [container, cis]
标签的使用方法:
您可以使用该-T <tag>参数禁用具有给定标签的rule。-T可以指定多次。例如,要跳过所有带有“filesystem”和“cis”标签的rule,你可以使用falco -T filesystem -T cis ...., -T不能用 指定-t。
您可以使用该-t 参数仅运行具有给定标记的rule。-t可以指定多次。例如,要仅使用“filesystem”和“cis”标签运行这些rule,您可以使用falco -t filesystem -t cis .... ,-t不能用-Tor指定-D <pattern>(通过rule名称正则表达式禁用rule)
当前 Falco rule集的标签
我们还检查了默认rule集,并用一组初始标签标记了所有rule。以下是我们使用的标签: