mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Vulnerabilities run via crontab job (#9938)
# Checklist for submitter If some of the following don't apply, delete the relevant line. - [ ] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [ ] Documented any API changes (docs/Using-Fleet/REST-API.md or docs/Contributing/API-for-contributors.md) - [ ] Documented any permissions changes - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features. - [ ] Added/updated tests - [ ] Manual QA for all new/changed functionality - For Orbit and Fleet Desktop changes: - [ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux. - [ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)). --------- Co-authored-by: Benjamin Edwards <edwards.benw@gmail.com>
This commit is contained in:
parent
2e870004e5
commit
99b9c24b0a
4 changed files with 362 additions and 3 deletions
|
|
@ -0,0 +1,344 @@
|
|||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
labels:
|
||||
app: fleet
|
||||
chart: fleet
|
||||
heritage: {{ .Release.Service }}
|
||||
release: {{ .Release.Name }}
|
||||
name: {{ .Values.fleetName }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
schedule: "{{ .Values.crons.vulnerabilities }}"
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: {{ .Values.fleetName }}
|
||||
imagePullPolicy: Always
|
||||
command: [/usr/bin/fleet]
|
||||
args: ["vuln_processing"]
|
||||
image: {{ .Values.imageRepo }}:{{ .Values.imageTag }}
|
||||
ports:
|
||||
- name: {{ .Values.fleetName }}
|
||||
containerPort: {{ .Values.fleet.listenPort }}
|
||||
resources:
|
||||
limits:
|
||||
cpu: {{ .Values.resources.limits.cpu }}
|
||||
memory: {{ .Values.resources.limits.memory }}
|
||||
requests:
|
||||
cpu: {{ .Values.resources.requests.cpu }}
|
||||
memory: {{ .Values.resources.requests.memory }}
|
||||
env:
|
||||
## BEGIN FLEET SECTION
|
||||
- name: FLEET_SERVER_SANDBOX_ENABLED
|
||||
value: "1"
|
||||
- name: FLEET_LICENSE_ENFORCE_HOST_LIMIT
|
||||
value: "true"
|
||||
- name: FLEET_VULNERABILITIES_DATABASES_PATH
|
||||
value: /tmp/vuln
|
||||
{{- if ne .Values.packaging.enrollSecret "" }}
|
||||
- name: FLEET_PACKAGING_GLOBAL_ENROLL_SECRET
|
||||
value: "{{ .Values.packaging.enrollSecret }}"
|
||||
- name: FLEET_PACKAGING_S3_BUCKET
|
||||
value: "{{ .Values.packaging.s3.bucket }}"
|
||||
- name: FLEET_PACKAGING_S3_PREFIX
|
||||
value: "{{ .Values.packaging.s3.prefix }}"
|
||||
{{- end }}
|
||||
- name: FLEET_SERVER_ADDRESS
|
||||
value: "0.0.0.0:{{ .Values.fleet.listenPort }}"
|
||||
- name: FLEET_AUTH_BCRYPT_COST
|
||||
value: "{{ .Values.fleet.auth.bcryptCost }}"
|
||||
- name: FLEET_AUTH_SALT_KEY_SIZE
|
||||
value: "{{ .Values.fleet.auth.saltKeySize }}"
|
||||
- name: FLEET_APP_TOKEN_KEY_SIZE
|
||||
value: "{{ .Values.fleet.app.tokenKeySize }}"
|
||||
- name: FLEET_APP_TOKEN_VALIDITY_PERIOD
|
||||
value: "{{ .Values.fleet.app.inviteTokenValidityPeriod }}"
|
||||
- name: FLEET_SESSION_KEY_SIZE
|
||||
value: "{{ .Values.fleet.session.keySize }}"
|
||||
- name: FLEET_SESSION_DURATION
|
||||
value: "{{ .Values.fleet.session.duration }}"
|
||||
- name: FLEET_LOGGING_DEBUG
|
||||
value: "{{ .Values.fleet.logging.debug }}"
|
||||
- name: FLEET_LOGGING_JSON
|
||||
value: "{{ .Values.fleet.logging.json }}"
|
||||
- name: FLEET_LOGGING_DISABLE_BANNER
|
||||
value: "{{ .Values.fleet.logging.disableBanner }}"
|
||||
- name: FLEET_SERVER_TLS
|
||||
value: "{{ .Values.fleet.tls.enabled }}"
|
||||
{{- if .Values.fleet.tls.enabled }}
|
||||
- name: FLEET_SERVER_TLS_COMPATIBILITY
|
||||
value: "{{ .Values.fleet.tls.compatibility }}"
|
||||
- name: FLEET_SERVER_CERT
|
||||
value: "/secrets/tls/{{ .Values.fleet.tls.certSecretKey }}"
|
||||
- name: FLEET_SERVER_KEY
|
||||
value: "/secrets/tls/{{ .Values.fleet.tls.keySecretKey }}"
|
||||
{{- end }}
|
||||
{{- if ne .Values.fleet.carving.s3.bucketName "" }}
|
||||
- name: FLEET_S3_BUCKET
|
||||
value: "{{ .Values.fleet.carving.s3.bucketName }}"
|
||||
- name: FLEET_S3_PREFIX
|
||||
value: "{{ .Values.fleet.carving.s3.prefix }}"
|
||||
{{- if ne .Values.fleet.carving.s3.accessKeyID "" }}
|
||||
- name: FLEET_S3_ACCESS_KEY_ID
|
||||
value: "{{ .Values.fleet.carving.s3.accessKeyID }}"
|
||||
- name: FLEET_S3_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.fleet.secretName }}"
|
||||
key: "{{ .Values.fleet.carving.s3.secretKey }}"
|
||||
{{ else }}
|
||||
- name: FLEET_S3_STS_ASSUME_ROLE_ARN
|
||||
value: "{{ .Values.fleet.carving.s3.stsAssumeRoleARN }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
## END FLEET SECTION
|
||||
## BEGIN MYSQL SECTION
|
||||
- name: FLEET_MYSQL_ADDRESS
|
||||
value: "{{ .Values.mysql.address }}"
|
||||
- name: FLEET_MYSQL_DATABASE
|
||||
value: "{{ .Values.mysql.database }}"
|
||||
- name: FLEET_MYSQL_USERNAME
|
||||
value: "{{ .Values.mysql.username }}"
|
||||
- name: FLEET_MYSQL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.mysql.secretName }}
|
||||
key: {{ .Values.mysql.passwordKey }}
|
||||
- name: FLEET_MYSQL_MAX_OPEN_CONNS
|
||||
value: "{{ .Values.mysql.maxOpenConns }}"
|
||||
- name: FLEET_MYSQL_MAX_IDLE_CONNS
|
||||
value: "{{ .Values.mysql.maxIdleConns }}"
|
||||
- name: FLEET_MYSQL_CONN_MAX_LIFETIME
|
||||
value: "{{ .Values.mysql.connMaxLifetime }}"
|
||||
{{- if .Values.mysql.tls.enabled }}
|
||||
- name: FLEET_MYSQL_TLS_CA
|
||||
value: "/secrets/mysql/{{ .Values.mysql.tls.caCertKey }}"
|
||||
- name: FLEET_MYSQL_TLS_CERT
|
||||
value: "/secrets/mysql/{{ .Values.mysql.tls.certKey }}"
|
||||
- name: FLEET_MYSQL_TLS_KEY
|
||||
value: "/secrets/mysql/{{ .Values.mysql.tls.keyKey }}"
|
||||
- name: FLEET_MYSQL_TLS_CONFIG
|
||||
value: "{{ .Values.mysql.tls.config }}"
|
||||
- name: FLEET_MYSQL_TLS_SERVER_NAME
|
||||
value: "{{ .Values.mysql.tls.serverName }}"
|
||||
{{- end }}
|
||||
## END MYSQL SECTION
|
||||
## BEGIN REDIS SECTION
|
||||
- name: FLEET_REDIS_ADDRESS
|
||||
value: "{{ .Values.redis.address }}"
|
||||
- name: FLEET_REDIS_DATABASE
|
||||
value: "{{ .Values.redis.database }}"
|
||||
{{- if .Values.redis.usePassword }}
|
||||
- name: FLEET_REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.redis.secretName }}"
|
||||
key: "{{ .Values.redis.passwordKey }}"
|
||||
{{- end }}
|
||||
## END REDIS SECTION
|
||||
## BEGIN OSQUERY SECTION
|
||||
- name: FLEET_OSQUERY_NODE_KEY_SIZE
|
||||
value: "{{ .Values.osquery.nodeKeySize }}"
|
||||
- name: FLEET_OSQUERY_LABEL_UPDATE_INTERVAL
|
||||
value: "{{ .Values.osquery.labelUpdateInterval }}"
|
||||
- name: FLEET_OSQUERY_DETAIL_UPDATE_INTERVAL
|
||||
value: "{{ .Values.osquery.detailUpdateInterval }}"
|
||||
- name: FLEET_OSQUERY_STATUS_LOG_PLUGIN
|
||||
value: "{{ .Values.osquery.logging.statusPlugin }}"
|
||||
- name: FLEET_OSQUERY_RESULT_LOG_PLUGIN
|
||||
value: "{{ .Values.osquery.logging.resultPlugin }}"
|
||||
{{- if eq .Values.osquery.logging.statusPlugin "filesystem" }}
|
||||
- name: FLEET_FILESYSTEM_STATUS_LOG_FILE
|
||||
value: "/logs/{{ .Values.osquery.logging.filesystem.statusLogFile }}"
|
||||
{{- end }}
|
||||
{{- if eq .Values.osquery.logging.resultPlugin "filesystem" }}
|
||||
- name: FLEET_FILESYSTEM_RESULT_LOG_FILE
|
||||
value: "/logs/{{ .Values.osquery.logging.filesystem.resultLogFile }}"
|
||||
{{- end }}
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "filesystem") (eq .Values.osquery.logging.resultPlugin "filesystem") }}
|
||||
- name: FLEET_FILESYSTEM_ENABLE_LOG_ROTATION
|
||||
value: "{{ .Values.osquery.logging.filesystem.enableRotation }}"
|
||||
- name: FLEET_FILESYSTEM_ENABLE_LOG_COMPRESSION
|
||||
value: "{{ .Values.osquery.logging.filesystem.enableCompression }}"
|
||||
{{- end }}
|
||||
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "firehose") (eq .Values.osquery.logging.resultPlugin "firehose") }}
|
||||
- name: FLEET_FIREHOSE_REGION
|
||||
value: "{{ .Values.osquery.logging.firehose.region }}"
|
||||
{{- if eq .Values.osquery.logging.statusPlugin "firehose" }}
|
||||
- name: FLEET_FIREHOSE_STATUS_STREAM
|
||||
value: "{{ .Values.osquery.logging.firehose.statusStream }}"
|
||||
{{- end }}
|
||||
{{- if eq .Values.osquery.logging.resultPlugin "firehose" }}
|
||||
- name: FLEET_FIREHOSE_RESULT_STREAM
|
||||
value: "{{ .Values.osquery.logging.firehose.resultStream }}"
|
||||
{{- end }}
|
||||
{{- if ne .Values.osquery.logging.firehose.accessKeyID "" }}
|
||||
- name: FLEET_FIREHOSE_ACCESS_KEY_ID
|
||||
value: "{{ .Values.osquery.logging.firehose.accessKeyID }}"
|
||||
- name: FLEET_FIREHOSE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.osquery.secretName }}"
|
||||
key: "{{ .Values.osquery.logging.firehose.secretKey }}"
|
||||
{{ else }}
|
||||
- name: FLEET_FIREHOSE_STS_ASSUME_ROLE_ARN
|
||||
value: "{{ .Values.osquery.logging.firehose.stsAssumeRoleARN }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "kinesis") (eq .Values.osquery.logging.resultPlugin "kinesis") }}
|
||||
- name: FLEET_KINESIS_REGION
|
||||
value: "{{ .Values.osquery.logging.kinesis.region }}"
|
||||
{{- if eq .Values.osquery.logging.statusPlugin "kinesis" }}
|
||||
- name: FLEET_KINESIS_STATUS_STREAM
|
||||
value: "{{ .Values.osquery.logging.kinesis.statusStream }}"
|
||||
{{- end }}
|
||||
{{- if eq .Values.osquery.logging.resultPlugin "kinesis" }}
|
||||
- name: FLEET_KINESIS_RESULT_STREAM
|
||||
value: "{{ .Values.osquery.logging.kinesis.resultStream }}"
|
||||
{{- end }}
|
||||
{{- if ne .Values.osquery.logging.kinesis.accessKeyID "" }}
|
||||
- name: FLEET_KINESIS_ACCESS_KEY_ID
|
||||
value: "{{ .Values.osquery.logging.kinesis.accessKeyID }}"
|
||||
- name: FLEET_KINESIS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.osquery.secretName }}"
|
||||
key: "{{ .Values.osquery.logging.kinesis.secretKey }}"
|
||||
{{ else }}
|
||||
- name: FLEET_KINESIS_STS_ASSUME_ROLE_ARN
|
||||
value: "{{ .Values.osquery.logging.kinesis.stsAssumeRoleARN }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "lambda") (eq .Values.osquery.logging.resultPlugin "lambda") }}
|
||||
- name: FLEET_LAMBDA_REGION
|
||||
value: "{{ .Values.osquery.logging.lambda.region }}"
|
||||
{{- if eq .Values.osquery.logging.statusPlugin "lambda" }}
|
||||
- name: FLEET_LAMBDA_STATUS_FUNCTION
|
||||
value: "{{ .Values.osquery.logging.lambda.statusFunction }}"
|
||||
{{- end }}
|
||||
{{- if eq .Values.osquery.logging.resultPlugin "lambda" }}
|
||||
- name: FLEET_LAMBDA_RESULT_FUNCTION
|
||||
value: "{{ .Values.osquery.logging.lambda.resultFunction }}"
|
||||
{{- end }}
|
||||
{{- if ne .Values.osquery.logging.lambda.accessKeyID "" }}
|
||||
- name: FLEET_LAMBDA_ACCESS_KEY_ID
|
||||
value: "{{ .Values.osquery.logging.lambda.accessKeyID }}"
|
||||
- name: FLEET_LAMBDA_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.osquery.secretName }}"
|
||||
key: "{{ .Values.osquery.logging.lambda.secretKey }}"
|
||||
{{ else }}
|
||||
- name: FLEET_LAMBDA_STS_ASSUME_ROLE_ARN
|
||||
value: "{{ .Values.osquery.logging.lambda.stsAssumeRoleARN }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "pubsub") (eq .Values.osquery.logging.resultPlugin "pubsub") }}
|
||||
- name: FLEET_PUBSUB_PROJECT
|
||||
value: "{{ .Values.osquery.logging.pubsub.project }}"
|
||||
{{- end }}
|
||||
{{- if eq .Values.osquery.logging.statusPlugin "pubsub" }}
|
||||
- name: FLEET_PUBSUB_STATUS_TOPIC
|
||||
value: "{{ .Values.osquery.logging.pubsub.statusTopic }}"
|
||||
{{- end }}
|
||||
{{- if eq .Values.osquery.logging.resultPlugin "pubsub" }}
|
||||
- name: FLEET_PUBSUB_RESULT_TOPIC
|
||||
value: "{{ .Values.osquery.logging.pubsub.resultTopic }}"
|
||||
{{- end }}
|
||||
## END OSQUERY SECTION
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: [ALL]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 3333
|
||||
runAsUser: 3333
|
||||
runAsNonRoot: true
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: {{ .Values.fleet.listenPort }}
|
||||
timeoutSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: {{ .Values.fleet.listenPort }}
|
||||
timeoutSeconds: 10
|
||||
{{- if or (.Values.fleet.tls.enabled) (.Values.mysql.tls.enabled) (eq .Values.osquery.logging.statusPlugin "filesystem") (eq .Values.osquery.logging.resultPlugin "filesystem") }}
|
||||
volumeMounts:
|
||||
{{- if .Values.fleet.tls.enabled }}
|
||||
- name: {{ .Values.fleetName }}-tls
|
||||
readOnly: true
|
||||
mountPath: /secrets/tls
|
||||
{{- end }}
|
||||
{{- if .Values.mysql.tls.enabled }}
|
||||
- name: mysql-tls
|
||||
readOnly: true
|
||||
mountPath: /secrets/mysql
|
||||
{{- end }}
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "filesystem") (eq .Values.osquery.logging.resultPlugin "filesystem") }}
|
||||
- name: osquery-logs
|
||||
mountPath: /logs
|
||||
{{- end }}
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
{{- end }}
|
||||
{{- if .Values.gke.cloudSQL.enableProxy }}
|
||||
- name: cloudsql-proxy
|
||||
image: "gcr.io/cloudsql-docker/gce-proxy:{{ .Values.gke.cloudSQL.imageTag }}"
|
||||
command:
|
||||
- "/cloud_sql_proxy"
|
||||
- "-verbose={{ .Values.gke.cloudSQL.verbose}}"
|
||||
- "-instances={{ .Values.gke.cloudSQL.instanceName }}=tcp:3306"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 0.5 # 500Mhz
|
||||
memory: 150Mi
|
||||
requests:
|
||||
cpu: 0.1 # 100Mhz
|
||||
memory: 50Mi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: [ALL]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: 3333
|
||||
runAsUser: 3333
|
||||
runAsNonRoot: true
|
||||
{{- end }}
|
||||
hostPID: false
|
||||
hostNetwork: false
|
||||
hostIPC: false
|
||||
serviceAccountName: {{ .Values.fleetName }}
|
||||
{{- if or (.Values.fleet.tls.enabled) (.Values.mysql.tls.enabled) (eq .Values.osquery.logging.statusPlugin "filesystem") (eq .Values.osquery.logging.resultPlugin "filesystem") }}
|
||||
volumes:
|
||||
{{- if .Values.fleet.tls.enabled }}
|
||||
- name: {{ .Values.fleetName }}-tls
|
||||
secret:
|
||||
secretName: "{{ .Values.fleet.secretName }}"
|
||||
{{- end }}
|
||||
{{- if .Values.mysql.tls.enabled }}
|
||||
- name: mysql-tls
|
||||
secret:
|
||||
secretName: "{{ .Values.mysql.secretName }}"
|
||||
{{- end }}
|
||||
{{- if or (eq .Values.osquery.logging.statusPlugin "filesystem") (eq .Values.osquery.logging.resultPlugin "filesystem") }}
|
||||
- name: osquery-logs
|
||||
emptyDir:
|
||||
sizeLimit: "{{ .Values.osquery.logging.filesystem.volumeSize }}"
|
||||
{{- end }}
|
||||
- name: tmp
|
||||
emptyDir:
|
||||
{{- end }}
|
||||
|
|
@ -50,10 +50,12 @@ spec:
|
|||
memory: {{ .Values.resources.requests.memory }}
|
||||
env:
|
||||
## BEGIN FLEET SECTION
|
||||
- name: FLEET_VULNERABILITIES_EXTERNAL_SCHEDULED
|
||||
value: "true"
|
||||
- name: FLEET_SESSION_DURATION
|
||||
value: "1y"
|
||||
- name: FLEET_SERVER_SANDBOX_ENABLED
|
||||
value: "1"
|
||||
- name: FLEET_VULNERABILITIES_PERIODICITY
|
||||
value: "15m"
|
||||
- name: FLEET_LICENSE_ENFORCE_HOST_LIMIT
|
||||
value: "true"
|
||||
- name: FLEET_VULNERABILITIES_DATABASES_PATH
|
||||
|
|
|
|||
|
|
@ -187,3 +187,6 @@ gke:
|
|||
useManagedCertificate: false
|
||||
# Workload Identity allows the K8s service account to assume the IAM permissions of a GCP service account
|
||||
workloadIdentityEmail: ""
|
||||
|
||||
crons:
|
||||
vulnerabilities: "0,15,30,45 * * * *"
|
||||
|
|
|
|||
|
|
@ -81,6 +81,11 @@ resource "random_password" "db" {
|
|||
length = 8
|
||||
}
|
||||
|
||||
resource "random_integer" "cron_offset" {
|
||||
min = 0
|
||||
max = 14
|
||||
}
|
||||
|
||||
resource "helm_release" "main" {
|
||||
name = terraform.workspace
|
||||
chart = "${path.module}/fleet"
|
||||
|
|
@ -157,7 +162,7 @@ resource "helm_release" "main" {
|
|||
|
||||
set {
|
||||
name = "imageTag"
|
||||
value = "v4.27.1"
|
||||
value = "v4.26.0-1"
|
||||
}
|
||||
|
||||
set {
|
||||
|
|
@ -184,6 +189,11 @@ resource "helm_release" "main" {
|
|||
name = "serviceAccountAnnotations.eks\\.amazonaws\\.com/role-arn"
|
||||
value = aws_iam_role.main.arn
|
||||
}
|
||||
|
||||
set {
|
||||
name = "crons.vulnerabilities"
|
||||
value = "${random_integer.cron_offset.result}\\,${random_integer.cron_offset.result + 15}\\,${random_integer.cron_offset.result + 30}\\,${random_integer.cron_offset.result + 45} * * * *"
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "main" {
|
||||
|
|
|
|||
Loading…
Reference in a new issue