关于 KICS
KICS 是 Keeping Infrastructure as Code Secure 的缩写,是一个开源项目,主要用来在开发早期发现基础设施即代码中的一些安全漏洞、合规问题以及错误配置等。目前支持多种平台,诸如 Terraform、Kubernetes、Docker、Helm、Ansible 等。
KICS 的原理
KICS 是插件式架构,具有可扩展的 IaC 语言解析管道,可以轻松地整合新的 IaC 语言和查询。KICS 有几个主要的组件:CLI、解析器(parser)、查询执行引擎(queries exection engine)、IaC 提供者(IaC provider)、安全查询(security queries)以及结果写入器(results writer)。各组件的主要功能为:
- CLI:为 KICS 提供命令行输入;
- 解析器:负责解析输入的 IaC 文件(比如 terraform 及其他形式);
- IaC 提供者:将 IaC 语言转换成规范化的 JSON;
- 查询执行引擎:对规范化的 JSON 使用 REGO 查询;
- 安全查询:针对每个安全漏洞和错误配置进行前置 REGO 查询;
- 写入器:将结果写入到 JSON 文件中;
架构图如下:
使用 KICS 扫描 IaC
可以通过源码构建、brew 或者 docker 的方式来使用 KICS。详细使用方法可以参考KICS 安装官方文档。本文选择用 docker 的方式来使用 KICS。docker 镜像为 checkmarx/kics:latest
。可以通过启动容器的方式来查看 KICS 的用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| $ docker run -t checkmarx/kics --help
Keeping Infrastructure as Code Secure
Usage:
kics [command]
Available Commands:
generate-id Generates uuid for query
help Help about any command
list-platforms List supported platforms
remediate Auto remediates the project
scan Executes a scan analysis
version Displays the current version
Flags:
--ci display only log messages to CLI output (mutually exclusive with silent)
-h, --help help for kics
-f, --log-format string determines log format (pretty,json) (default "pretty")
--log-level string determines log level (TRACE,DEBUG,INFO,WARN,ERROR,FATAL) (default "INFO")
--log-path string path to generate log file (info.log)
--no-color disable CLI color output
--profiling string enables performance profiler that prints resource consumption metrics in the logs during the execution (CPU, MEM)
-s, --silent silence stdout messages (mutually exclusive with verbose and ci)
-v, --verbose write logs to stdout too (mutually exclusive with silent)
Use "kics [command] --help" for more information about a command.
|
查看 KICS 支持的平台类型:
1
2
3
4
5
6
7
8
9
10
11
12
| $ docker run -t checkmarx/kics list-platforms
Ansible
AzureResourceManager
Buildah
CloudFormation
DockerCompose
Dockerfile
GRPC
GoogleDeploymentManager
Kubernetes
OpenAPI
Terraform
|
使用 KICS 扫描 Dockerfile
使用如下的 Dockerfile 来进行扫描:
1
2
3
4
5
6
7
8
9
| FROM golang:1.12.9-alpine3.9 as builder
WORKDIR /tmp
COPY main.go /tmp
RUN go build main.go
FROM alpine:latest
WORKDIR /usr/src/app/
COPY --from=builder /tmp/main /usr/src/app/
CMD ["./main"]
|
使用如下命令进行扫描并查看输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
| docker run -t -v $PWD:/tmp/ checkmarx/kics scan -t Dockerfile -p "/tmp/"
.0MO.
OMMMx
;NMX;
... ... ....
WMMMd cWMMM0. KMMMO ;xKWMMMMNOc. ,xXMMMMMWXkc.
WMMMd .0MMMN: KMMMO :XMMMMMMMMMMMWl xMMMMMWMMMMMMl
WMMMd lWMMMO. KMMMO xMMMMKc...'lXMk ,MMMMx .;dXx
WMMMd.0MMMX; KMMMO cMMMMd ' 'MMMMNl'
WMMMNWMMMMl KMMMO 0MMMN oMMMMMMMXkl.
WMMMMMMMMMMo KMMMO 0MMMX .ckKWMMMMMM0.
WMMMMWokMMMMk KMMMO oMMMMc . .:OMMMM0
WMMMK. dMMMM0. KMMMO KMMMMx' ,kNc :WOc. .NMMMX
WMMMd cWMMMX. KMMMO kMMMMMWXNMMMMMd .WMMMMWKO0NMMMMl
WMMMd ,NMMMN, KMMMO 'xNMMMMMMMNx, .l0WMMMMMMMWk,
xkkk: ,kkkkx okkkl ;xKXKx; ;dOKKkc
Scanning with Keeping Infrastructure as Code Secure v1.5.12
Preparing Scan Assets: Done
Executing queries: [---------------------------------------------------] 100.00%
Files scanned: 1
Parsed files: 1
Queries loaded: 48
Queries failed to execute: 0
------------------------------------
Healthcheck Instruction Missing, Severity: LOW, Results: 1
Description: Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working
Platform: Dockerfile
[1]: ../../tmp/Dockerfile:9
008:
009: FROM alpine:latest
010:
Image Version Using 'latest', Severity: MEDIUM, Results: 1
Description: When building images, always tag them with useful tags which codify version information, intended destination (prod or test, for instance), stability, or other information that is useful when deploying the application in different environments. Do not rely on the automatically-created latest tag
Platform: Dockerfile
[1]: ../../tmp/Dockerfile:9
008:
009: FROM alpine:latest
010:
Missing User Instruction, Severity: HIGH, Results: 1
Description: A user should be specified in the dockerfile, otherwise the image will run as root
Platform: Dockerfile
[1]: ../../tmp/Dockerfile:9
008:
009: FROM alpine:latest
010:
Results Summary:
HIGH: 1
MEDIUM: 1
LOW: 1
INFO: 0
TOTAL: 3
Scan duration: 7.366705761s
|
可以看到扫描出来了三个安全问题,高中低各一个。高危漏洞指没有指定容器的启用用户,中危漏洞是指使用了 latest
镜像 tag,低危漏洞是指没有使用 HEALTHCHECK。修复之后的 Dockerfile 如下:
1
2
3
4
5
6
7
8
9
10
11
12
| FROM golang:1.12.9-alpine3.9 as builder
WORKDIR /tmp
COPY main.go /tmp
RUN go build main.go
FROM alpine:3.10
RUN addgroup -S devsecops && adduser -S devsecops -G devsecops
WORKDIR /usr/src/app/
COPY --from=builder /tmp/main /usr/src/app/
USER devsecops
HEALTHCHECK CMD curl --fail http://localhost:9999 || exit 1
CMD ["./main"]
|
再次扫描:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| docker run -t -v $PWD:/tmp/ checkmarx/kics scan -t Dockerfile -p "/tmp/"
.0MO.
OMMMx
;NMX;
... ... ....
WMMMd cWMMM0. KMMMO ;xKWMMMMNOc. ,xXMMMMMWXkc.
WMMMd .0MMMN: KMMMO :XMMMMMMMMMMMWl xMMMMMWMMMMMMl
WMMMd lWMMMO. KMMMO xMMMMKc...'lXMk ,MMMMx .;dXx
WMMMd.0MMMX; KMMMO cMMMMd ' 'MMMMNl'
WMMMNWMMMMl KMMMO 0MMMN oMMMMMMMXkl.
WMMMMMMMMMMo KMMMO 0MMMX .ckKWMMMMMM0.
WMMMMWokMMMMk KMMMO oMMMMc . .:OMMMM0
WMMMK. dMMMM0. KMMMO KMMMMx' ,kNc :WOc. .NMMMX
WMMMd cWMMMX. KMMMO kMMMMMWXNMMMMMd .WMMMMWKO0NMMMMl
WMMMd ,NMMMN, KMMMO 'xNMMMMMMMNx, .l0WMMMMMMMWk,
xkkk: ,kkkkx okkkl ;xKXKx; ;dOKKkc
Scanning with Keeping Infrastructure as Code Secure v1.5.12
Preparing Scan Assets: Done
Executing queries: [---------------------------------------------------] 100.00%
Files scanned: 1
Parsed files: 1
Queries loaded: 48
Queries failed to execute: 0
------------------------------------
Results Summary:
HIGH: 0
MEDIUM: 0
LOW: 0
INFO: 0
TOTAL: 0
Scan duration: 6.053745825s
|
可以看到所有级别的安全问题都为 0。证明问题已经被修复。
注意:上述 Dockerfile 修复只是为了验证 KICS 的 IaC 扫描能力,需要根据自身场景进行 Dockerfile 的准确编写与修复。
使用 KICS 扫描 Helm Charts
使用 helm create
创建一个 helm chart:
1
2
| $ helm create kics
Creating kics
|
使用 KICS 进行扫描:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
| docker run -t -v $PWD:/tmp/ checkmarx/kics scan -t Kubernetes -p "/tmp/"
.0MO.
OMMMx
;NMX;
... ... ....
WMMMd cWMMM0. KMMMO ;xKWMMMMNOc. ,xXMMMMMWXkc.
WMMMd .0MMMN: KMMMO :XMMMMMMMMMMMWl xMMMMMWMMMMMMl
WMMMd lWMMMO. KMMMO xMMMMKc...'lXMk ,MMMMx .;dXx
WMMMd.0MMMX; KMMMO cMMMMd ' 'MMMMNl'
WMMMNWMMMMl KMMMO 0MMMN oMMMMMMMXkl.
WMMMMMMMMMMo KMMMO 0MMMX .ckKWMMMMMM0.
WMMMMWokMMMMk KMMMO oMMMMc . .:OMMMM0
WMMMK. dMMMM0. KMMMO KMMMMx' ,kNc :WOc. .NMMMX
WMMMd cWMMMX. KMMMO kMMMMMWXNMMMMMd .WMMMMWKO0NMMMMl
WMMMd ,NMMMN, KMMMO 'xNMMMMMMMNx, .l0WMMMMMMMWk,
xkkk: ,kkkkx okkkl ;xKXKx; ;dOKKkc
Scanning with Keeping Infrastructure as Code Secure v1.5.12
Preparing Scan Assets: Done
Executing queries: [---------------------------------------------------] 100.00%
Files scanned: 4
Parsed files: 3
Queries loaded: 146
Queries failed to execute: 0
------------------------------------
Root Container Not Mounted Read-only, Severity: LOW, Results: 1
Description: Check if the root container filesystem is not being mounted read-only.
Platform: Kubernetes
[1]: ../../tmp/kics/templates/deployment.yaml:30
029: {{- toYaml .Values.podSecurityContext | nindent 8 }}
030: containers:
031: - name: {{ .Chart.Name }}
CPU Limits Not Set, Severity: MEDIUM, Results: 1
Description: CPU limits should be set because if the system has CPU time free, a container is guaranteed to be allocated as much CPU as it requests
Platform: Kubernetes
[1]: ../../tmp/kics/templates/deployment.yaml:48
047: port: http
048: resources:
049: {{- toYaml .Values.resources | nindent 12 }}
Privilege Escalation Allowed, Severity: HIGH, Results: 1
Description: Containers should not run with allowPrivilegeEscalation in order to prevent them from gaining more privileges than their parent process
Platform: Kubernetes
[1]: ../../tmp/kics/templates/deployment.yaml:30
029: {{- toYaml .Values.podSecurityContext | nindent 8 }}
030: containers:
031: - name: {{ .Chart.Name }}
NET_RAW Capabilities Not Being Dropped, Severity: HIGH, Results: 1
Description: Containers should drop 'ALL' or at least 'NET_RAW' capabilities
Platform: Kubernetes
[1]: ../../tmp/kics/templates/deployment.yaml:30
029: {{- toYaml .Values.podSecurityContext | nindent 8 }}
030: containers:
031: - name: {{ .Chart.Name }}
Results Summary:
HIGH: 2
MEDIUM: 10
LOW: 7
INFO: 0
TOTAL: 19
Scan duration: 4.371884514s
|
可以看到总计有 19 处安全问题。可以根据提示进行修复,修复之后再次扫描即可。
将 KICS 集成到 Tekton CI/CD 中
使用 Tekton 创建一个 task,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-docker-image
spec:
resources:
inputs:
- name: source-code
type: git
steps:
- name: dockerfile-kics-scan
image: checkmarx/kics
script: |
#! /bin/sh
kics scan -t Dockerfile -p $(resources.inputs.source-code.path)
|
然后创建 Task
即可。然后用 TaskRun
触发一个 Task
,可以查看两者的状态:
1
2
3
4
5
6
7
| $ tkn -n tekton-kics tr list
NAME STARTED DURATION STATUS
dockerfile-kics-scan-run 4 minutes ago 21 seconds Succeeded
$ tkn -n tekton-kics t list
NAME DESCRIPTION AGE
dockerfile-kics-scan 4 minutes ago
|
整个构建过程会在 tekton-kics
namespace 下面创建一个 pods:
1
2
3
4
5
6
7
8
| $ kubectl -n tekton-kics get pods -w
NAME READY STATUS RESTARTS AGE
build-docker-image-run-pod 0/4 PodInitializing 0 7s
build-docker-image-run-pod 4/4 Running 0 13s
build-docker-image-run-pod 4/4 Running 0 13s
build-docker-image-run-pod 2/4 NotReady 0 15s
build-docker-image-run-pod 0/4 Completed 0 22s
build-docker-image-run-pod 0/4 Completed 0 24s
|
通过 logs -f
可查看构建过程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| kubectl -n tekton-kics logs -f build-docker-image-run-pod -c step-dockerfile-kics-scan
.0MO.
OMMMx
;NMX;
... ... ....
WMMMd cWMMM0. KMMMO ;xKWMMMMNOc. ,xXMMMMMWXkc.
WMMMd .0MMMN: KMMMO :XMMMMMMMMMMMWl xMMMMMWMMMMMMl
WMMMd lWMMMO. KMMMO xMMMMKc...'lXMk ,MMMMx .;dXx
WMMMd.0MMMX; KMMMO cMMMMd ' 'MMMMNl'
WMMMNWMMMMl KMMMO 0MMMN oMMMMMMMXkl.
WMMMMMMMMMMo KMMMO 0MMMX .ckKWMMMMMM0.
WMMMMWokMMMMk KMMMO oMMMMc . .:OMMMM0
WMMMK. dMMMM0. KMMMO KMMMMx' ,kNc :WOc. .NMMMX
WMMMd cWMMMX. KMMMO kMMMMMWXNMMMMMd .WMMMMWKO0NMMMMl
WMMMd ,NMMMN, KMMMO 'xNMMMMMMMNx, .l0WMMMMMMMWk,
xkkk: ,kkkkx okkkl ;xKXKx; ;dOKKkc
Scanning with Keeping Infrastructure as Code Secure v1.5.12
Files scanned: 1
Parsed files: 1
Queries loaded: 48
Queries failed to execute: 0
------------------------------------
Results Summary:
HIGH: 0
MEDIUM: 0
LOW: 0
INFO: 0
TOTAL: 0
Scan duration: 3.556468026s
|
结果显示没有任何安全漏洞,是因为使用了前述修复之后的 Dockerfile 来进行演示。
关于其他 IaC 的扫描以及与 Tekton 的集成与上述演示的类似,在此不做详述。