From 81dd08fd5b98f97fc7afcd772d16c4cf4c3f17bb Mon Sep 17 00:00:00 2001 From: Tommy Date: Sun, 26 May 2024 21:51:19 +0200 Subject: [PATCH] feat: initial work on grr --- .../containers/grr-daemon/Dockerfile | 34 ++++++ .../grr-daemon/config/communicator.txt | 0 .../grr-daemon/config/config.textproto.tmpl | 8 ++ .../containers/grr-daemon/config/grr.yaml | 14 +++ .../config/textservices/grr.service | 9 ++ .../grr-daemon/grr-client-config.yaml | 11 ++ charts/grr-client/templates/daemonset.yaml | 48 +++++++++ charts/grr-client/values.yaml | 15 +++ charts/grr/.helmignore | 1 + charts/grr/Chart.yaml | 17 +++ charts/grr/README.md | 8 ++ charts/grr/templates/_helpers.tpl | 38 +++++++ charts/grr/templates/configmaps.yaml | 102 ++++++++++++++++++ charts/grr/templates/deployment-admin.yaml | 57 ++++++++++ .../deployment-fleetspeak-admin.yaml | 64 +++++++++++ .../deployment-fleetspeak-frontend.yaml | 88 +++++++++++++++ charts/grr/templates/deployment-frontend.yaml | 57 ++++++++++ charts/grr/templates/deployment-worker.yaml | 55 ++++++++++ charts/grr/templates/init-database.yaml | 51 +++++++++ charts/grr/templates/secret-grr.yaml | 9 ++ charts/grr/templates/service.yaml | 67 ++++++++++++ charts/grr/templates/serviceaccount.yaml | 6 ++ charts/grr/values.yaml | 77 +++++++++++++ 23 files changed, 836 insertions(+) create mode 100644 charts/grr-client/containers/grr-daemon/Dockerfile create mode 100644 charts/grr-client/containers/grr-daemon/config/communicator.txt create mode 100644 charts/grr-client/containers/grr-daemon/config/config.textproto.tmpl create mode 100644 charts/grr-client/containers/grr-daemon/config/grr.yaml create mode 100644 charts/grr-client/containers/grr-daemon/config/textservices/grr.service create mode 100644 charts/grr-client/containers/grr-daemon/grr-client-config.yaml create mode 100644 charts/grr-client/templates/daemonset.yaml create mode 100644 charts/grr-client/values.yaml create mode 100644 charts/grr/.helmignore create mode 100644 charts/grr/Chart.yaml create mode 100644 charts/grr/README.md create mode 100644 charts/grr/templates/_helpers.tpl create mode 100644 charts/grr/templates/configmaps.yaml create mode 100644 charts/grr/templates/deployment-admin.yaml create mode 100644 charts/grr/templates/deployment-fleetspeak-admin.yaml create mode 100644 charts/grr/templates/deployment-fleetspeak-frontend.yaml create mode 100644 charts/grr/templates/deployment-frontend.yaml create mode 100644 charts/grr/templates/deployment-worker.yaml create mode 100644 charts/grr/templates/init-database.yaml create mode 100644 charts/grr/templates/secret-grr.yaml create mode 100644 charts/grr/templates/service.yaml create mode 100644 charts/grr/templates/serviceaccount.yaml create mode 100644 charts/grr/values.yaml diff --git a/charts/grr-client/containers/grr-daemon/Dockerfile b/charts/grr-client/containers/grr-daemon/Dockerfile new file mode 100644 index 0000000..04aac90 --- /dev/null +++ b/charts/grr-client/containers/grr-daemon/Dockerfile @@ -0,0 +1,34 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +FROM ghcr.io/google/grr:latest AS grr +COPY config /config +COPY grr-client-config.yaml /config/grr.client.yaml +COPY executable-signing.key /config/ + +RUN mkdir /client_installers && \ + grr_config_updater repack_clients \ + --secondary_configs /config/grr.yaml \ + --noupload + +WORKDIR / + +FROM ubuntu:22.04 +WORKDIR / + +COPY config /config +COPY --from=grr /config/grr.client.yaml /config/grr.client.yaml + +COPY --from=grr /client_installers/grr_*_amd64.deb . +RUN dpkg -i grr_*_amd64.deb && rm grr_*_amd64.deb +ENTRYPOINT ["fleetspeak-client", "-config" , "/config/config.textproto", "-alsologtostderr"] \ No newline at end of file diff --git a/charts/grr-client/containers/grr-daemon/config/communicator.txt b/charts/grr-client/containers/grr-daemon/config/communicator.txt new file mode 100644 index 0000000..e69de29 diff --git a/charts/grr-client/containers/grr-daemon/config/config.textproto.tmpl b/charts/grr-client/containers/grr-daemon/config/config.textproto.tmpl new file mode 100644 index 0000000..88c76df --- /dev/null +++ b/charts/grr-client/containers/grr-daemon/config/config.textproto.tmpl @@ -0,0 +1,8 @@ +trusted_certs: FRONTEND_TRUSTED_CERTIFICATES +server: "FLEETSPEAK_FRONTEND_ADDRESS:FLEETSPEAK_FRONTEND_PORT" +client_label: "" +filesystem_handler: < + configuration_directory: "/config/" + state_file: "/fleetspeak.state" +> +streaming: true \ No newline at end of file diff --git a/charts/grr-client/containers/grr-daemon/config/grr.yaml b/charts/grr-client/containers/grr-daemon/config/grr.yaml new file mode 100644 index 0000000..1b279fa --- /dev/null +++ b/charts/grr-client/containers/grr-daemon/config/grr.yaml @@ -0,0 +1,14 @@ +PrivateKeys.executable_signing_private_key: "%(/config/executable-signing.key|file)" +Client.executable_signing_public_key: "%(/config/executable-signing.pub|file)" +# Configuration for repacking client templates: +Client.fleetspeak_enabled: true +ClientBuilder.fleetspeak_bundled: true +ClientBuilder.template_dir: /client_templates +ClientBuilder.executables_dir: /client_installers + +Target:Linux: + ClientBuilder.fleetspeak_client_config: /config/config.textproto +Target:Windows: + ClientBuilder.fleetspeak_client_config: /config/config.textproto +Target:Darwin: + ClientBuilder.fleetspeak_client_config: /config/config.textproto diff --git a/charts/grr-client/containers/grr-daemon/config/textservices/grr.service b/charts/grr-client/containers/grr-daemon/config/textservices/grr.service new file mode 100644 index 0000000..5558504 --- /dev/null +++ b/charts/grr-client/containers/grr-daemon/config/textservices/grr.service @@ -0,0 +1,9 @@ +name: "GRR" +factory: "Daemon" +config { + [type.googleapis.com/fleetspeak.daemonservice.Config] { + argv: "/usr/sbin/grrd" + argv: "--config" + argv: "/config/grr.client.yaml" + } +} \ No newline at end of file diff --git a/charts/grr-client/containers/grr-daemon/grr-client-config.yaml b/charts/grr-client/containers/grr-daemon/grr-client-config.yaml new file mode 100644 index 0000000..7ef8544 --- /dev/null +++ b/charts/grr-client/containers/grr-daemon/grr-client-config.yaml @@ -0,0 +1,11 @@ +Client.fleetspeak_enabled: true +Client.foreman_check_frequency: 10 +Client.allowed_commands: /hostroot/usr/bin/crictl -r unix:///hostroot/run/containerd/containerd.sock images -o yaml, /hostroot/usr/bin/crictl -r unix:///hostroot/run/containerd/containerd.sock info -o yaml, /hostroot/usr/bin/crictl -r unix:///hostroot/run/containerd/containerd.sock pods -o yaml, /hostroot/usr/bin/crictl -r unix:///hostroot/run/containerd/containerd.sock ps -o yaml, /hostroot/usr/bin/crictl -r unix:///hostroot/run/containerd/containerd.sock stats -o yaml, /hostroot/usr/bin/crictl -r unix:///hostroot/run/containerd/containerd.sock statsp -o yaml +Logging.verbose: true +Logging.engines: file,stderr +Logging.path: / +Logging.filename: /grr-client.log + +Config.writeback: /config/grr-client.local.yaml + +Client.executable_signing_public_key: "%(/config/executable-signing.pub|file)" diff --git a/charts/grr-client/templates/daemonset.yaml b/charts/grr-client/templates/daemonset.yaml new file mode 100644 index 0000000..7bc5e04 --- /dev/null +++ b/charts/grr-client/templates/daemonset.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: grr + labels: + app: grr +spec: + selector: + matchLabels: + app: grr + template: + metadata: + labels: + app: grr + spec: + # Only deploying GRR to nodes with the label 'grrclient=installed'. + nodeSelector: + grrclient: installed + serviceAccountName: grr-sa + # Uses the host network rather than the container network. This way + # the hostname that shows up in GRR will contain the cluster name too. + hostNetwork: true + # Allows us to list all processes on the host rather than just those + # from the container. + hostPID: true + # Labeling volumes from the root file system so they can be exposed to + # our container. + volumes: + - name: root + hostPath: + path: / + dnsPolicy: ClusterFirstWithHostNet + containers: + - name: grr + image: {{ .Values.grr.daemon.image.repository }}:{{ .Values.grr.daemon.image.tag }} + resources: + {{- toYaml .Values.grr.daemon.resources | nindent 10 }} + imagePullPolicy: {{ .Values.grr.daemon.imagePullPolicy }} + # Making it a privileged container. This way the processes within + # the container get almost the same privileges as those outside the + # container (e.g. manipulating the network stack or accessing devices). + securityContext: + privileged: true + # Exposing the machine's file system to the container (read-only). + volumeMounts: + - mountPath: /hostroot + name: root + readOnly: true \ No newline at end of file diff --git a/charts/grr-client/values.yaml b/charts/grr-client/values.yaml new file mode 100644 index 0000000..4e34f15 --- /dev/null +++ b/charts/grr-client/values.yaml @@ -0,0 +1,15 @@ +grr: + image: + repository: "ghcr.io/google/grr" + tag: latest + + daemon: + image: "grr-daemon:v0.1" + imagePullPolicy: "Never" + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi diff --git a/charts/grr/.helmignore b/charts/grr/.helmignore new file mode 100644 index 0000000..e746a6c --- /dev/null +++ b/charts/grr/.helmignore @@ -0,0 +1 @@ +*/configs/* \ No newline at end of file diff --git a/charts/grr/Chart.yaml b/charts/grr/Chart.yaml new file mode 100644 index 0000000..f8c7e8a --- /dev/null +++ b/charts/grr/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: grr +description: | + A toolset of DFIR tools +appVersion: "20240508" +type: application +version: 0.2.0 +maintainers: +- name: Tommy Skaug + email: tommy@skaug.me +keywords: +- timesketch +- forensics +- google +- scale +sources: +- https://github.com/google/osdfir-infrastructure diff --git a/charts/grr/README.md b/charts/grr/README.md new file mode 100644 index 0000000..9cf8b13 --- /dev/null +++ b/charts/grr/README.md @@ -0,0 +1,8 @@ + + +## Debugging + +```sh +task flux:sync +kubectl annotate es timesketch-conf force-sync=$(date +%s) --overwrite -n sec-forensics +``` diff --git a/charts/grr/templates/_helpers.tpl b/charts/grr/templates/_helpers.tpl new file mode 100644 index 0000000..2faa5e0 --- /dev/null +++ b/charts/grr/templates/_helpers.tpl @@ -0,0 +1,38 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "grr.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "grr.fullname" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "grr.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "grr.labels" -}} +helm.sh/chart: {{ include "grr.chart" . }} +{{ include "grr.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +date: "{{ now | htmlDate }}" +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "grr.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grr.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/grr/templates/configmaps.yaml b/charts/grr/templates/configmaps.yaml new file mode 100644 index 0000000..91af375 --- /dev/null +++ b/charts/grr/templates/configmaps.yaml @@ -0,0 +1,102 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: fleetspeak-services +data: + services.textproto: | + services { + name: "GRR" + factory: "GRPC" + config { + [type.googleapis.com/fleetspeak.grpcservice.Config] { + target: "{{ .Values.fleetspeak.frontend.url }}:4443" + insecure: true + } + } + } + broadcast_poll_time { + seconds: 1 + } +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: fleetspeak-admin-components +data: + admin.components.textproto: | + mysql_data_source_name: "{{`{{ .GRR_MYSQL_FLEETSPEAK_USERNAME }}`}}:{{`{{ .GRR_MYSQL_FLEETSPEAK_PASSWORD }}`}}@tcp({{ .Values.mysql.host }}:{{ .Values.mysql.port }})/{{ .Values.mysql.fleetspeak.database }}" + admin_config: < + listen_address: "0.0.0.0:4444" + > + notification_use_http_notifier: true + stats_config: < + address: "0.0.0.0:9002" + > +--- +{{- $cert := genSelfSignedCert .Values.fleetspeak.subjectCommonName nil (list "fleetspeak-frontend") 3650 }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: fleetspeak-frontend-components +data: + frontend.components.textproto: | + mysql_data_source_name: "{{`{{ .GRR_MYSQL_FLEETSPEAK_USERNAME }}`}}:{{`{{ .GRR_MYSQL_FLEETSPEAK_PASSWORD }}`}}@tcp({{ .Values.mysql.host }}:{{ .Values.mysql.port }})/{{ .Values.mysql.fleetspeak.database }}" + https_config: < + listen_address: "0.0.0.0:4443" + certificates: {{ $cert.Cert | quote }} + key: {{ $cert.Key | quote }} + {{- if .Values.fleetspeak.httpsHeaderChecksum }} + frontend_config: < + https_header_checksum_config: < + client_certificate_header: "client-certificate" + client_certificate_checksum_header: "X-Client-Cert-Hash" + > + > + {{- end }} + > + health_check_config: < + listen_address: "0.0.0.0:8080" + > + notification_listen_address: "0.0.0.0:12000" + notification_public_address: "{{ .Values.fleetspeak.frontend.url }}:12000" + stats_config: < + address: "0.0.0.0:9002" + > +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: grr-server-local +data: + server.local.yaml: | + Database.implementation: MysqlDB + Blobstore.implementation: DbBlobStore + Mysql.host: {{ .Values.mysql.host }} + Mysql.port: 3306 + Mysql.database: grr + Mysql.username: "{{`{{ .GRR_MYSQL_USERNAME }}`}}" + Mysql.password: "{{`{{ .GRR_MYSQL_PASSWORD }}`}}" + Mysql.flow_processing_threads_max: 20 + AdminUI.csrf_secret_key: "{{`{{ .GRR_CSRF_SECRET_KEY }}`}}" + AdminUI.url: http://localhost:8000 + AdminUI.bind: 0.0.0.0 + AdminUI.use_precompiled_js: true + API.DefaultRouter: ApiCallRouterWithoutChecks + + Logging.domain: localhost + Logging.verbose: true + Logging.engines: file,stderr + Logging.path: /grr + Logging.filename: /grr/grr-server.log + Monitoring.alert_email: grr-monitoring@localhost + Monitoring.emergency_access_email: grr-emergency@localhost + #Monitoring.http_address: 0.0.0.0 + #Monitoring.http_port: 9002 + + Client.executable_signing_public_key: "%(/grr/certs/executable-signing.crt|file)" + PrivateKeys.executable_signing_private_key: "%(/grr/certs/executable-signing.key|file)" + + Server.initialized: true + Server.fleetspeak_enabled: true + Server.fleetspeak_server: {{ .Values.fleetspeak.admin.url }}:4444 + Server.fleetspeak_message_listen_address: 0.0.0.0:11111 \ No newline at end of file diff --git a/charts/grr/templates/deployment-admin.yaml b/charts/grr/templates/deployment-admin.yaml new file mode 100644 index 0000000..7116e76 --- /dev/null +++ b/charts/grr/templates/deployment-admin.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grr-admin + labels: + app: grr-admin + {{- include "grr.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.grr.admin.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: grr-admin + template: + metadata: + labels: + app: grr-admin + app.kubernetes.io/name: grr-admin + prometheus: grr-admin + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: nodepool + operator: In + values: + - grr + containers: + - name: grr-admin + image: {{ .Values.grr.image.repository }}:{{ .Values.grr.image.tag }} + resources: + {{- toYaml .Values.grr.admin.resources | nindent 10 }} + ports: + - containerPort: 8000 + name: admin + - containerPort: 9001 + name: metrics + args: ["-component", "admin_ui", "-config", "/usr/src/grr/grr/core/install_data/etc/server.local.yaml", "--logtostderr"] + volumeMounts: + - name: grr-admin-config + mountPath: /usr/src/grr/grr/core/install_data/etc/server.local.yaml + subPath: server.local.yaml + - name: cert-volume + readOnly: true + mountPath: "/grr/certs" + volumes: + - name: grr-admin-config + secret: + secretName: grr-server-local + items: + - key: server.local.yaml + path: server.local.yaml + - name: cert-volume + secret: + secretName: grr-executable-signing-cert \ No newline at end of file diff --git a/charts/grr/templates/deployment-fleetspeak-admin.yaml b/charts/grr/templates/deployment-fleetspeak-admin.yaml new file mode 100644 index 0000000..7a0d4bf --- /dev/null +++ b/charts/grr/templates/deployment-fleetspeak-admin.yaml @@ -0,0 +1,64 @@ + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fleetspeak-admin + labels: + app: fleetspeak-admin + {{- include "grr.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.fleetspeak.admin.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: fleetspeak-admin + {{- include "grr.labels" . | nindent 6 }} + template: + metadata: + labels: + app: fleetspeak-admin + app.kubernetes.io/name: fleetspeak-admin + prometheus: fleetspeak-admin + {{- include "grr.labels" . | nindent 8 }} + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: nodepool + operator: In + values: + - grr + containers: + - name: fleetspeak-admin + image: {{ .Values.fleetspeak.image.repository }}:{{ .Values.fleetspeak.image.tag }} + resources: + {{- toYaml .Values.fleetspeak.admin.resources | nindent 10 }} + ports: + - containerPort: 4444 + name: admin + - containerPort: 9001 + name: metrics + command: ["/fleetspeak/bin/server"] + args: ["-alsologtostderr"] + volumeMounts: + - name: fleetspeak-admin-components + mountPath: /etc/fleetspeak-server/server.components.config + subPath: server.components.config + - name: fleetspeak-services + mountPath: /etc/fleetspeak-server/server.services.config + subPath: server.services.config + volumes: + - name: fleetspeak-admin-components + secret: + secretName: fleetspeak-admin-components + items: + - key: admin.components.textproto + path: server.components.config + - name: fleetspeak-services + configMap: + name: fleetspeak-services + items: + - key: services.textproto + path: server.services.config \ No newline at end of file diff --git a/charts/grr/templates/deployment-fleetspeak-frontend.yaml b/charts/grr/templates/deployment-fleetspeak-frontend.yaml new file mode 100644 index 0000000..516f4af --- /dev/null +++ b/charts/grr/templates/deployment-fleetspeak-frontend.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fleetspeak-frontend + labels: + app: fleetspeak-frontend + {{- include "grr.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.fleetspeak.frontend.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: fleetspeak-frontend + template: + metadata: + labels: + app: fleetspeak-frontend + app.kubernetes.io/name: fleetspeak-frontend + prometheus: fleetspeak-frontend + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: nodepool + operator: In + values: + - grr + initContainers: + - name: init-fleetspeak-frontend + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: busybox:1.36 + command: ['sh', '-c', "cp /stage/fleetspeak-server/server.*.config /etc/fleetspeak-server/; sed -i \"s/FLEETSPEAK_FRONTEND_IP/$POD_IP/g\" /etc/fleetspeak-server/server.components.config"] + volumeMounts: + - name: fleetspeak-config-volume + mountPath: /etc/fleetspeak-server + - name: fleetspeak-frontend-components + mountPath: /stage/fleetspeak-server/server.components.config + subPath: server.components.config + - name: fleetspeak-services + mountPath: /stage/fleetspeak-server/server.services.config + subPath: server.services.config + containers: + - name: fleetspeak-frontend + image: {{ .Values.fleetspeak.image.repository }}:{{ .Values.fleetspeak.image.tag }} + resources: + {{- toYaml .Values.fleetspeak.frontend.resources | nindent 10 }} + ports: + - containerPort: 4443 + name: frontend + - containerPort: 8080 + name: healthz + - containerPort: 12000 + name: notification + - containerPort: 9001 + name: metrics + readinessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + command: ["/fleetspeak/bin/server"] + args: ["-alsologtostderr"] + volumeMounts: + - name: fleetspeak-config-volume + mountPath: /etc/fleetspeak-server + volumes: + - name: fleetspeak-config-volume + emptyDir: + sizeLimit: 5Mi + - name: fleetspeak-frontend-components + secret: + secretName: fleetspeak-frontend-components + items: + - key: frontend.components.textproto + path: server.components.config + - name: fleetspeak-services + configMap: + name: fleetspeak-services + items: + - key: services.textproto + path: server.services.config \ No newline at end of file diff --git a/charts/grr/templates/deployment-frontend.yaml b/charts/grr/templates/deployment-frontend.yaml new file mode 100644 index 0000000..797d2a2 --- /dev/null +++ b/charts/grr/templates/deployment-frontend.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grr-frontend + labels: + app: grr-frontend + {{- include "grr.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.grr.frontend.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: grr-frontend + template: + metadata: + labels: + app: grr-frontend + app.kubernetes.io/name: grr-frontend + prometheus: grr-frontend + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: nodepool + operator: In + values: + - grr + containers: + - name: grr-frontend + image: {{ .Values.grr.image.repository }}:{{ .Values.grr.image.tag }} + resources: + {{- toYaml .Values.grr.frontend.resources | nindent 10 }} + ports: + - containerPort: 11111 + name: frontend + - containerPort: 9001 + name: metrics + args: ["-component", "frontend", "-config", "/usr/src/grr/grr/core/install_data/etc/server.local.yaml", "--logtostderr"] + volumeMounts: + - name: grr-frontend-config + mountPath: /usr/src/grr/grr/core/install_data/etc/server.local.yaml + subPath: server.local.yaml + - name: cert-volume + readOnly: true + mountPath: "/grr/certs" + volumes: + - name: grr-frontend-config + secret: + secretName: grr-server-local + items: + - key: server.local.yaml + path: server.local.yaml + - name: cert-volume + secret: + secretName: grr-executable-signing-cert \ No newline at end of file diff --git a/charts/grr/templates/deployment-worker.yaml b/charts/grr/templates/deployment-worker.yaml new file mode 100644 index 0000000..30d9256 --- /dev/null +++ b/charts/grr/templates/deployment-worker.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grr-worker + labels: + app: grr-worker + {{- include "grr.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: grr-worker + template: + metadata: + labels: + app: grr-worker + app.kubernetes.io/name: grr-worker + prometheus: grr-worker + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: nodepool + operator: In + values: + - grr + containers: + - name: grr-worker + image: {{ .Values.grr.image.repository }}:{{ .Values.grr.image.tag }} + resources: + {{- toYaml .Values.grr.worker.resources | nindent 10 }} + ports: + - containerPort: 9001 + name: metrics + args: ["-component", "worker", "-config", "/usr/src/grr/grr/core/install_data/etc/server.local.yaml", "--logtostderr"] + volumeMounts: + - name: grr-worker-config + mountPath: /usr/src/grr/grr/core/install_data/etc/server.local.yaml + subPath: server.local.yaml + - name: cert-volume + readOnly: true + mountPath: "/grr/certs" + volumes: + - name: grr-worker-config + secret: + secretName: grr-server-local + items: + - key: server.local.yaml + path: server.local.yaml + - name: cert-volume + secret: + secretName: grr-executable-signing-cert \ No newline at end of file diff --git a/charts/grr/templates/init-database.yaml b/charts/grr/templates/init-database.yaml new file mode 100644 index 0000000..43e92b0 --- /dev/null +++ b/charts/grr/templates/init-database.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "grr.fullname" . }}-init + labels: + {{- include "grr.labels" . | nindent 4 }} +spec: + template: + spec: + restartPolicy: Never + containers: + - name: mysql-db-init + image: "{{ .Values.initContainers.dbInit.image.repository }}:{{ .Values.initContainers.dbInit.image.tag }}" + command: ["/bin/sh", "-c"] + args: + ["/usr/bin/mysql -u root -h {{ .Values.mysql.host }} -p\"$MYSQL_ROOT_PASSWORD\" --execute \" + CREATE USER IF NOT EXISTS '$GRR_MYSQL_USERNAME'@'%%' IDENTIFIED BY '$GRR_MYSQL_PASSWORD'; + CREATE DATABASE IF NOT EXISTS grr; + GRANT ALL ON grr.* TO '$GRR_MYSQL_USERNAME'@'%%'; + CREATE USER IF NOT EXISTS '$GRR_MYSQL_FLEETSPEAK_USERNAME'@'%%' IDENTIFIED BY '$GRR_MYSQL_FLEETSPEAK_PASSWORD'; + CREATE DATABASE IF NOT EXISTS fleetspeak; + GRANT ALL ON fleetspeak.* TO '$GRR_MYSQL_FLEETSPEAK_USERNAME'@'%%'; + FLUSH PRIVILEGES;\""] + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.mysql.existingSecretName }} + key: MYSQL_ROOT_PASSWORD + - name: GRR_MYSQL_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.mysql.existingSecretName }} + key: GRR_MYSQL_USERNAME + - name: GRR_MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.mysql.existingSecretName }} + key: GRR_MYSQL_PASSWORD + - name: GRR_MYSQL_FLEETSPEAK_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.mysql.existingSecretName }} + key: GRR_MYSQL_FLEETSPEAK_USERNAME + - name: GRR_MYSQL_FLEETSPEAK_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.mysql.existingSecretName }} + key: GRR_MYSQL_FLEETSPEAK_PASSWORD + backoffLimit: 3 diff --git a/charts/grr/templates/secret-grr.yaml b/charts/grr/templates/secret-grr.yaml new file mode 100644 index 0000000..39a5c4e --- /dev/null +++ b/charts/grr/templates/secret-grr.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: grr-executable-signing-cert +data: + {{- $cert := genSelfSignedCert "{{.Values.grr.subjectCommonName}}" nil nil 3650 }} + executable-signing.crt: {{ b64enc $cert.Cert }} + executable-signing.key: {{ b64enc $cert.Key }} \ No newline at end of file diff --git a/charts/grr/templates/service.yaml b/charts/grr/templates/service.yaml new file mode 100644 index 0000000..18006f2 --- /dev/null +++ b/charts/grr/templates/service.yaml @@ -0,0 +1,67 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grr.fullname" . }}-fleetspeak-admin + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "grr.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: admin + port: 4444 + protocol: TCP + targetPort: 4444 + selector: + app: fleetspeak-admin +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grr.fullname" . }}-fleetspeak-frontend + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "grr.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: frontend + port: 4443 + protocol: TCP + targetPort: 4443 + selector: + app: fleetspeak-frontend +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grr.fullname" . }}-admin + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "grr.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: admin + port: 8000 + protocol: TCP + targetPort: 8000 + selector: + app: grr-admin +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grr.fullname" . }}-frontend + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "grr.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: frontend + port: 11111 + protocol: TCP + targetPort: 11111 + selector: + app: grr-frontend \ No newline at end of file diff --git a/charts/grr/templates/serviceaccount.yaml b/charts/grr/templates/serviceaccount.yaml new file mode 100644 index 0000000..e794d4c --- /dev/null +++ b/charts/grr/templates/serviceaccount.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "grr.fullname" . }} + labels: + {{- include "grr.labels" . | nindent 4 }} \ No newline at end of file diff --git a/charts/grr/values.yaml b/charts/grr/values.yaml new file mode 100644 index 0000000..87c7ba8 --- /dev/null +++ b/charts/grr/values.yaml @@ -0,0 +1,77 @@ +initContainers: + dbInit: + image: + repository: mariadb + tag: "10.11.6" + +mysql: + host: mariadb-dfir.databases.svc.cluster.local + port: 3306 + existingSecretName: grr-mysql-init-secret + fleetspeak: + database: fleetspeak + grr: + database: grr + +fleetspeak: + image: + repository: ghcr.io/google/fleetspeak + tag: latest + + httpsHeaderChecksum: false + subjectCommonName: "fleetspeak-frontend" + + admin: + replicas: 1 + url: grr-fleetspeak-admin.sec-forensics.svc.cluster.local + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi + frontend: + replicas: 1 + url: grr-fleetspeak-frontend.sec-forensics.svc.cluster.local + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi +grr: + image: + repository: "ghcr.io/google/grr" + tag: latest + + subjectCommonName: grr.252.no + admin: + replicas: 1 + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi + frontend: + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi + + worker: + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 50m + memory: 128Mi +prometheus: + metricsPort: 9001