diff --git a/operator/README.md b/operator/README.md index 817682670b..d3127e4aa8 100644 --- a/operator/README.md +++ b/operator/README.md @@ -21,6 +21,9 @@ helm install securecodebox-operator secureCodeBox/operator | Key | Type | Default | Description | |-----|------|---------|-------------| +| customCACertificate | object | `{"certificate":"public.crt","existingCertificate":null}` | Setup for Custom CA certificates. These are automatically mounted into every secureCodeBox component (lurcher, parser & hooks). Requires that every namespace has a configmap with the CA certificate(s) | +| customCACertificate.certificate | string | `"public.crt"` | key in the configmap holding the certificate(s) | +| customCACertificate.existingCertificate | string | `nil` | name of the configMap holding the ca certificate(s), needs to be the same across all namespaces | | image.pullPolicy | string | `"Always"` | Image pull policy | | image.repository | string | `"docker.io/securecodebox/operator"` | The operator image repository | | image.tag | string | defaults to the charts version | Parser image tag | @@ -29,8 +32,10 @@ helm install securecodebox-operator secureCodeBox/operator | lurcher.image.tag | string | defaults to the charts version | Parser image tag | | minio.defaultBucket.enabled | bool | `true` | | | minio.defaultBucket.name | string | `"securecodebox"` | | -| minio.enabled | bool | `true` | | +| minio.enabled | bool | `true` | Enable this to use minio as storage backend instead of a cloud bucket provider like AWS S3, Google Cloud Storage, DigitalOcean Spaces etc. | | minio.resources.requests.memory | string | `"256Mi"` | | +| minio.tls.certSecret | string | `"minio-tls"` | | +| minio.tls.enabled | bool | `false` | | | podSecurityContext | object | `{}` | Sets the securityContext on the operators pod level. See: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container | | resources | object | `{"limits":{"cpu":"100m","memory":"30Mi"},"requests":{"cpu":"100m","memory":"20Mi"}}` | CPU/memory resource requests/limits (see: https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/, https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) | | s3.authType | string | `"access-secret-key"` | Authentication method. Supports access-secret-key (used by most s3 endpoint) and aws-irsa (Used by AWS EKS IAM Role to Kubenetes Service Account Binding. Support for AWS IRSA is considered experimental in the secureCodeBox) | diff --git a/operator/controllers/execution/scans/hook_reconciler.go b/operator/controllers/execution/scans/hook_reconciler.go index a9dfc058a5..0f6e53c13c 100644 --- a/operator/controllers/execution/scans/hook_reconciler.go +++ b/operator/controllers/execution/scans/hook_reconciler.go @@ -417,6 +417,10 @@ func (r *ScanReconciler) createJobForHook(hook *executionv1.ScanCompletionHook, }, }, } + + r.Log.V(8).Info("Configuring customCACerts for Hook") + injectCustomCACertsIfConfigured(job) + if err := ctrl.SetControllerReference(scan, job, r.Scheme); err != nil { r.Log.Error(err, "Unable to set controllerReference on job", "job", job) return "", err diff --git a/operator/controllers/execution/scans/job.go b/operator/controllers/execution/scans/job.go index bfb12aa085..1a72417a20 100644 --- a/operator/controllers/execution/scans/job.go +++ b/operator/controllers/execution/scans/job.go @@ -2,9 +2,12 @@ package scancontrollers import ( "context" + "fmt" + "os" executionv1 "github.com/secureCodeBox/secureCodeBox/operator/apis/execution/v1" batch "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -64,3 +67,42 @@ func (r *ScanReconciler) checkIfJobIsCompleted(scan *executionv1.Scan, labels cl return checkIfAllJobsCompleted(jobs), nil } + +// injectCustomCACertsIfConfigured injects CA Certificates to /etc/ssl/certs/ +// currently only supports jobs with a single container +func injectCustomCACertsIfConfigured(job *batch.Job) { + customCACertificate, isConfigured := os.LookupEnv("CUSTOM_CA_CERTIFICATE_EXISTING_CERTIFICATE") + if !isConfigured { + return + } + + job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: "ca-certificate", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: customCACertificate, + }, + }, + }, + }) + + certificateName, hasCertificateName := os.LookupEnv("CUSTOM_CA_CERTIFICATE_NAME") + if !hasCertificateName { + panic("Missing CUSTOM_CA_CERTIFICATE_NAME config parameter. Do you have `customCACertificate.certificate` configured you helm values?") + } + mountPath := fmt.Sprintf("/etc/ssl/certs/%s", certificateName) + + job.Spec.Template.Spec.Containers[0].VolumeMounts = append(job.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{ + Name: "ca-certificate", + ReadOnly: true, + MountPath: mountPath, + SubPath: certificateName, + }) + + // Add env var for node.js to load the custom ca certs + job.Spec.Template.Spec.Containers[0].Env = append(job.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{ + Name: "NODE_EXTRA_CA_CERTS", + Value: mountPath, + }) +} diff --git a/operator/controllers/execution/scans/parse_reconciler.go b/operator/controllers/execution/scans/parse_reconciler.go index 5ea58ebd2c..49e2a23063 100644 --- a/operator/controllers/execution/scans/parse_reconciler.go +++ b/operator/controllers/execution/scans/parse_reconciler.go @@ -174,6 +174,9 @@ func (r *ScanReconciler) startParser(scan *executionv1.Scan) error { parseDefinition.Spec.Volumes..., ) + r.Log.V(8).Info("Configuring customCACerts for Parser") + injectCustomCACertsIfConfigured(job) + if err := ctrl.SetControllerReference(scan, job, r.Scheme); err != nil { return err } diff --git a/operator/controllers/execution/scans/scan_reconciler.go b/operator/controllers/execution/scans/scan_reconciler.go index fae0a2454a..15a2a0e268 100644 --- a/operator/controllers/execution/scans/scan_reconciler.go +++ b/operator/controllers/execution/scans/scan_reconciler.go @@ -276,6 +276,29 @@ func (r *ScanReconciler) constructJobForScan(scan *executionv1.Scan, scanType *e }, } + customCACertificate, isConfigured := os.LookupEnv("CUSTOM_CA_CERTIFICATE_EXISTING_CERTIFICATE") + r.Log.Info("Configuring customCACerts for lurcher", "customCACertificate", customCACertificate, "isConfigured", isConfigured) + if customCACertificate != "" { + job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, corev1.Volume{ + Name: "ca-certificate", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: customCACertificate, + }, + }, + }, + }) + + certificateName := os.Getenv("CUSTOM_CA_CERTIFICATE_NAME") + lurcherSidecar.VolumeMounts = append(lurcherSidecar.VolumeMounts, corev1.VolumeMount{ + Name: "ca-certificate", + ReadOnly: true, + MountPath: "/etc/ssl/certs/" + certificateName, + SubPath: certificateName, + }) + } + job.Spec.Template.Spec.Containers = append(job.Spec.Template.Spec.Containers, *lurcherSidecar) if err := ctrl.SetControllerReference(scan, job, r.Scheme); err != nil { diff --git a/operator/templates/manager/manager.yaml b/operator/templates/manager/manager.yaml index 8332b32639..c62ea31f71 100644 --- a/operator/templates/manager/manager.yaml +++ b/operator/templates/manager/manager.yaml @@ -15,6 +15,12 @@ spec: labels: control-plane: securecodebox-controller-manager spec: + {{- if .Values.customCACertificate.existingCertificate }} + volumes: + - name: ca-certificate + configMap: + name: {{ .Values.customCACertificate.existingCertificate }} + {{- end }} serviceAccountName: {{ .Values.serviceAccount.name }} securityContext: {{ .Values.podSecurityContext | toYaml | nindent 8 }} @@ -24,6 +30,12 @@ spec: args: - --enable-leader-election image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.Version }}" + {{- if .Values.customCACertificate.existingCertificate }} + volumeMounts: + - name: ca-certificate + mountPath: /etc/ssl/certs/{{ .Values.customCACertificate.certificate }} + subPath: {{ .Values.customCACertificate.certificate }} + {{- end }} imagePullPolicy: {{ .Values.image.pullPolicy }} name: manager env: @@ -34,7 +46,7 @@ spec: # TODO: integrate with cert manager and auto gen a cert for minio {{- if .Values.minio.enabled }} - name: S3_USE_SSL - value: 'false' + value: "{{ .Values.minio.tls.enabled }}" - name: S3_ENDPOINT value: "{{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc.cluster.local" - name: S3_PORT @@ -86,6 +98,12 @@ spec: value: "{{ .Values.lurcher.image.repository }}:{{ .Values.lurcher.image.tag | default .Chart.Version }}" - name: LURCHER_PULL_POLICY value: {{ .Values.lurcher.image.pullPolicy }} + {{- if .Values.customCACertificate.existingCertificate }} + - name: CUSTOM_CA_CERTIFICATE_EXISTING_CERTIFICATE + value: {{ .Values.customCACertificate.existingCertificate | quote }} + - name: CUSTOM_CA_CERTIFICATE_NAME + value: {{ .Values.customCACertificate.certificate | quote }} + {{ end }} resources: {{- toYaml .Values.resources | nindent 12 }} securityContext: diff --git a/operator/values.yaml b/operator/values.yaml index 1b7c8f09e0..17c5ba4dd3 100644 --- a/operator/values.yaml +++ b/operator/values.yaml @@ -14,6 +14,13 @@ image: # image.pullPolicy -- Image pull policy pullPolicy: Always +# -- Setup for Custom CA certificates. These are automatically mounted into every secureCodeBox component (lurcher, parser & hooks). +# Requires that every namespace has a configmap with the CA certificate(s) +customCACertificate: + # -- name of the configMap holding the ca certificate(s), needs to be the same across all namespaces + existingCertificate: null + # -- key in the configmap holding the certificate(s) + certificate: "public.crt" serviceAccount: # -- Name of the serviceAccount the operator uses to talk to the k8s api @@ -52,8 +59,11 @@ lurcher: pullPolicy: Always minio: - # minio.enabled Enable this to use minio as storage backend instead of a cloud bucket provider like AWS S3, Google Cloud Storage, DigitalOcean Spaces etc. + # -- Enable this to use minio as storage backend instead of a cloud bucket provider like AWS S3, Google Cloud Storage, DigitalOcean Spaces etc. enabled: true + tls: + enabled: false + certSecret: minio-tls defaultBucket: enabled: true name: "securecodebox" diff --git a/scanners/amass/Chart.yaml b/scanners/amass/Chart.yaml index 4011cb9921..d87b93f69c 100644 --- a/scanners/amass/Chart.yaml +++ b/scanners/amass/Chart.yaml @@ -5,8 +5,8 @@ description: A Helm chart for the Amass security scanner that integrates with th type: application # version - gets automatically set to the secureCodeBox release version when the helm charts gets published version: v2.5.0-alpha1 -# Latest Amass release version can be found here: https://github.com/OWASP/Amass/releases -appVersion: "v3.10.5" +# Latest Amass release version can be found here: https://github.com/OWASP/Amass/releases +appVersion: "v3.11.3" kubeVersion: ">=v1.11.0-0" keywords: diff --git a/scanners/gitleaks/README.md b/scanners/gitleaks/README.md index d46cad4814..fc220135ad 100644 --- a/scanners/gitleaks/README.md +++ b/scanners/gitleaks/README.md @@ -90,7 +90,7 @@ For more information on how to use cascades take a look at | Key | Type | Default | Description | |-----|------|---------|-------------| | image.repository | string | `"docker.io/securecodebox/scanner-gitleaks"` | Container Image to run the scan | -| image.tag | string | `nil` | defaults to the charts version | +| image.tag | string | `nil` | defaults to the app version | | parseJob.ttlSecondsAfterFinished | string | `nil` | seconds after which the kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | | parserImage.repository | string | `"docker.io/securecodebox/parser-gitleaks"` | Parser image repository | | parserImage.tag | string | defaults to the charts version | Parser image tag | diff --git a/scanners/gitleaks/values.yaml b/scanners/gitleaks/values.yaml index 7dddc6c614..57a4c3f65a 100644 --- a/scanners/gitleaks/values.yaml +++ b/scanners/gitleaks/values.yaml @@ -1,7 +1,7 @@ image: # image.repository -- Container Image to run the scan repository: docker.io/securecodebox/scanner-gitleaks - # image.tag -- defaults to the charts version + # image.tag -- defaults to the app version tag: null parserImage: