分析容器系统调用:Sysdig

Sysdig:一个非常强大的系统监控、分析和故障排查工具。

汇聚strace+tcpdump+htop+iftop+lsof工具与一身

sysdig除了能获取系统资源利用率、进程、网络连接、系统调用等信息,还具备了很强的分析能力,例如:

  • 按照CPU使用率对进程排序
  • 按照数据包对进程排序
  • 打开最多的文件描述符进程
  • 查看进程打开了那些文件
  • 查看进程的http请求报文
  • 查看机器上容器列表及资源使用情况

项目地址:https://github.com/draios/sysdig

文档:https://github.com/draios/sysdig/wiki

https://docs.sysdig.com/en/docs/installation/sysdig-monitor/install-sysdig-agent/kubernetes/

sysdig通过在内核的驱动模块注册系统调用的hook,这样当有系统调用发生和完成时,他会把系统调用信息拷贝到特定的buffer,然后用户态组件对数据信息处理(解压、解析、过滤等),并最终通过sysdig命令和用户进行交互。

6、监控、审计和运行时安全 - 图1

宿主机安装

文档:https://github.com/draios/sysdig/wiki/How-to-Install-Sysdig-for-Linux

  1. rpm --import https://s3.amazonaws.com/download.draios.com/DRAIOS-GPG-KEY.public
  2. curl -s -o /etc/yum.repos.d/draios.repo https://s3.amazonaws.com/download.draios.com/stable/rpm/draios.repo
  3. yum install epel-release -y
  4. yum install sysdig -y
  5. /usr/bin/sysdig-probe-loader # 加载驱动模块
  • 下载rpm
  1. yum install -y sysdig --downloadonly --downloaddir=./sysdig
  2. rpm -ivh sysdig/*.rpm --nodeps

sysdig常用参数:

中文文档:https://cizixs.com/2017/04/27/sysdig-for-linux-system-monitor-and-analysis/

  1. -l, --list:列出可用于过滤和输出的字段
  2. -M <num_seconds> :多少秒后停止收集
  3. -p <output_format>, --print=<output_format> :指定打印事件时使用的格式
  4. 使用-pc或-pcontainer 容器友好的格式
  5. 使用-pk或-pkubernetes k8s友好的格式
  6. -c <chiselname> <chiselargs>:指定内置工具,可直接完成具体的数据聚合、分析工作
  7. -w <filename>:保存到文件中
  8. -r <filename>:从文件中读取

执行sysdig命令,实时输出大量系统调用

实例: 59509 23:59:19.023099531 0 kubelet (1738) < epoll_ctl

格式: %evt.num %evt.outputtime %evt.cpu %proc.name (%thread.tid) %evt.dir %evt.type %evt.info

  1. evt.num 递增的事件号
  2. evt.time 事件发生的时间
  3. evt.cpu 事件被捕获时所在的 CPU,也就是系统调用是在哪个 CPU 执行的
  4. proc.name 生成事件的进程名字
  5. thread.tid 线程的 id,如果是单线程的程序,这也是进程的 pid
  6. evt.dir 事件的方向(direction),> 代表进入事件,< 代表退出事件
  7. evt.type 事件的名称,比如 openstat等,一般是系统调用
  8. evt.args 事件的参数。如果是系统调用,这些对应着系统调用的参数
  • 自定义格式输出:sysdig -p “user:%user.name time:%evt.time proc_name:%proc.name”

sysdig过滤

  1. fd:根据文件描述符过滤,比如 fd 标号(fd.num)、fd 名字(fd.name
  2. process:根据进程信息过滤,比如进程 idproc.id)、进程名(proc.name
  3. evt:根据事件信息过滤,比如事件编号、事件名
  4. user:根据用户信息过滤,比如用户 id、用户名、用户 home 目录
  5. syslog:根据系统日志过滤,比如日志的严重程度、日志的内容
  6. container:根据容器信息过滤,比如容器ID、容器名称、容器镜像

查看完整过滤器列表:sysdig -l

示例:

  1. 1、查看一个进程的系统调用
  2. sysdig proc.name=kubelet
  3. 2、查看建立TCP连接的事件
  4. sysdig evt.type=accept
  5. 3、查看/etc目录下打开的文件描述符
  6. sysdig fd.name contains /etc
  7. 4、查看容器的系统调用
  8. sysdig -M 10 container.name=web

注:还支持运算操作符,=

、!=、>=、>、<、

<=、contains、in 、exists、and、or、not

  1. Chisels:实用的工具箱,一组预定义的功能集合,用来分析特定的场景。
  2. sysdig cl 列出所有Chisels,以下是一些常用的:
  3. topprocs_cpu:输出按照 CPU 使用率排序的进程列表,例如sysdig -c
  4. topprocs_net:输出进程使用网络TOP
  5. topprocs_file:进程读写磁盘文件TOP
  6. topfiles_bytes:读写磁盘文件TOP
  7. netstat:列出网络的连接情况
网络 shell # 查看使用网络的进程TOP sysdig -c topprocs_net # 查看建立连接的端口 sysdig -c fdcount_by fd.sport "evt.type=accept" -M 10 # 查看建立连接的端口 sysdig -c fdbytes_by fd.sport # 查看建立连接的IP sysdig -c fdcount_by fd.cip "evt.type=accept" -M 10 # 查看建立连接的IP sysdig -c fdbytes_by fd.cip
硬盘 shell # 查看进程磁盘I/O读写 sysdig -c topprocs_file # 查看进程打开的文件描述符数量 sysdig -c fdcount_by proc.name "fd.type=file" -M 10 # 查看读写磁盘文件 sysdig -c topfiles_bytes sysdig -c topfiles_bytes proc.name=etcd # 查看/tmp目录读写磁盘活动文件 sysdig -c fdbytes_by fd.filename "fd.directory=/tmp/"
CPU shell # 查看CPU使用率TOP sysdig -c topprocs_cpu # 查看容器CPU使用率TOP sysdig -pc -c topprocs_cpu container.name=web sysdig -pc -c topprocs_cpu container.id=web
容器 shell # 查看机器上容器列表及资源使用情况 csysdig -vcontainers # 查看容器资源使用TOP sysdig -c topcontainers_cpu/topcontainers_net/topcontainers_file

其他常用命令:

  1. sysdig -c netstat
  2. sysdig -c ps
  3. sysdig -c lsof

k8s集群部署

https://docs.sysdig.com/en/docs/installation/sysdig-monitor/install-sysdig-agent/kubernetes/

  1. helm repo add sysdig https://charts.sysdig.com
  2. helm repo update
  3. helm install sysdig-agent --namespace sysdig-agent --create-namespace \
  4. --set global.sysdig.accessKey=<ACCESS_KEY> \
  5. --set global.sysdig.region=<SAAS_REGION> \
  6. --set nodeAnalyzer.enabled=false \
  7. --set global.clusterConfig.name=<CLUSTER_NAME> \
  8. sysdig/sysdig-deploy

监控容器运行时:Falco

项目地址:https://github.com/falcosecurity/falc

https://developer.aliyun.com/article/1113077

  1. Falco 是一个 Linux 安全工具,它使用系统调用来保护和监控系统。
  2. Falco最初是由Sysdig开发的,后来加入CNCF孵化器,成为首个加入CNCF的运行时安全项目。
  3. Falco提供了一组默认规则,可以监控内核态的异常行为,例如:
  4. 对于系统目录/etc, /usr/bin, /usr/sbin的读写行为
  5. 文件所有权、访问权限的变更
  6. 从容器打开shell会话
  7. 容器生成新进程
  8. 特权容器启动

6、监控、审计和运行时安全 - 图2

docker方式部署

https://www.ebpf.top/post/hello_falco/

  1. docker run --rm -i -t \
  2. --privileged \
  3. -e FALCO_BPF_PROBE="" \
  4. -v /var/run/docker.sock:/host/var/run/docker.sock \
  5. -v /dev:/host/dev \
  6. -v /proc:/host/proc:ro \
  7. -v /boot:/host/boot:ro \
  8. -v /lib/modules:/host/lib/modules:ro \
  9. -v /usr:/host/usr:ro \
  10. -v /etc:/host/etc:ro \
  11. falcosecurity/falco:latest
  12. repos.cloud.cmft/ruoyi/falco:latest
  13. docker run --rm -i -t \
  14. > --privileged \
  15. > -v /root/.falco:/root/.falco \
  16. > -v /proc:/host/proc:ro \
  17. > -v /boot:/host/boot:ro \
  18. > -v /lib/modules:/host/lib/modules:ro \
  19. > -v /usr:/host/usr:ro \
  20. > -v /etc:/host/etc:ro \
  21. > falcosecurity/falco-driver-loader:latest bpf --compile
  • 转换成k8s
  1. kind: DaemonSet
  2. apiVersion: apps/v1
  3. metadata:
  4. name: falco
  5. namespace: default
  6. labels:
  7. app: falco
  8. spec:
  9. selector:
  10. matchLabels:
  11. app: falco
  12. template:
  13. metadata:
  14. labels:
  15. app: falco
  16. spec:
  17. volumes:
  18. - name: host-time
  19. hostPath:
  20. path: /etc/localtime
  21. type: ''
  22. - name: runtime-sockt
  23. hostPath:
  24. path: /var/run/docker.sock
  25. type: ''
  26. - name: dev
  27. hostPath:
  28. path: /dev
  29. type: ''
  30. - name: proc
  31. hostPath:
  32. path: /proc
  33. type: ''
  34. - name: boot
  35. hostPath:
  36. path: /boot
  37. type: ''
  38. - name: modules
  39. hostPath:
  40. path: /lib/modules
  41. type: ''
  42. - name: usr
  43. hostPath:
  44. path: /usr
  45. type: ''
  46. - name: etc
  47. hostPath:
  48. path: /etc
  49. type: ''
  50. containers:
  51. - name: falco
  52. image: 'repos.cloud.cmft/ruoyi/falco:latest'
  53. ports:
  54. - name: http-0
  55. containerPort: 8765
  56. protocol: TCP
  57. env:
  58. - name: FALCO_BPF_PROBE
  59. value: '""'
  60. resources:
  61. limits:
  62. cpu: '1'
  63. memory: 1000Mi
  64. requests:
  65. cpu: 100m
  66. memory: 100Mi
  67. volumeMounts:
  68. - name: host-time
  69. readOnly: true
  70. mountPath: /etc/localtime
  71. - name: runtime-sockt
  72. readOnly: true
  73. mountPath: /host/var/run/docker.sock
  74. - name: dev
  75. mountPath: /host/dev
  76. - name: proc
  77. readOnly: true
  78. mountPath: /rpoc
  79. - name: boot
  80. readOnly: true
  81. mountPath: /host/boot
  82. - name: modules
  83. readOnly: true
  84. mountPath: /host/lib/modules
  85. - name: usr
  86. readOnly: true
  87. mountPath: /host/usr
  88. - name: etc
  89. readOnly: true
  90. mountPath: /host/etc

k8s集群部署

https://falco.org/docs/install-operate/deployment/

https://github.com/falcosecurity/charts/tree/master/charts/falco

https://falco.org/docs/install-operate/deployment/

https://github.com/falcosecurity/deploy-kubernetes/tree/main/kubernetes/falco/templates

  1. helm repo add falcosecurity https://falcosecurity.github.io/charts
  2. helm repo update
  3. helm search repo falco
  4. NAME CHART VERSION APP VERSION DESCRIPTION
  5. falcosecurity/falco 4.6.0 0.38.1 Falco
  6. falcosecurity/falco-exporter 0.11.0 0.8.3 Prometheus Metrics Exporter for Falco output ev...
  7. falcosecurity/falcosidekick 0.8.1 2.29.0 Connect Falco to your ecosystem
  8. falcosecurity/event-generator 0.3.3 0.10.0 A Helm chart used to deploy the event-generator...
  9. falcosecurity/k8s-metacollector 0.1.8 0.1.1 Install k8s-metacollector to fetch and distribu..
  10. helm pull falcosecurity/falco --version 4.6.0
  11. tar xf falco-4.6.0.tgz
  12. cd falco/
  13. # 修改镜像以及版本号(Charts.yaml)
  14. helm package ./
  15. helm -n ruoyi upgrade --install falco --set driver.kind=ebpf -f values.yaml ./

安装和配置

官方文档:https://falco.org/docs/

安装文档:https://falco.org/zh/docs/installation

  1. # 安装
  2. rpm --import https://falco.org/repo/falcosecurity-3672BA8F.asc
  3. curl -s -o /etc/yum.repos.d/falcosecurity.repo https://falco.org/repo/falcosecurity-rpm.repo
  4. yum install epel-release -y
  5. yum update
  6. yum install falco -y
  7. systemctl start falco
  8. systemctl enable falco
  • 下载二进制
  1. yum install -y falco --downloadonly --downloaddir=./falco
  2. rpm -ivh falco/*.rpm --nodeps
  1. falco配置文件目录:/etc/falco
  2. falco.yaml falco配置与输出告警通知方式
  3. falco_rules.yaml 规则文件,默认已经定义很多威胁场景
  4. falco_rules.local.yaml 自定义扩展规则文件
  5. k8s_audit_rules.yaml K8s审计日志规则

告警规则

  1. #告警规则示例(falco_rules.local.yaml):
  2. - rule: The program "sudo" is run in a container
  3. desc: An event will trigger every time you run sudo in a container
  4. condition: evt.type = execve and evt.dir=< and container.id != host and proc.name = sudo
  5. output: "Sudo run in container (user=%user.name %container.info parent=%proc.pname cmdline=%proc.cmdline)"
  6. priority: ERROR
  7. tags: [users, container]

参数说明:

• rule:规则名称,唯一

• desc:规则的描述

• condition: 条件表达式

• output:符合条件事件的输出格式

• priority:告警的优先级

• tags:本条规则的 tags 分类

  1. 威胁场景测试:
  2. 1、监控系统二进制文件目录读写(默认规则)
  3. 2、监控根目录或者/root目录写入文件(默认规则)
  4. 3、监控运行交互式Shell的容器(默认规则)
  5. 4、监控容器创建的不可信任进程(自定义规则)
  6. 验证:tail -f /var/log/messages(告警通知默认输出到标准输出和系统日志)
  1. # 监控容器创建的不可信任进程规则,在falco_rules.local.yaml文件添加:
  2. - rule: Unauthorized process on nginx containers
  3. condition: spawned_process and container and container.image startswith nginx and not proc.name in (nginx)
  4. desc: test
  5. output: "Unauthorized process on nginx containers (user=%user.name container_name=%container.name container_id=%container.id image=%container.image.repository shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty)"
  6. priority: WARNING

参数解读:

  1. condition表达式解读:
  2. spawned_process 运行新进程
  3. container 容器
  4. container.image startswith nginx nginx开头的容器镜像
  5. not proc.name in (nginx) 不属于nginx的进程名称(允许进程名称列表)
  6. 重启falco应用新配置文件:
  7. systemctl restart falco

告警通知方式

  1. Falco支持五种输出告警通知的方式:
  2. 输出到标准输出(默认启用)
  3. 输出到文件
  4. 输出到Syslog(默认启用)
  5. 输出到HTTP服务
  6. 输出到其他程序(命令行管道方式)

配置输出到指定的文件:<font style="color:#E8323C;">/etc/falco/falco.yaml</font>

  1. 告警配置文件:/etc/falco/falco.yaml
  2. 例如输出到指定文件:
  3. file_output:
  4. enabled: true
  5. keep_alive: true
  6. filename: /var/log/falco_events.log
  • syslog_output:是否写入syslog日志(默认启用)
  • stdout_output:是否写入syslog日志的标准输出(默认启用)
  • json_output: false 是否以json格式写入(默认关闭)

部署Falco UI

6、监控、审计和运行时安全 - 图3

• FalcoSideKick:一个集中收集并指定输出,支持大量方式输出,例如Influxdb、Elasticsearch等

项目地址 https://github.com/falcosecurity/falcosidekick

• FalcoSideKick-UI:告警通知集中图形展示系统

项目地址 https://github.com/falcosecurity/falcosidekick-ui

https://github.com/Only303/falcosidekick

  1. docker run -d \
  2. -p 2801:2801 \
  3. --name falcosidekick \
  4. -e WEBUI_URL=http://192.168.31.71:2802 \
  5. falcosecurity/falcosidekick
  6. docker run -d \
  7. -p 2802:2802 \
  8. --name falcosidekick-ui \
  9. falcosecurity/falcosidekick-ui
  1. 修改falco配置文件指定http方式输出:
  2. json_output: true
  3. json_include_output_property: true
  4. http_output:
  5. enabled: true
  6. url: "http://192.168.31.71:2801/"

kubernetes日志审计

在Kubernetes集群中,API Server的审计日志记录了哪些用户、哪些服务请求操作集群资源,并且可以编写不同规则,控制忽略、存储的操作日志。

审计日志采用JSON格式输出,每条日志都包含丰富的元数据,例如请求的URL、HTTP方法、客户端来源等,你可以使用监控服务来分析API流量,以检测趋势或可能存在的安全隐患。

  1. 这些可能会访问API Server
  2. 管理节点(controller-managerscheduler
  3. 工作节点(kubeletkube-proxy
  4. 集群服务(CoreDNSHPACalico等)
  5. kubectlAPIDashboard

事件和阶段:

当客户端向 API Server发出请求时,该请求将经历一个或多个阶段:

阶段 说明
RequestReceived 审核处理程序已收到请求
ResponseStarted 已发送响应标头,但尚未发送响应正文
ResponseComplete 响应正文已完成,不再发送任何字节
Panic 内部服务器出错,请求未完成

6、监控、审计和运行时安全 - 图4

Kubernetes审核策略文件包含一系列规则,描述了记录日志的级别,

采集哪些日志,不采集哪些日志

级别 说明
None 不为事件创建日志条目
Metadata 创建日志条目。包括元数据,但不包括请求正文或响应正文
Request 创建日志条目。包括元数据和请求正文,但不包括响应正文
RequestResponse 创建日志条目。包括元数据、请求正文和响应正文

6、监控、审计和运行时安全 - 图5

审计日志支持写入本地文件和Webhook(发送到外部HTTP API)两种方式。 启用审计日志功能:

  1. vi /etc/kubernetes/manifests/kube-apiserver.yaml
  2. ...
  3. # 添加日志审计
  4. - --audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml
  5. - --audit-log-path=/var/log/k8s_audit.log
  6. - --audit-log-maxage=30
  7. - --audit-log-maxbackup=10
  8. - --audit-log-maxsize=100
  9. ...
  10. # 挂在到容器中的目录
  11. - mountPath: /etc/kubernetes/audit
  12. name: audit
  13. readOnly: true
  14. # 挂在日志文件
  15. - mountPath: /var/log/k8s_audit.log
  16. name: audit-log
  17. ...
  18. # 挂在宿主机目录
  19. volumes:
  20. - hostPath:
  21. path: /etc/kubernetes/audit
  22. type: DirectoryOrCreate
  23. name: audit
  24. # 挂在日志文件(宿主机上需要提前创建该日志文件)
  25. volumes:
  26. - hostPath:
  27. path: /var/log/k8s_audit.log
  28. type: File
  29. name: audit-log

audit-policy-file 审计日志策略文件

audit-log-path 审计日志输出文件

audit-log-maxage 审计日志保留的最大天数

audit-log-maxbackup 审计日志最大分片存储多少个日志文件

audit-log-maxsize 单个审计日志最大大小,单位MB

  • 注:使用hostpath数据卷将宿主机/etc/kubernetes/audit目录挂载到容器中

示例:只记录指定资源操作日志audit/audit-policy.yaml

  • 注:重新配置改文件无法生效需要(包括重启kubelet),需要kill,apiserver进程或者pod
  1. apiVersion: audit.k8s.io/v1
  2. kind: Policy
  3. # 忽略步骤,不为RequestReceived阶段生成审计日志
  4. omitStages:
  5. - "RequestReceived"
  6. rules:
  7. # 不记录日志
  8. - level: None
  9. users:
  10. - system:apiserver
  11. - system:kube-controller-manager
  12. - system:kube-scheduler
  13. - system:kube-proxy
  14. - kubelet
  15. # 针对资源记录日志
  16. - level: Metadata
  17. resources:
  18. - group: ""
  19. resources: ["pods","services"]
  20. - group: "apps"
  21. resources: ["deployments"]
  22. # 其他资源不记录日志
  23. - level: None

日志解析

因为日志是使用的json格式不便于查看,可以使用jq进行解析

  1. apt-get install jq -y
  2. yum -y install epel-release
  3. yum install jq -y

解析方式如下:(其中一条的日志如下)

  1. echo '{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"a42dc4ff-0b34-4646-9696-6b93fe56ca25","stage":"ResponseComplete","requestURI":"/apis/coordination.k8s.io/v1/namespaces/kube-system/leases/kube-controller-manager?timeout=5s","verb":"update","user":{"username":"system:kube-controller-manager","groups":["system:authenticated"]},"sourceIPs":["192.168.6.31"],"userAgent":"kube-controller-manager/v1.21.5 (linux/amd64) kubernetes/aea7bba/leader-election","objectRef":{"resource":"leases","namespace":"kube-system","name":"kube-controller-manager","uid":"a95ba47c-1a5a-428a-af4f-0116ba3ca697","apiGroup":"coordination.k8s.io","apiVersion":"v1","resourceVersion":"227727"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2021-11-03T01:46:45.514801Z","stageTimestamp":"2021-11-03T01:46:45.518179Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"system:kube-controller-manager\" of ClusterRole \"system:kube-controller-manager\" to User \"system:kube-controller-manager\""}}' | jq
  2. # 解析到的内容
  3. {
  4. "kind": "Event", # 事件
  5. "apiVersion": "audit.k8s.io/v1", # 审计版本
  6. "level": "Metadata", # 级别
  7. "auditID": "a42dc4ff-0b34-4646-9696-6b93fe56ca25", # 审计ID
  8. "stage": "ResponseComplete", # 审计阶段
  9. "requestURI": "/apis/coordination.k8s.io/v1/namespaces/kube-system/leases/kube-controller-manager?timeout=5s", # 请求url
  10. "verb": "update", # 请求方式,操作
  11. "user": { # 请求用户信息
  12. "username": "system:kube-controller-manager",
  13. "groups": [
  14. "system:authenticated"
  15. ]
  16. },
  17. "sourceIPs": [ # 源IP
  18. "192.168.6.31"
  19. ],
  20. "userAgent": "kube-controller-manager/v1.21.5 (linux/amd64) kubernetes/aea7bba/leader-election", #
  21. "objectRef": { # 操作对象
  22. "resource": "leases",
  23. "namespace": "kube-system",
  24. "name": "kube-controller-manager",
  25. "uid": "a95ba47c-1a5a-428a-af4f-0116ba3ca697",
  26. "apiGroup": "coordination.k8s.io",
  27. "apiVersion": "v1",
  28. "resourceVersion": "227727"
  29. },
  30. "responseStatus": { # 响应
  31. "metadata": {},
  32. "code": 200
  33. },
  34. "requestReceivedTimestamp": "2021-11-03T01:46:45.514801Z", # 请求接收时间戳
  35. "stageTimestamp": "2021-11-03T01:46:45.518179Z", #
  36. "annotations": { # 注解
  37. "authorization.k8s.io/decision": "allow",
  38. "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"system:kube-controller-manager\" of ClusterRole \"system:kube-controller-manager\" to User \"system:kube-controller-manager\""
  39. }
  40. }

收集日志审计方案

  1. 收集审计日志方案:
  2. 审计日志文件+filebeat
  3. 审计webhook+logstash
  4. 审计webhook+falco