使用Falco检测针对应用的入侵
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将会捕捉到所有的访问请求: