CNCF项目Falco是一个Kubernetes威胁检测引擎,它通过观察应用程序和容器的行为来检测运行时威胁,更可使用Falco插件扩展跨云环境下的威胁检测功能。 Falco使用一系列传感器(Sensor)收集不同来源的事件,并根据可定制的规则来过滤出其中值得关注的信息。其基本工作方式如图所示: 基于Falco的数据来源,其可以检测到诸如:Privilege escalationsAccess to sensitive dataOwnership and mode changesUnexpected network connections or socket mutationsUnwanted program executionData exfiltrationCompliance violations 等多种安全威胁事件。 Falco自带有一套现成的规则,存放于/etc/falco目录下: 这些现成的规则,针对的是对Kubernetes、Linux、及Container的威胁检测。我们也可以参考这些规则,开发出额外一些针对应用的威胁检测,满足客户的关切。下面就此举一、两则例子,供大家参考。Falco安装 Falco可以直接安装在Linux主机上,也可部署在Kubernetes集群上。需要注意的是,如果是在minikube、kind等环境中部署,有一些特别之处,请参考https://falco.org/docs/getting-started/third-party/learning/。 这里是直接在Kubernetes本地集群上、使用helm进行部署: helm repo add falcosecurity https://falcosecurity.github.io/charts helm repo update helm install falco --set ebpf.enabled=true falcosecurity/falco 如一切顺利,falco将会被部署到default namespce上,并使用eBPF探针方式代替缺省的Linux核心模块方式。 (为不影响性能,Falco的输出是有缓冲的,所以有一个比较大的延时。如果没有意识到该点,初用者会误以为它没在工作!在非生产环境中,建议通过设置tty为true来让它实时输出:helm upgrade falco falcosecurity/falco --set tty=true) Falco检测对应用的威胁侦测使用attached terminal方式进入容器 Falco有一条"Terminal shell in container"的规则,所以每当我们以这种方式进行容器时,Falco会产生如下log: 06:16:22.801863338: Notice A shell was spawned in a container with an attached terminal (user=root user_loginuid=-1 k8s.ns=default k8s.pod=service-a-ccbb8955-l7qs6 container=d07dcc237595 shell=sh parent=runc cmdline=sh terminal=34816 container_id=d07dcc237595 image=docker.io/biandayu/simple-service)侦测对应用所在目录的写操作 假设有一个Spring Boot应用,镜像为biandayu/simple-service。容器化后,应用所在目录为/app。如果我们希望侦测该目录下的写操作,可以按如下方式进行—— 创建一个名为my_rules.yaml的文件,其内容如下: customRules: my_rules: |- - list: myapp_directories items: [/app, /app/lib, /app/hello, /app/META-INF] - macro: monitored_myapp_dir condition: fd.directory in (myapp_directories) - rule: Write myapp directory desc: an attempt to write to any file of myapp condition: > evt.dir = < and open_write and monitored_myapp_dir and container.image.repository contains "biandayu/simple-service" output: > File below a myapp directory opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, myapp] 使用helm upgrade falco falcosecurity/falco --reuse-values -f my_rules.yaml升级Falco。 升级完成后,如果我们在上述应用容器中的/app目录下,使用touch方式写入一个新文件,则会在Falco的log中找到如下信息: 06:25:16.920675477: Error File below a myapp directory opened for writing (user=root user_loginuid=-1 command=touch should_not_here file=/app/should_not_here parent=sh pcmdline=sh gparent= container_id=d07dcc237595 image=docker.io/biandayu/simple-service) k8s.ns=default k8s.pod=service-a-ccbb8955-l7qs6 container=d07dcc237595侦测对应用的网络访问 /etc/falco/rules.available/application_rules.yaml中有针对流行应用编写的一些Falco规则,其中大多数为侦测非特定端口的访问请求。比如HTTP的标准端口是80、443,如果访问的不是这两下端口,则为非正常访问请求。 为简单地演示该功能,这里准备了一个记录所有访问请求的规则,不建议在真实环境中使用。 将下面这段添加到my_rules.yaml文件中: - rule: All inbound connection of myapp desc: Detect any inbound connection condition: > inbound and container.image.repository contains "biandayu/simple-service" output: Inbound connection source (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [network, myapp] 再次使用helm upgrade falco falcosecurity/falco --reuse-values -f my_rules.yaml升级Falco。 升级成功后,现在再访问示例应用,Falco将会捕捉到所有的访问请求: