前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker安全入门与实战(三)

Docker安全入门与实战(三)

作者头像
0xtuhao
发布2022-06-21 10:26:13
7560
发布2022-06-21 10:26:13
举报
文章被收录于专栏:从运维安全到DevSecOps

入侵检测和漏洞扫描可谓是主动发现安全问题的“内功外功”,在容器技术应用越来越广泛的今天,也需要被给予同样的重视。本文将探讨Docker入侵检测工具Sysdig Falco的基础知识以及如何检测容器的异常行为等问题。 Sysdig Falco是一种旨在检测异常活动开源的系统行为监控程序。作为Linux主机入侵检测系统,对待Docker依旧特别有用,因为它支持容器上下文,如container.id,container.image或其规则的命名空间。

原理

虽说Sysdig Falco是一种审计工具,但却与SeccompAppArmor等内核态的审计工具全然不同。 Sysdig Falco在用户空间中运行,使用内核模块拦截系统调用,而其他类似工具在内核级别运行系统调用过滤或监控。用户空间实现的一个好处是能够与Docker编排工具等外部系统集成。

特点

Sysdig Falco具备以下特点:

  • 监控行为或活动
    • 探测通过规则集定义好的异常行为
    • 使用sysdig丰富和强大的过滤表达式
  • 对容器的全面支持
    • 使用sysdig的容器支持
  • 丰富的通知方式
    • 输出报警到文件、标准输出以及syslog
  • 开源
    • 任何人都可以贡献规则或者代码

架构

如下图所示,当发生系统调用时,内核hook会调用sysdig库,产生一个事件,经过Falco规则集的过滤表达式之后产生异常事件,触发报警。

demo

sysdig falco定义的规则非常容易理解,下面可以看几个demo:

  • 容器中执行了shell

container.id != host and proc.name = bash

  • 系统二进制文件被重写

fd.directory in (/bin,/sbin,/usr/bin,/user/sbin) and write

  • 容器namespace发生改变

evt.type = setns and not proc.name in (docker,sysdig)

  • /dev下有非设备文件写入

(evt.type = create or evt.arg.flags contains O_CREAT) and proc.name != blkid and fd.directory = /dev and fd.name != /dev/null

  • 进程试图访问相机

evt.type = open and fd.name = /dev/video0 and not proc.name in (skype,webex)

本文将从以下4个安全威胁场景展示如何使用Sysdig Falco进行异常行为监控:

  • 运行交互式shell的容器
  • 运行未经授权的进程
  • 写入非用户数据目录
  • 容器异常挂载

读者将同时扮演攻击者和防御者(系统管理员)角色,验证Sysdig Falco是否已检测到入侵企图。

部署Sysdig Falco

首先,把构建Sysdig Falco所需要的配置文件放在/etc/falco下:

  • 展示和输出相关的配置
代码语言:javascript
复制
sudo -s
mkdir/etc/falco
cd/etc/falco
curl https://raw.githubusercontent.com/katacoda-scenarios/sysdig-scenarios/master/sysdig-falco/assets/falco.yaml -o falco.yaml

$ cat falco.yaml
#中间大部分省略了,主要是展示和输出相关的配置
# Where security notifications should go.
# Multiple outputs can be enabled.

syslog_output:
  enabled: false

file_output:
  enabled: true
  filename: /var/log/falco_events.log

stdout_output:
  enabled: true

program_output:
  enabled: false
  program: mail -s "Falco Notification" someone@example.com
  • 检测规则的配置
代码语言:javascript
复制
curl ttps://raw.githubusercontent.com/katacoda-scenarios/sysdig-scenarios/master/sysdig-falco/assets/falco_rules.yaml -o falco_rules.yaml

$ cat falco_rules.yaml
#中间大部分省略了,主要是检测规则的配置
- rule: Read sensitive file untrusted
  desc: >
    an attempt to read any sensitive file (e.g. files containing user/password/authentication
    information). Exceptions are made for known trusted programs.
  condition: >
    sensitive_files and open_read
    and not proc.name in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries,
     cron_binaries, read_sensitive_file_binaries, shell_binaries, hids_binaries)
    and not cmp_cp_by_passwd
    and not ansible_running_python
    and not proc.cmdline contains /usr/bin/mandb
  output: >
    Sensitive file opened for reading by non-trusted program (user=%user.name name=%proc.name
    command=%proc.cmdline file=%fd.name)
  priority: WARNING
  tags: [filesystem]
  • log文件创建

touch /var/log/falco_events.log

总而言之,falco.yaml配置Falco服务,falco_rules.yaml配置威胁检测模式,falco_events.log将用作事件日志文件。

然后,我们可以从Dockerhub拉取镜像并启动Sysdig Falco容器,安装我们之前定义的配置文件:

代码语言:javascript
复制
docker pull sysdig/falco
docker run -d --name falco --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v/dev:/host/dev -v/proc:/host/proc :ro -v/boot:/host/boot:ro -v/lib/modules:/host/lib/modules:ro -v/usr:/host/usr:ro -v /etc/falco/falco.yaml: /etc/falco/falco.yaml -v /etc/falco/falco_rules.yaml:/etc/falco/falco_rules.yaml -v /var/log/falco_events.log:/var/log/falco_events.log sysdig/falco

注意:如果不小心终止了容器或想要重新加载配置文件,随时可以重新启动falco。

代码语言:javascript
复制
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUSPORTS               NAMES
81cf560cb4d0        sysdig/falco        "/docker-entrypoint.…"   59 seconds ago      Up 25 seconds                    falco

下面开始进行4个威胁场景的检测演示。

运行交互式shell的容器

我们的第一个例子很简单:检测攻击者在任意容器中运行交互式shell。此警报包含在默认规则集中。让我们先触发它看看,然后再查看规则定义。

在Docker主机上运行容器,例如Nginx:

代码语言:javascript
复制
docker run -d -P --name example1 nginx
docker ps

现在生成一个交互式shell:

docker exec -it example1 bash

如果需要,你可以玩一下,然后运行exit离开容器shell。

如果我们使用>tail /var/log/falco_events.log来打开日志文件,我们应该能够看到类似下面的log:

代码语言:javascript
复制
17:13:24.357351845: Notice A shell was spawned in a container with an attached terminal (user=root example1 (id=604aa46610dd) shell=bash parent=<NA> cmdline=bash terminal=34816)

这是/etc/falco/falco_rules.yaml中触发事件的规则:

代码语言:javascript
复制
- rule: Terminal shell in container
   desc: A shell was spawned by a program in a container with an attached terminal.
   condition: >
     spawned_process and container
     and shell_procs and proc.tty != 0
   output: "A shell was spawned in a container with an attached terminal (user=%user.name %container.info shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty)"
   priority: NOTICE
   tags: [container, shell]

这是一个相当复杂的规则,可能你现在还没有完全理解每个部分,但是看到识别规则名称、描述、一些触发条件、事件输出以及Falco提供的一些上下文感知变量,如proc.name或%container.info,优先级和一些标签。这是sysdig falco的特有语法和配置导致的。

运行未经授权的进程

Docker最佳实践建议每个容器只运行一个进程。这在安全上也是非常有意义,因为你可以轻而易举的发现异常启动的进程。比如说你知道你的Nginx容器应该只运行nginx进程。其他的任意进程都是异常的指标。 让我们为此示例下载配置文件的新版本:

代码语言:javascript
复制
sudo -s
cd/etc/falco
curl https://raw.githubusercontent.com/katacoda-scenarios/sysdig-scenarios/master/sysdig-falco/assets/falco_rules_step3.yaml -o falco_rules.yaml

现在,请注意文件中的以下规则:

代码语言:javascript
复制
# Our nginx containers should only be running the 'nginx' process
 - rule: Unauthorized process on nginx containers
   desc: There is a process running in the nginx container that is not described in the template
   condition: spawned_process and container and container.image startswith nginx and not proc.name in (nginx)
   output: Unauthorized process (%proc.cmdline) running in (%container.id)
   priority: WARNING

让我们剖析这条规则的触发条件,每个条件都是缺一不可的:

  • spawned_process(宏:成功运行新进程)
  • container(宏:运行它的命名空间属于容器而不是主机)
  • 以nginx开头的container.image(容器属性:拥有每个授权进程列表的镜像名称)
  • 不属于nginx(允许的进程名称列表)的proc.name

要应用新配置文件,我们将重新启动Sysdig Falco容器:

docker restart falco

现在我们需要运行一个新的Nginx容器:

docker run -d -P --name example2 nginx

并运行example2容器中的任意内容,例如ls:

代码语言:javascript
复制
$ docker exec -it example2 ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

如果我们使用tail /var/log/falco_events.log查看日志,可以看到类似下面的记录:

代码语言:javascript
复制
$ tail /var/log/falco_events.log
17:16:00.345074348: Notice A shell was spawned in a container with an attached terminal (user=root example1 (id=083bf0190f7e) shell=bash parent=<NA> cmdline=bash  terminal=34816)
17:16:54.625502123: Warning Unauthorized process (ls ) running in (d81ccf05e0a6)

看吧,这个异常捕获得非常漂亮! Sysdig Falco通知显示了一个异常的进程。

写入非用户数据目录

容器不变性意味着运行的容器完全相同,它们不会对从镜像运行的软件进行任意更改,并且任意用户数据都位于外部安装的卷中。当任意进程尝试写入非数据目录时,就让触发警报。 让我们为此示例下载配置文件的新版本:

代码语言:javascript
复制
sudo -s
cd/etc/falco
curl https://raw.githubusercontent.com/katacoda-scenarios/sysdig-scenarios/master/sysdig-falco/assets/falco_rules_step4.yaml -o falco_rules.yaml

注意定义我们为Nginx定制的允许写入目录的宏:

代码语言:javascript
复制
- rule: Write to non user_data dir
   desc: attempt to write to directories that should be immutable
   condition: open_write and container and not user_data_dir
   output: "Writing to non user_data dir (user=%user.name command=%proc.cmdline file=%fd.name)"
   priority: ERROR

我们来看看上面使用的open_write宏:

代码语言:javascript
复制
- macro: open_write
 condition: (evt.type=open or evt.type=openat) and evt.is_open_write=true and fd.typechar='f'

这些条件基于Sysdig系统调用过滤器,在这种情况下,我们过滤打开或openat系统调用,打开模式写入和文件描述符。 要应用新配置文件,我们将重新启动Sysdig Falco容器:

docker restart falco

现在,可以生成一个新容器并尝试以下规则:

代码语言:javascript
复制
docker run -d -P --name example3 nginx
docker exec -it example3 bash
mkdir /userdata
touch /userdata/foo
touch /usr/foo

退出容器并查看日志文件tail /var/log/falco_events.log。你会发现两个异常事件:

代码语言:javascript
复制
$ tail /var/log/falco_events.log
...
17:19:23.529937252: Error Writing to non user_data dir (user=root command=bash  file=/dev/tty)
17:19:23.540872232: Error Writing to non user_data dir (user=root command=touch /usr/foo file=/usr/foo)

第一个事件是因为运行交互式shell写入/dev/tty,这是正常的和符合预期的。第二个事件是Falco检测到写入/usr的异常文件。

通过容器进行敏感挂载

容器通常具有已定义且不经常更改的挂载点集合。如果容器尝试在允许的目录集之外安装主机目录或文件,则可能是某人试图突破容器,或者是团队成员为容器开放了太大的权限。 让我们为此示例下载配置文件的新版本:

代码语言:javascript
复制
sudo -s
cd/etc/falco
curl https://raw.githubusercontent.com/katacoda-scenarios/sysdig-scenarios/master/sysdig-falco/assets/falco_rules_step5.yaml -o falco_rules.yaml

这是监视容器敏感挂载的规则:

代码语言:javascript
复制
- rule: Launch Sensitive Mount Container
desc: >
  Detect the initial process started by a container that has a mount from a sensitive host directory
  (i.e. /proc). Exceptions are made for known trusted images.
condition: evt.type=execve and proc.vpid=1 and container and sensitive_mount and not trusted_containers
output: Container with sensitive mount started (user=%user.name command=%proc.cmdline %container.info)
priority: INFO
tags: [container, cis]

宏sensitive_mount包含禁用目录。默认情况下,它只是监视/proc,但在我们的配置文件中,我们已经修改为包含/mnt了。

代码语言:javascript
复制
- macro: sensitive_mount
condition: (container.mount.dest[/proc*] != "N/A" or container.mount.dest[/mnt*] != "N/A")

要应用新配置文件,我们将重新启动Sysdig Falco容器:

docker restart falco

现在,可以生成一个新容器并尝试mount /mnt:

代码语言:javascript
复制
docker run -d -P --name example4 -v/mnt:/tmp/mnt alpine

如果我们使用tail /var/log/falco_events.log查看日志,可能会看到:

代码语言:javascript
复制
17:21:07.360913099: Informational Container with sensitive mount started (user=root command=sh  example4(id=c35126bf862a))

Sysdig Falco通知显示它检测到敏感的挂载。

事件发生器

Falco有一个合成事件生成器,可以显示默认规则集的所有功能。这非常适合全面了解Sysdig Falco的所有功能。

让我们拉取镜像并启动事件生成器:

代码语言:javascript
复制
docker pull sysdig/falco-event-generator
docker run -d --name falco-event-generator sysdig/falco-event-generator

如果我们使用tail -f /var/log/falco_events.log查看日志,将看到检测到许多可疑行为,因为该容器模拟了各种典型的容器入侵和突破尝试:

代码语言:javascript
复制
19:00:55.362191761: Error File created below /dev by untrusted program (user=root command=event_generator  file=/dev/created-by-event-generator-sh)
19:00:56.365043165: Notice Database-related program spawned process other than itself (user=root program=sh -c ls > /dev/null parent=mysqld)
19:00:57.367928872: Warning Sensitive file opened for reading by non-trusted program (user=root name=event_generator command=event_generator  file=/etc/shadow)
19:00:59.370589147: Error File below known binary directory renamed/removed (user=root command=event_generator  operation=rename file=<NA> res=0 oldpath=/bin/true newpath=/bin/true.event-generator-sh )
...

本文介绍了Sysdig Falco的基础知识及其基于Docker部署上的操作。从内核系统调用和事件,Linux命名空间和特定于容器的元数据开始,可以配置安全警报,而无需修改或检测Docker镜像。 这次我们只使用简单的文件输出来关注规则语法,但你也可以配置sysdig falco的自定义编程输出以向企业中的事件和报警系统发送通知。

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原理
  • 特点
  • 架构
  • demo
  • 部署Sysdig Falco
  • 运行交互式shell的容器
  • 运行未经授权的进程
  • 写入非用户数据目录
  • 通过容器进行敏感挂载
  • 事件发生器
  • 参考资料
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档