terrascan

https://github.com/tenable/terrascan
在这里插入图片描述

Terrascan 是基础架构即代码的静态代码分析器。Terrascan 允许:

  • 将基础架构作为代码无缝扫描,以查找错误配置。
  • 监控已配置的云基础架构,以查找引入终端安全评估漂移的配置更改,并启用恢复到安全终端
  • 检测安全漏洞和违规行为。
  • 在配置云原生基础架构之前降低风险。
  • 提供在本地运行或与 CI\CD 集成的灵活性。

terrascan的基本原理是,通过内置的策略,对目标进行扫描。使用前需要下载策略库,而策略库是经常更新的。类似于扫描病毒需要下载病毒库。它还有一个特点是支持涵盖了IaC和容器领域的的文件扫描:

可见IaC中常用的Cfn,Terraform,以及容器领域的K8S,Helm,Kustomize,Dockerfile都有支持,
一个产品搞定,不需要再部署其他的工具,简化了CICD的设计。

安装(Linux)

# 下载
aria2c https://github.com/tenable/terrascan/releases/download/v1.19.1/terrascan_1.19.1_Linux_x86_64.tar.gz

# 没有aria2c可以直接用wget
wget https://github.com/tenable/terrascan/releases/download/v1.19.1/terrascan_1.19.1_Linux_x86_64.tar.gz

# 解压
tar -xzvf terrascan.tar.gz

#安装
install terrascan /usr/local/bin && rm terrascan

命令帮助

Usage:
  terrascan [command]

Available Commands:
  init        Initializes Terrascan and clones policies from the Terrascan GitHub repository.
  scan        Detect compliance and security violations across Infrastructure as Code.
  server      Run Terrascan as an API server
  version     Terrascan version

Flags:
  -c, --config-path string      config file path
  -l, --log-level string        log level (debug, info, warn, error, panic, fatal) (default "info")
      --log-output-dir string   directory path to write the log and output files
  -x, --log-type string         log output type (console, json) (default "console")
  -o, --output string           output type (human, json, yaml, xml, junit-xml, sarif, github-sarif) (default "human")
      --temp-dir string         temporary directory path to download remote repository,module and templates

init:下载策略库,即从策略库仓库 git clone到本地$HOME/.terrascan目录
scan:具体的scan命令,命令行方式使用
server:作为服务器,提供API供外部调用使用,方便和第三方系统整合

扫描参数

  • 指定路径(默认为当前路径) -d
  • 指定文件 -f
  • 指定远程存储路径 -r
    • git, s3, gcs, http, terraform-registry
    • -u 指定具体的url
  • 指定目标类型 -i

arm, cft, docker, helm, k8s, kustomize, terraform, tfplan

  -i, --iac-type string           iac type (arm, cft, docker, helm, k8s, kustomize, terraform, tfplan)
      --iac-version string        iac version (arm: v1, cft: v1, docker: v1, helm: v3, k8s: v1, kustomize: v2, v3, v4, terraform: v12, v13, v14, v15, tfplan: v1)
  • 指定输出格式
    • yaml, json, human(默认),xml

工作原理

初次执行时,先从github上下载对应的策略库,并根据策略库的要求检查目标文件。
也可以主动指定init命令更新策略库

命令行执行

  1. 测试用例文件
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx
        resources: {}
        volumeMounts:
        - mountPath: /data
          name: mytest
      restartPolicy: Always
      volumes:
      - name: mytest
        persistentVolumeClaim:
          claimName: my-test-pvc
  1. 执行命令行
terrascan scan -i k8s -f nginx.yaml 
terrascan scan -i k8s -f nginx.yaml -o json
terrascan scan -i k8s -f nginx.yaml -o yaml
  1. 检查结果
k8s@k8s-devp-master:~/yaml$ terrascan scan -i k8s -f nginx.yaml

Violation Details -

        Description    :        Memory Limits Not Set in config file.
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        Apply Security Context to Your Pods and Containers
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        No readiness probe will affect automatic recovery in case of unexpected errors
        File           :        nginx.yaml
        Line           :        1
        Severity       :        LOW
        -----------------------------------------------------------------------

        Description    :        CPU Limits Not Set in config file.
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        Container images with readOnlyRootFileSystem set as false mounts the container root file system with write permissions
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        Memory Request Not Set in config file.
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        No liveness probe will ensure there is no recovery in case of unexpected errors
        File           :        nginx.yaml
        Line           :        1
        Severity       :        LOW
        -----------------------------------------------------------------------

        Description    :        Image without digest affects the integrity principle of image security
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        CPU Request Not Set in config file.
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        Minimize Admission of Root Containers
        File           :        nginx.yaml
        Line           :        1
        Severity       :        HIGH
        -----------------------------------------------------------------------

        Description    :        Default Namespace Should Not be Used
        File           :        nginx.yaml
        Line           :        1
        Severity       :        HIGH
        -----------------------------------------------------------------------

        Description    :        Containers Should Not Run with AllowPrivilegeEscalation
        File           :        nginx.yaml
        Line           :        1
        Severity       :        HIGH
        -----------------------------------------------------------------------

        Description    :        Default seccomp profile not enabled will make the container to make non-essential system calls
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        AppArmor profile not set to default or custom profile will make the container vulnerable to kernel level threats
        File           :        nginx.yaml
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

        Description    :        No tag or container image with :Latest tag makes difficult to rollback and track
        File           :        nginx.yaml
        Line           :        1
        Severity       :        LOW
        -----------------------------------------------------------------------


Scan Summary -

        File/Folder         :   /home/k8s/yaml/nginx.yaml
        IaC Type            :   k8s
        Scanned At          :   2024-04-19 08:37:56.943717392 +0000 UTC
        Policies Validated  :   42
        Violated Policies   :   15
        Low                 :   3
        Medium              :   9
        High                :   3

作为服务启动

  1. 启动
k8s@k8s-devp-master:~/yaml$ terrascan server -p 10888
2024-04-19T09:02:06.409Z        info    http-server/start.go:63 registering routes...
2024-04-19T09:02:06.409Z        info    http-server/start.go:75 Route GET - /health
2024-04-19T09:02:06.409Z        info    http-server/start.go:75 Route GET - /v1/providers
2024-04-19T09:02:06.409Z        info    http-server/start.go:75 Route POST - /v1/{iac}/{iacVersion}/{cloud}/local/file/scan
2024-04-19T09:02:06.409Z        info    http-server/start.go:75 Route POST - /v1/{iac}/{iacVersion}/{cloud}/remote/dir/scan
2024-04-19T09:02:06.409Z        info    http-server/start.go:75 Route POST - /v1/k8s/webhooks/{apiKey}/scan/validate
2024-04-19T09:02:06.409Z        info    http-server/start.go:109        http server listening at port 10888
  1. 执行

Server模式下,如何使用几乎没有任何说明,只能参考其源码猜测:
https://github.com/tenable/terrascan/blob/master/pkg/http-server/routes.go
https://github.com/tenable/terrascan/blob/master/pkg/http-server/file-scan_test.go

// Routes returns a slice of routes of API endpoints to be registered with
// http server
func (g *APIServer) Routes() []*Route {
    h := NewAPIHandler()
    routes := []*Route{
        {verb: "GET", path: "/health", fn: h.Health},
        {verb: "GET", path: versionedPath("/providers"), fn: h.iacProviders},
        {verb: "POST", path: versionedPath("/{iac}/{iacVersion}/{cloud}/local/file/scan"), fn: h.scanFile},
        {verb: "POST", path: versionedPath("/{iac}/{iacVersion}/{cloud}/remote/dir/scan"), fn: h.scanRemoteRepo},

        // k8s webhook Routes
        {verb: "POST", path: versionedPath("/k8s/webhooks/{apiKey}/scan/validate"), fn: h.validateK8SWebhook},
    }

    return routes
}
// http request of the type "/v1/{iacType}/{iacVersion}/{cloudType}/file/scan"
			url := fmt.Sprintf("/v1/%s/%s/%s/local/file/scan", tt.iacType, tt.iacVersion, tt.cloudType)

可以看到,它支持如下功能:

  • /providers:功能支持列表
  • /{iac}/{iacVersion}/{cloud}/local/file/scan:本地文件扫描
  • /{iac}/{iacVersion}/{cloud}/remote/dir/scan:远程目录扫描
  • /k8s/webhooks/{apiKey}/scan/validate:和Kubernetes整合用的webhook

功能列表获取

k8s@k8s-devp-master:~/yaml$ curl -X GET  -L http://localhost:10888/v1/providers
[
  {
    "type": "arm",
    "versions": [
      "v1"
    ],
    "defaultVersion": "v1"
  },
  {
    "type": "cft",
    "versions": [
      "v1"
    ],
    "defaultVersion": "v1"
  },
  {
    "type": "docker",
    "versions": [
      "v1"
    ],
    "defaultVersion": "v1"
  },
  {
    "type": "helm",
    "versions": [
      "v3"
    ],
    "defaultVersion": "v3"
  },
  {
    "type": "k8s",
    "versions": [
      "v1"
    ],
    "defaultVersion": "v1"
  },
  {
    "type": "kustomize",
    "versions": [
      "v2",
      "v3",
      "v4"
    ],
    "defaultVersion": "v4"
  },
  {
    "type": "terraform",
    "versions": [
      "v12",
      "v13",
      "v14",
      "v15"
    ],
    "defaultVersion": "v15"
  },
  {
    "type": "tfplan",
    "versions": [
      "v1"
    ],
    "defaultVersion": "v1"
  }

根据以上结果可以拼接访问URL:

另外文件扫描接口只支持multipart/form-data类型的文件上传,不能作为POST的数据直接上传。
命令行参考以下:
可以看到执行结果和命令行一样,json格式。file等信息是内部中间结果信息,可忽略。

 curl -X POST  -L http://localhost:10888/v1/k8s/v1/k8s/local/file/scan -F 'file=@./nginx.yaml'
 
 {
  "results": {
    "violations": [
      {
        "rule_name": "privilegeEscalationCheck",
        "description": "Containers Should Not Run with AllowPrivilegeEscalation",
        "rule_id": "AC_K8S_0085",
        "severity": "HIGH",
        "category": "Compliance Validation",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "secCompProfile",
        "description": "Default seccomp profile not enabled will make the container to make non-essential system calls",
        "rule_id": "AC_K8S_0080",
        "severity": "MEDIUM",
        "category": "Identity and Access Management",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "appArmorProfile",
        "description": "AppArmor profile not set to default or custom profile will make the container vulnerable to kernel level threats",
        "rule_id": "AC_K8S_0073",
        "severity": "MEDIUM",
        "category": "Identity and Access Management",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "imageWithoutDigest",
        "description": "Image without digest affects the integrity principle of image security",
        "rule_id": "AC_K8S_0069",
        "severity": "MEDIUM",
        "category": "Infrastructure Security",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "securityContextUsed",
        "description": "Apply Security Context to Your Pods and Containers",
        "rule_id": "AC_K8S_0064",
        "severity": "MEDIUM",
        "category": "Infrastructure Security",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "MemorylimitsCheck",
        "description": "Memory Limits Not Set in config file.",
        "rule_id": "AC_K8S_0100",
        "severity": "MEDIUM",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "runAsNonRootCheck",
        "description": "Minimize Admission of Root Containers",
        "rule_id": "AC_K8S_0087",
        "severity": "HIGH",
        "category": "Identity and Access Management",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "MemoryRequestsCheck",
        "description": "Memory Request Not Set in config file.",
        "rule_id": "AC_K8S_0099",
        "severity": "MEDIUM",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "nolivenessProbe",
        "description": "No liveness probe will ensure there is no recovery in case of unexpected errors",
        "rule_id": "AC_K8S_0070",
        "severity": "LOW",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "noReadinessProbe",
        "description": "No readiness probe will affect automatic recovery in case of unexpected errors",
        "rule_id": "AC_K8S_0072",
        "severity": "LOW",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "readOnlyFileSystem",
        "description": "Container images with readOnlyRootFileSystem set as false mounts the container root file system with write permissions",
        "rule_id": "AC_K8S_0078",
        "severity": "MEDIUM",
        "category": "Identity and Access Management",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "imageWithLatestTag",
        "description": "No tag or container image with :Latest tag makes difficult to rollback and track",
        "rule_id": "AC_K8S_0068",
        "severity": "LOW",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "otherNamespace",
        "description": "Default Namespace Should Not be Used",
        "rule_id": "AC_K8S_0086",
        "severity": "HIGH",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "CpulimitsCheck",
        "description": "CPU Limits Not Set in config file.",
        "rule_id": "AC_K8S_0098",
        "severity": "MEDIUM",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      },
      {
        "rule_name": "CpuRequestsCheck",
        "description": "CPU Request Not Set in config file.",
        "rule_id": "AC_K8S_0097",
        "severity": "MEDIUM",
        "category": "Security Best Practices",
        "resource_name": "nginx",
        "resource_type": "kubernetes_deployment",
        "file": "terrascan-3209226987.yaml",
        "line": 1
      }
    ],
    "skipped_violations": null,
    "scan_summary": {
      "file/folder": "/tmp/terrascan-3209226987.yaml",
      "iac_type": "k8s",
      "scanned_at": "2024-04-19 09:13:38.989530627 +0000 UTC",
      "policies_validated": 42,
      "violated_policies": 15,
      "low": 3,
      "medium": 9,
      "high": 3
    }
  }


Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐