入侵检测和漏洞扫描可谓是主动发现安全问题的“内功外功”,在容器技术应用越来越广泛的今天,也需要被给予同样的重视。本文将探讨Docker入侵检测工具Sysdig Falco的基础知识以及如何检测容器的异常行为等问题。 Sysdig Falco是一种旨在检测异常活动开源的系统行为监控程序。作为Linux主机入侵检测系统,对待Docker依旧特别有用,因为它支持容器上下文,如container.id,container.image或其规则的命名空间。
虽说Sysdig Falco是一种审计工具,但却与Seccomp或AppArmor等内核态的审计工具全然不同。 Sysdig Falco在用户空间中运行,使用内核模块拦截系统调用,而其他类似工具在内核级别运行系统调用过滤或监控。用户空间实现的一个好处是能够与Docker编排工具等外部系统集成。
Sysdig Falco具备以下特点:
如下图所示,当发生系统调用时,内核hook会调用sysdig库,产生一个事件,经过Falco规则集的过滤表达式之后产生异常事件,触发报警。
sysdig falco定义的规则非常容易理解,下面可以看几个demo:
container.id != host and proc.name = bash
fd.directory in (/bin,/sbin,/usr/bin,/user/sbin) and write
evt.type = setns and not proc.name in (docker,sysdig)
(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进行异常行为监控:
读者将同时扮演攻击者和防御者(系统管理员)角色,验证Sysdig Falco是否已检测到入侵企图。
首先,把构建Sysdig Falco所需要的配置文件放在/etc/falco下:
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
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]
touch /var/log/falco_events.log
总而言之,falco.yaml配置Falco服务,falco_rules.yaml配置威胁检测模式,falco_events.log将用作事件日志文件。
然后,我们可以从Dockerhub拉取镜像并启动Sysdig Falco容器,安装我们之前定义的配置文件:
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。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUSPORTS NAMES
81cf560cb4d0 sysdig/falco "/docker-entrypoint.…" 59 seconds ago Up 25 seconds falco
下面开始进行4个威胁场景的检测演示。
我们的第一个例子很简单:检测攻击者在任意容器中运行交互式shell。此警报包含在默认规则集中。让我们先触发它看看,然后再查看规则定义。
在Docker主机上运行容器,例如Nginx:
docker run -d -P --name example1 nginx
docker ps
现在生成一个交互式shell:
docker exec -it example1 bash
如果需要,你可以玩一下,然后运行exit离开容器shell。
如果我们使用>tail /var/log/falco_events.log来打开日志文件,我们应该能够看到类似下面的log:
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中触发事件的规则:
- 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进程。其他的任意进程都是异常的指标。 让我们为此示例下载配置文件的新版本:
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
现在,请注意文件中的以下规则:
# 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
让我们剖析这条规则的触发条件,每个条件都是缺一不可的:
要应用新配置文件,我们将重新启动Sysdig Falco容器:
docker restart falco
现在我们需要运行一个新的Nginx容器:
docker run -d -P --name example2 nginx
并运行example2容器中的任意内容,例如ls:
$ 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查看日志,可以看到类似下面的记录:
$ 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通知显示了一个异常的进程。
容器不变性意味着运行的容器完全相同,它们不会对从镜像运行的软件进行任意更改,并且任意用户数据都位于外部安装的卷中。当任意进程尝试写入非数据目录时,就让触发警报。 让我们为此示例下载配置文件的新版本:
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定制的允许写入目录的宏:
- 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宏:
- 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
现在,可以生成一个新容器并尝试以下规则:
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。你会发现两个异常事件:
$ 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的异常文件。
容器通常具有已定义且不经常更改的挂载点集合。如果容器尝试在允许的目录集之外安装主机目录或文件,则可能是某人试图突破容器,或者是团队成员为容器开放了太大的权限。 让我们为此示例下载配置文件的新版本:
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
这是监视容器敏感挂载的规则:
- 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了。
- macro: sensitive_mount
condition: (container.mount.dest[/proc*] != "N/A" or container.mount.dest[/mnt*] != "N/A")
要应用新配置文件,我们将重新启动Sysdig Falco容器:
docker restart falco
现在,可以生成一个新容器并尝试mount /mnt:
docker run -d -P --name example4 -v/mnt:/tmp/mnt alpine
如果我们使用tail /var/log/falco_events.log查看日志,可能会看到:
17:21:07.360913099: Informational Container with sensitive mount started (user=root command=sh example4(id=c35126bf862a))
Sysdig Falco通知显示它检测到敏感的挂载。
Falco有一个合成事件生成器,可以显示默认规则集的所有功能。这非常适合全面了解Sysdig Falco的所有功能。
让我们拉取镜像并启动事件生成器:
docker pull sysdig/falco-event-generator
docker run -d --name falco-event-generator sysdig/falco-event-generator
如果我们使用tail -f /var/log/falco_events.log查看日志,将看到检测到许多可疑行为,因为该容器模拟了各种典型的容器入侵和突破尝试:
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的自定义编程输出以向企业中的事件和报警系统发送通知。