1、什么是Falco
Falco是一款由Sysdig开源的进程异常行为检测工具。它既能够检测传统主机上的应用程序,也能够检测容器环境和云平台(主要是Kubernetes和Mesos)。
它能够检测所有涉及系统调用的进程行为。例如:
- 某容器中启动了一个shell
- 某服务进程创建了一个非预期类型的子进程
- /etc/shadow文件被读写
- /dev目录下创建了一个非设备文件
- ls之类的常规系统工具向外进行了对外网络通信
此外,其还可以检测云环境下的特有行为。例如:
-
创建了带有特权容器、挂载敏感路径或使用了宿主机网络的Pod
-
向用户授予大范围权限(例如cluster-admin)
-
创建了带有敏感信息的configmap
那么,Falco与传统的主机安全检测工具有什么不同呢?
#1.Falco主要依赖于底层Sysdig内核模块提供的系统调用事件流,与用户态工具通过定时采样或轮询方式实现的离散式监控不同,它提供的是一种连续式实时监控功能;
#2.与工作在内核层进行系统调用捕获、过滤和监控的工具相比,Falco自身运行在用户空间,仅仅借助内核模块来获得数据,Falco的规则变更和程序起止要更为灵活;
#3.与其他既工作内核层又提供用户空间接口的工具相比,Falco具有非常易学的规则语法(可以与SELinux的规法对比)和对云环境的支持。
Falco采用C++语言编写,但它提供了丰富的告警输出方式(后面会提到),因此能够非常方便地与其他工具协同工作。
2、程序架构
在进入细节之前,我们希望给出一个“俯瞰”视角,以帮助您建立一个关于Falco的整体概念。
总体来讲,Falco是一个基于规则的进程异常行为检测工具,它目前支持的事件源有两种:
-
Sysdig内核模块
-
Kubernetes审计日志
其中,Sysdig内核模块提供的是整个宿主机上的实时系统调用事件信息,是Falco依赖的核心事件源。
另外,Falco支持五种输出告警的方式:
-
输出到标准输出
-
输出到文件
-
输出到Syslog
-
输出到HTTP服务
-
输出到其他程序(命令行管道方式)
值得一提的是,最后两种方式使得我们能够很容易将Falco与其他组件或框架组合起来。
下图展示了它的基本架构:
其中,紫色模块为Falco目前支持的输入事件源,绿色模块为目前支持的输出方式,蓝色模块即Falco用户态程序。
3、工作原理
Falco采用类似于iptables的规则匹配方式来检测异常。它自带了一份规则文件/etc/falco/falco_rules.yaml 供使用,我们也可以将自己定义的规则放在/etc/falco/falco_rules.local.yaml文件中。
它的异常检测流程是直观的。以系统调用为例:Sysdig内核模块首先加载,用户态的Falco运行后读取并解析本地配置文件和规则文件、初始化规则引擎;一旦有进程做了系统调用,内核模块将捕获到这次调用,并把详细信息传给Falco,Falco对这些信息作规则匹配,如果满足规则就通过约定好的方式输出告警。上述工作流程可以表示如下:
规则介绍
Falco的规则使用 YAML 描述,一个规则文件(如 /etc/falco/falco_rules.yaml)包含三类元素:
-
规则:一条规则是描述“在什么条件下生成什么样的告警”的规定
-
宏:这里宏的意义与C语言中的基本相同,它是一些“判定条件片段”,能够在不同的规则甚至宏中复用
-
列表:即元素集合,能够被规则、宏或者其他列表使用
从层次上来说,基础条件表达式、列表和宏一起构成规则,规则是最直接被Falco用来判断某一行为是否异常的依赖标准。一条规则至少由以下必需项构成:规则名、条件、描述文字、输出信息和优先级。
二、文件输出方式
步骤
前提条件:为此我们需要一个有效的Kubernetes设置。你可以使用AWS/GCP提供的云Kubernetes,也可以使用minikube在本地设置一个。我们还要求kubectl和Helm安装在你的客户端机器上。
让我们从Falco的安装开始。
1. 在Helm中添加falcosecurity仓库
$ helm repo add falcosecurity https://falcosecurity.github.io/charts
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "falcosecurity" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
2. 安装chart
$ helm install falco falcosecurity/falco \
--set falco.jsonOutput=true \
--set falco.fileOutput.enabled=true,falco.fileOutput.keepAlive=true,falco.fileOutput.filename=/mnt/events.txt #这里我们安装时打开文件文件输出以及定义日志文件位置
NAME: falco
LAST DEPLOYED: Mon Nov 9 22:09:28 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Falco agents are spinning up on each node in your cluster. After a few
seconds, they are going to start monitoring your containers looking for
security issues.
No further action should be required.
3. 几秒钟后Falco应该开始运行,验证一下,你马上就会看到你创建的pod。
$ helm ls
$ kubectl get pods
4.我们使用nfs持久化保存日志文件
#安装nfs
#master节点作为nfs服务端,node节点作为客户端
#master节点安装nfs
$yum install -y nfs-utils rpcbind
#node节点安装nfs
$ yum install -y nfs-utils
$ yum install -y nfs-utils
#配置nfs
$vim /etc/exports
/nfsdata *(rw,no_root_squash,no_all_squash,sync)
#创建/nfsdata目录并赋权
$mkdir /nfsdata
$chmod 775 -R /nfsdata
#启动nfs和rpcbind服务
$systemctl start rpcbind
$systemctl start nfs
#node节点查看master共享目录
$showmount -e {NFS服务节点ip}
Export list for {NFS服务节点ip}:
/nfsdata *
5.创建pv以及pvc
创建顺序:后端存储—pv—pvc—pod
PV :PersistentVolume(持久化卷),是对底层的共享存储的一种抽象,PV由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、GlusterFS、NFS等,都是通过插件机制完成与共享存储的对接
#vim pv1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
labels:
app: nfs
spec:
capacity: #指定 PV 的容量为 1G
storage: 1Gi
accessModes: #指定访问模式
- ReadWriteOnce #PV 能以 read-write 模式 mount 到单个节点
persistentVolumeReclaimPolicy: Recycle #指定当 PV 的回收策略为 Recycle
storageClassName: nfs #指定 PV 的 class 为 nfs。相当于为 PV 设置了一个分类,PVC 可以指定 class 申请相应 class 的 PV
nfs:
path: /nfsdata
server: 192.168.56.132 #nfs服务端ip
创建pv
$kubectl apply -f pv1.yaml
$persistentvolume/pv1 created
查看pv
$kubectl get pv
创建pvc的yaml文件
#vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes: #指定访问模式
ReadWriteOnce #PV 能以 read-write 模式 mount 到单个节点
resources:
requests:
storage: 1Gi
storageClassName: nfs
创建pvc
$kubectl apply -f pvc.yml
persistentvolumeclaim/pvc1 created
#查看pvc
$kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pv1 1Gi RWO nfs 3s
#查看pv和pvc是否绑定
kubectl get pv
6.创建falco的yaml部署文件
$kubectl get daemonsets.apps falco -o=yaml > falco.yaml
添加文件中的挂载目录
volumeMounts:
·····
- mountPath: /mnt
name: events-volume
·····
- name: events-volume
persistentVolumeClaim:
claimName: pvc1
删除未挂载文件的Daemonset,创建新的Daemonset
$kubectl delete daemonsets.apps falco
$kubectl apply -f falco.yaml
7.创建pod进行动作测试,查看动作是否记录至日志文件
创建 NGINX Pod:
$ kubectl run --generator=run-pod/v1 nginx --image=nginx
进入NGINX pod中,cat敏感文件/etc/shadow
$kubectl exec -it nginx -- bash
$cat /etc/shadow
查看日志文件是否记录以上两个动作