티스토리 뷰

Cloud/Kubernetes

Postee

Jacob_baek 2023. 3. 17. 18:51

webhookinterface를 이용해 입력 메세지를 받은 메세지를 라우팅해주는 어플리케이션으로
사전에 정의된 output과 통합하여 강제화 액션을 수행할 수도 있다.

Postee는 취약점 스캔결과를 전달하거나 Aqua Platform에서 협업시스템들에 감사 알람을 전달할수 있다.
(Aqua platform은 Postee를 개발한 회사의 platform으로 opensource로 제공되고 있지만 해당 기업이 contributing하고 있다.)

Rego rule을 이용하여 route를 수행하고 그에 맞는 action(ex, slack webhook 실행)을 수행한다.

Installation

helm은 다음 aquasecurity helm repo를 등록하고 사용하면 되고

jacob@laptop:~$ helm repo add aqua https://aquasecurity.github.io/helm-charts/
"aqua" has been added to your repositories
jacob@laptop:~$ helm search repo postee
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
aquasecurity/postee     v2.9.0          v2.9.0          A Helm chart for Postee
jacob@laptop:~$ helm install postee aquasecurity/postee -n postee
NAME: postee
LAST DEPLOYED: Fri Mar 17 18:43:12 2023
NAMESPACE: postee
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace postee -l "app.kubernetes.io/name=postee,app.kubernetes.io/instance=postee" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace postee $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Postee Webhook http://postee:8082 to set in your application."
  echo "Postee Website http://posteeui:8000 to configure Postee."
  kubectl --namespace postee port-forward $POD_NAME 8000:$CONTAINER_PORT

manifest는 아래와 같이 yaml을 사용하여 직접 설치를 진행하면 된다.

kubectl create -f https://raw.githubusercontent.com/aquasecurity/postee/main/deploy/kubernetes/postee.yaml

기본적으로 다음 두개의 pod가 동작된다.

  • deployment로 postee-ui : UI 기반으로 설정과 trigger 된 count등을 확인할 수 있다.(default로 8000 포트를 사용)
  • statusfulset으로 postee : 실제 message routing을 수행하는 pod로 webhook listen을 하고 있다.( default로 8082, 8445 포트 사용)

Configuration

https://github.com/aquasecurity/postee/blob/main/cfg.yaml

Example

postee를 통한 메세지 라우팅을 할때 3가지 구성요소를 지정해야 한다.

  • routes : 실제 trivy와 같은 tool을 통해 혹은 cURL로 직접 webhook을 호출했을때 어떤 route에 포함될지 검사가 진행되는 항목이다.
  • actions : 결과를 어디에 출력할지를 정하는 곳이다. slack/teams/webhook/stdout 등 다양한 방식을 지원한다.
  • templates : slack, teams과 같은 다양한 방식으로 출력을 내볼때 사용되는 template이다.
    이 또한 rego를 사용하여 만들어지기에 URL을 참고하여 붙여넣기를 하거나 수정하여 사용하면 된다.

아래는 실제 테스트시 사용해보았던 cfg.yaml 파일이다.

    routes:
    - name: stdout
      actions: [ stdout, webhook ]
      template: trivy-raw-json
    - name: Trivy Operator Alerts
      input: input.report.summary.criticalCount > 0 # You can customize this based on your needs
      actions: [send-slack-msg]
      template: trivy-operator-slack
    - name: trivy-alpine-vulns
      input: contains(input.Metadata.OS.Family, "alpine")
      actions: [my-jira]
      template: trivy-raw-json

    # Templates are used to format a message
    templates:
    - name: trivy-operator-slack
      rego-package: postee.trivyoperator.slack
    - name: trivy-raw-json
      rego-package: postee.rawmessage.json

    actions:
    - name: stdout
      type: stdout
      enable: true
    - name: send-slack-msg
      type: slack
      enable: true
      url: https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX
    - name: webhook
      type: webhook
      enable: false
      url: https://webhook.site/a191864a-ff5f-4e6b-97c8-c3e08ec201ec  ## 테스트용 https://webhook.site/를 이용

참고로 아래 링크에 route/action/template에 대한 예제 yaml들이 있으니 이를 참고하여 작성한다.

또한 template에서 사용하는 REGO의 경우 다음 링크를 참고하면 쉽게 사용이 가능할것이다.

How to use

여기서는 trivy를 이용하여 image scan을 수행하고 발견된 취약점을 바로 postee에 webhook 호출을 하는 것을 해보려 한다.

먼저 trivy의 webhook plugin을 설치하여 webhook 호출이 image scan과 함께 이루어지도록 하자.

jacob@laptop:~ $ trivy plugin install github.com/aquasecurity/trivy-plugin-webhook
2023-03-17T10:31:27.279+0900    INFO    Installing the plugin from github.com/aquasecurity/trivy-plugin-webhook...
2023-03-17T10:31:28.745+0900    INFO    Loading the plugin metadata...

이후 아래와 같이 postee의 url을 주구 image scan을 수행한다.

jacob@laptop:~ $ trivy webhook --url="http://[postee-endpoint-url]:8082" -- image alpine:3.11 | jq
2023/03/17 18:51:53 running trivy...
2023/03/17 18:51:53 running trivy with args:  [image alpine:3.11 --format=json --quiet --timeout=30s]
2023/03/17 18:51:57 trivy returned:  {
  "SchemaVersion": 2,
  "ArtifactName": "alpine:3.11",
  "ArtifactType": "container_image",
  "Metadata": {
    "OS": {
      "Family": "alpine",
      "Name": "3.11.13",
      "EOSL": true
    },
    "ImageID": "sha256:a787cb9865032e5b5a407ecdf34b57a23a4a076aaa043d71742ddb6726ec9229",
    "DiffIDs": [
      "sha256:69715584ec78c168981b0925dd7c50f4537bc598dcbce814db2803a10b777b5c"
    ],
    "RepoTags": [
      "alpine:3.11"
    ],
    "RepoDigests": [
      "alpine@sha256:bcae378eacedab83da66079d9366c8f5df542d7ed9ab23bf487e3e1a8481375d"
    ],
    "ImageConfig": {
      "architecture": "amd64",
      "container": "9a36cae78f6934ef1807fa6d7fbe783ef8ef7c719438a53c5ce3d6cabd0ad551",
      "created": "2021-11-12T17:20:17.61716938Z",
      "docker_version": "20.10.7",
      "history": [
        {
          "created": "2021-11-12T17:20:17.342816328Z",
          "created_by": "/bin/sh -c #(nop) ADD file:efe2d94a88cdbbd01c3ef095f0a2473cec9e74804b49cd6fb9b837d362631409 in / "
        },
        {
          "created": "2021-11-12T17:20:17.61716938Z",
          "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
          "empty_layer": true
        }
      ],
      "os": "linux",
      "rootfs": {
        "type": "layers",
        "diff_ids": [
          "sha256:69715584ec78c168981b0925dd7c50f4537bc598dcbce814db2803a10b777b5c"
        ]
      },
      "config": {
        "Cmd": [
          "/bin/sh"
        ],
        "Env": [
          "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
        ],
        "Image": "sha256:ff3f29274d45b1bf9ebf7c6df3a8021bb2396803c7644ee8306b9f45732a61ea"
      }
    }
  },
  "Results": [
    {
      "Target": "alpine:3.11 (alpine 3.11.13)",
      "Class": "os-pkgs",
      "Type": "alpine",
      "Vulnerabilities": [
        {
          "VulnerabilityID": "CVE-2022-37434",
          "PkgID": "zlib@1.2.11-r3",
          "PkgName": "zlib",
          "InstalledVersion": "1.2.11-r3",
          "FixedVersion": "1.2.11-r4",
          "Layer": {
            "Digest": "sha256:79e9f2f55bf5465a02ee6a6170e66005b20c7aa6b115af6fcd04fad706ea651a",
            "DiffID": "sha256:69715584ec78c168981b0925dd7c50f4537bc598dcbce814db2803a10b777b5c"
          },
          "SeveritySource": "nvd",
          "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2022-37434",
          "DataSource": {
            "ID": "alpine",
            "Name": "Alpine Secdb",
            "URL": "https://secdb.alpinelinux.org/"
          },
          "Title": "zlib: heap-based buffer over-read and overflow in inflate() in inflate.c via a large gzip header extra field",
          "Description": "zlib through 1.2.12 has a heap-based buffer over-read or buffer overflow in inflate in inflate.c via a large gzip header extra field. NOTE: only applications that call inflateGetHeader are affected. Some common applications bundle the affected zlib source code but may be unable to call inflateGetHeader (e.g., see the nodejs/node reference).",
          "Severity": "CRITICAL",
          "CweIDs": [
            "CWE-787"
          ],
          "CVSS": {
            "nvd": {
              "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
              "V3Score": 9.8
            },
            "redhat": {
              "V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:H",
              "V3Score": 7
            }
          },
          "References": [
            "http://seclists.org/fulldisclosure/2022/Oct/41",
            "http://www.openwall.com/lists/oss-security/2022/08/05/2",
            "http://www.openwall.com/lists/oss-security/2022/08/09/1",
            "https://access.redhat.com/errata/RHSA-2022:8291",
            "https://access.redhat.com/security/cve/CVE-2022-37434",
            "https://bugzilla.redhat.com/2116639",
            "https://bugzilla.redhat.com/show_bug.cgi?id=2053198",
            "https://bugzilla.redhat.com/show_bug.cgi?id=2077431",
            "https://bugzilla.redhat.com/show_bug.cgi?id=2081296",
            "https://bugzilla.redhat.com/show_bug.cgi?id=2116639",
            "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-37434",
            "https://errata.almalinux.org/9/ALSA-2022-8291.html",
            "https://errata.rockylinux.org/RLSA-2022:8291",
            "https://github.com/curl/curl/issues/9271",
            "https://github.com/ivd38/zlib_overflow",
            "https://github.com/madler/zlib/blob/21767c654d31d2dccdde4330529775c6c5fd5389/zlib.h#L1062-L1063",
            "https://github.com/madler/zlib/commit/eff308af425b67093bab25f80f1ae950166bece1",
            "https://github.com/nodejs/node/blob/75b68c6e4db515f76df73af476eccf382bbcb00a/deps/zlib/inflate.c#L762-L764",
            "https://linux.oracle.com/cve/CVE-2022-37434.html",
            "https://linux.oracle.com/errata/ELSA-2023-1095.html",
            "https://lists.debian.org/debian-lts-announce/2022/09/msg00012.html",
            "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/JWN4VE3JQR4O2SOUS5TXNLANRPMHWV4I/",
            "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/NMBOJ77A7T7PQCARMDUK75TE6LLESZ3O/",
            "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/PAVPQNCG3XRLCLNSQRM3KAN5ZFMVXVTY/",
            "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/X5U7OTKZSHY2I3ZFJSR2SHFHW72RKGDK/",
            "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/YRQAI7H4M4RQZ2IWZUEEXECBE5D56BH2/",
            "https://nvd.nist.gov/vuln/detail/CVE-2022-37434",
            "https://security.netapp.com/advisory/ntap-20220901-0005/",
            "https://support.apple.com/kb/HT213488",
            "https://support.apple.com/kb/HT213489",
            "https://support.apple.com/kb/HT213490",
            "https://support.apple.com/kb/HT213491",
            "https://support.apple.com/kb/HT213493",
            "https://support.apple.com/kb/HT213494",
            "https://ubuntu.com/security/notices/USN-5570-1",
            "https://ubuntu.com/security/notices/USN-5570-2",
            "https://ubuntu.com/security/notices/USN-5573-1",
            "https://www.debian.org/security/2022/dsa-5218"
          ],
          "PublishedDate": "2022-08-05T07:15:00Z",
          "LastModifiedDate": "2023-01-09T16:44:00Z"
        }
      ]
    }
  ]
}

2023/03/17 18:51:57 sending results to webhook...
2023/03/17 18:51:57 webhook returned:  ""

위 endpoint의 경우 http는 8082로 https로 8445 포트가 사용되어진다.

jacob@laptop:~ $ kubectl get svc -l app=postee
NAME         TYPE           CLUSTER-IP   EXTERNAL-IP      PORT(S)                         AGE
postee-svc   LoadBalancer   10.2.45.84   11.111.111.111   8445:30834/TCP,8082:30720/TCP   152m

trivy를 laptop에서 사용하려 하여 loadbalancer type으로 external IP를 추가하였고 내부에서 호출하는 경우라면
"postee-svc.default.svc.cluster.local:8082" 과 같은 URL을 입력하면 된다.

route에 매칭되는 webhook 호출이 있을 경우 해당 route에 설정된 action이 실행되게 되고
해당 action에 count가 증가하게 되어 호출되었는지 확인 할 수 있다.

action에 맞게 slack으로 출력된 결과이다.
(앞서 정의한 template에 맞게 출력이 되었다.)

OPA(open policy agent)의 REGO를 통해 route 및 template등을 작성할수 있기에 REGO를 잘 알고 이해한상태에서 사용하는것이 좋을듯하다.

'Cloud > Kubernetes' 카테고리의 다른 글

Eraser (Image cleaner)  (0) 2023.04.25
trivy-operator  (0) 2023.04.01
kubent(no trouble)  (0) 2023.03.14
Vertical Pods Autoscaler  (0) 2023.02.16
Custom Container Registry with containerd runtime on Kubernetes  (0) 2023.02.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/03   »
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
글 보관함