diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..55ea3527 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +## 0.1.0 - 2024-09-05 - *First GA release.* + +Official website for the docs: [https://docs.falco-talon.org/](https://docs.falco-talon.org/) + +This release contains: +- the **rule engine to match the Falco events with the actions to perform** +- basic **CLI** features: **check** of the rules, **list** the available actionners, outputs, notifiers, start the **web server** to receive the Falco events +- **metrics** in **Prometheus** and **OTEL format** +- export of **OTEL traces** +- deduplication of the Falco events with **NATS Jetstream** +- 13 **actionners**: + - `kubernetes:terminate` + - `kubernetes:label` + - `kubernetes:networkpolicy` + - `kubernetes:exec` + - `kubernetes:script` + - `kubernetes:log` + - `kubernetes:delete` + - `kubernetes:drain` + - `kubernetes:download` + - `kubernetes:tcpdump` + - `aws:lambda` + - `calico:networkpolicy` + - `cilium:networkpolicy` +- 6 **notifiers**: + - `elasticsearch` + - `k8s events` + - `loki` + - `slack` + - `smtp` + - `webhook` +- 3 **outputs**: + - `local:file` + - `aws:s3` + - `minio:s3` +- 2 **context** enrichments: + - `aws` (with IMDS) + - `k8s` diff --git a/deployment/helm/CHANGELOG.md b/deployment/helm/CHANGELOG.md new file mode 100644 index 00000000..7405c06b --- /dev/null +++ b/deployment/helm/CHANGELOG.md @@ -0,0 +1,8 @@ +# Change Log + +This file documents all notable changes to Falco Talon Helm Chart. The release +numbering uses [semantic versioning](http://semver.org). + +## 0.1.0 + +- First release diff --git a/deployment/helm/Chart.yaml b/deployment/helm/Chart.yaml index 01ef4636..d91763a2 100644 --- a/deployment/helm/Chart.yaml +++ b/deployment/helm/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 -appVersion: 0.1.0 -description: React to events from Falco +appVersion: v0.1.0 +description: React to the events from Falco name: falco-talon version: 0.1.0 keywords: diff --git a/deployment/helm/README.gotmpl b/deployment/helm/README.gotmpl new file mode 100644 index 00000000..8b985900 --- /dev/null +++ b/deployment/helm/README.gotmpl @@ -0,0 +1,61 @@ +# Falco Talon + +![release](https://flat.badgen.net/github/release/falco-talon/falco-talon/latest?color=green) ![last commit](https://flat.badgen.net/github/last-commit/falco-talon/falco-talon) ![licence](https://flat.badgen.net/badge/license/MIT/blue) ![docker pulls](https://flat.badgen.net/docker/pulls/issif/falco-talon?icon=docker) + +## Description + +`Falco Talon` is a Response Engine for managing threats in your Kubernetes. It enhances the solutions proposed by the Falco community with a no-code tailor made solution. With easy rules, you can react to `events` from [`Falco`](https://falco.org) in milliseconds. + +## Architecture + +`Falco Talon` can receive the `events` from [`Falco`](https://falco.org) or [`Falcosidekick`](https://github.com/falco-talon/falcosidekick): + +## Documentation + +The full documentation is available on its own website: [https://docs.falco-talon.org/docs](https://docs.falco-talon.org/docs). + +## Helm + +The helm chart is available in the folder [`deployment/helm`](https://github.com/falco-talon/falco-talon/tree/main/deployment/helm). + +Two config files are provided: +* `values.yaml` allows you to configure `Falcon Talon` and the deployment +* `rules.yaml` contains rules to set + +### Install Falco Talon + +```shell +git clone https://github.com/falco-talon/falco-talon.git +cd deployment/helm/ +helm upgrade -i falco-talon . -n falco --create-namespace -f values.yaml +``` + +### Uninstall Falco Talon + +``` +helm delete falco-talon -n falco +```` + +### Configuration + +{{ template "chart.valuesSection" . }} + +## Configure Falcosidekick + +Once you have installed `Falco Talon` with Helm, you need to connect `Falcosidekick` by adding the flag `--set falcosidekick.config.webhook.address=http://falco-talon:2803` + +```shell +helm upgrade -i falco falco-talon/falco --namespace falco \ + --create-namespace \ + --set tty=true \ + --set falcosidekick.enabled=true \ + --set falcosidekick.config.talon.address=http://falco-talon:2803 +``` + +## License + +Falco Talon is licensed to you under the [Apache 2.0](./LICENSE) open source license. + +## Author + +Thomas Labarussias (https://github.com/Issif) \ No newline at end of file diff --git a/deployment/helm/README.md b/deployment/helm/README.md index 30404ce4..10ca13de 100644 --- a/deployment/helm/README.md +++ b/deployment/helm/README.md @@ -1 +1,120 @@ -TODO \ No newline at end of file +# falco-talon + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![AppVersion: v0.1.0](https://img.shields.io/badge/AppVersion-v0.1.0-informational?style=flat-square) + +React to the events from Falco + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Issif | | | + +## Source Code + +* + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | affinity | +| config | object | `{"aws":{"accesKey":"","externalId":"","region":"","roleArn":"","secretKey":""},"deduplication":{"leaderElection":true,"timeWindowSeconds":5},"defaultNotifiers":["k8sevents"],"listenAddress":"0.0.0.0","listenPort":2803,"minio":{"accessKey":"","endpoint":"","secretKey":"","useSsl":false},"notifiers":{"elasticsearch":{"createIndexTemplate":true,"numberOfReplicas":1,"numberOfShards":1,"url":""},"loki":{"apiKey":"","customHeaders":[],"hostPort":"","tenant":"","user":""},"slack":{"footer":"https://github.com/falco-talon/falco-talon","format":"long","icon":"https://upload.wikimedia.org/wikipedia/commons/2/26/Circaetus_gallicus_claw.jpg","username":"Falco Talon","webhookUrl":""},"smtp":{"format":"html","from":"","hostPort":"","password":"","tls":false,"to":"","user":""},"webhook":{"url":""}},"otel":{"collectorEndpoint":"","collectorPort":4317,"collectorUseInsecureGrpc":false,"metricsEnabled":false,"tracesEnabled":false},"printAllEvents":false,"rulesFiles":["rules.yaml","rules_override.yaml"],"watchRules":true}` | config of Falco Talon (See https://docs.falco-talon.org/docs/configuration/) | +| config.aws | object | `{"accesKey":"","externalId":"","region":"","roleArn":"","secretKey":""}` | aws | +| config.aws.accesKey | string | `""` | access key (if not specified, default access_key from provider credential chain will be used) | +| config.aws.externalId | string | `""` | external id | +| config.aws.region | string | `""` | region (if not specified, default region from provider credential chain will be used) | +| config.aws.roleArn | string | `""` | role arn | +| config.aws.secretKey | string | `""` | secret key (if not specified, default secret_key from provider credential chain will be used) | +| config.deduplication | object | `{"leaderElection":true,"timeWindowSeconds":5}` | deduplication of the Falco events | +| config.deduplication.leaderElection | bool | `true` | enable the leader election for cluster mode | +| config.deduplication.timeWindowSeconds | int | `5` | duration in seconds for the deduplication time window | +| config.defaultNotifiers | list | `["k8sevents"]` | default notifiers for all rules | +| config.listenAddress | string | `"0.0.0.0"` | listen address | +| config.listenPort | int | `2803` | listen port | +| config.minio | object | `{"accessKey":"","endpoint":"","secretKey":"","useSsl":false}` | minio | +| config.minio.accessKey | string | `""` | access key | +| config.minio.endpoint | string | `""` | endpoint | +| config.minio.secretKey | string | `""` | secret key | +| config.minio.useSsl | bool | `false` | use ssl | +| config.notifiers | object | `{"elasticsearch":{"createIndexTemplate":true,"numberOfReplicas":1,"numberOfShards":1,"url":""},"loki":{"apiKey":"","customHeaders":[],"hostPort":"","tenant":"","user":""},"slack":{"footer":"https://github.com/falco-talon/falco-talon","format":"long","icon":"https://upload.wikimedia.org/wikipedia/commons/2/26/Circaetus_gallicus_claw.jpg","username":"Falco Talon","webhookUrl":""},"smtp":{"format":"html","from":"","hostPort":"","password":"","tls":false,"to":"","user":""},"webhook":{"url":""}}` | notifiers (See https://docs.falco-talon.org/docs/notifiers/list/ for the settings) | +| config.notifiers.elasticsearch | object | `{"createIndexTemplate":true,"numberOfReplicas":1,"numberOfShards":1,"url":""}` | elasticsearch | +| config.notifiers.elasticsearch.createIndexTemplate | bool | `true` | create the index template | +| config.notifiers.elasticsearch.numberOfReplicas | int | `1` | number of replicas | +| config.notifiers.elasticsearch.numberOfShards | int | `1` | number of shards | +| config.notifiers.elasticsearch.url | string | `""` | url | +| config.notifiers.loki | object | `{"apiKey":"","customHeaders":[],"hostPort":"","tenant":"","user":""}` | loki | +| config.notifiers.loki.apiKey | string | `""` | api key | +| config.notifiers.loki.customHeaders | list | `[]` | custom headers | +| config.notifiers.loki.hostPort | string | `""` | host:port | +| config.notifiers.loki.tenant | string | `""` | tenant | +| config.notifiers.loki.user | string | `""` | user | +| config.notifiers.slack | object | `{"footer":"https://github.com/falco-talon/falco-talon","format":"long","icon":"https://upload.wikimedia.org/wikipedia/commons/2/26/Circaetus_gallicus_claw.jpg","username":"Falco Talon","webhookUrl":""}` | slack | +| config.notifiers.slack.footer | string | `"https://github.com/falco-talon/falco-talon"` | footer | +| config.notifiers.slack.format | string | `"long"` | format | +| config.notifiers.slack.icon | string | `"https://upload.wikimedia.org/wikipedia/commons/2/26/Circaetus_gallicus_claw.jpg"` | icon | +| config.notifiers.slack.username | string | `"Falco Talon"` | username | +| config.notifiers.slack.webhookUrl | string | `""` | webhook url | +| config.notifiers.smtp | object | `{"format":"html","from":"","hostPort":"","password":"","tls":false,"to":"","user":""}` | smtp | +| config.notifiers.smtp.format | string | `"html"` | format | +| config.notifiers.smtp.from | string | `""` | from | +| config.notifiers.smtp.hostPort | string | `""` | host:port | +| config.notifiers.smtp.password | string | `""` | password | +| config.notifiers.smtp.tls | bool | `false` | enable tls | +| config.notifiers.smtp.to | string | `""` | to | +| config.notifiers.smtp.user | string | `""` | user | +| config.notifiers.webhook | object | `{"url":""}` | webhook | +| config.notifiers.webhook.url | string | `""` | url | +| config.otel | object | `{"collectorEndpoint":"","collectorPort":4317,"collectorUseInsecureGrpc":false,"metricsEnabled":false,"tracesEnabled":false}` | open telemetry parameters | +| config.otel.collectorEndpoint | string | `""` | collector endpoint | +| config.otel.collectorPort | int | `4317` | collector port | +| config.otel.collectorUseInsecureGrpc | bool | `false` | use insecure grpc | +| config.otel.metricsEnabled | bool | `false` | enable otel metrics | +| config.otel.tracesEnabled | bool | `false` | enable otel traces | +| config.printAllEvents | bool | `false` | print in stdout all received events, not only those which match a rule | +| config.rulesFiles | list | `["rules.yaml","rules_override.yaml"]` | list of rules to load | +| config.watchRules | bool | `true` | auto reload the rules when the files change | +| extraEnv | list | `[{"name":"LOG_LEVEL","value":"warning"}]` | extra env | +| image | object | `{"pullPolicy":"Always","registry":"falco.docker.scarf.sh","repository":"issif/falco-talon","tag":""}` | image parameters | +| image.pullPolicy | string | `"Always"` | The image pull policy | +| image.registry | string | `"falco.docker.scarf.sh"` | The image registry to pull from | +| image.repository | string | `"issif/falco-talon"` | The image repository to pull from | +| image.tag | string | `""` | Override the image tag to pull | +| imagePullSecrets | list | `[]` | one or more secrets to be used when pulling images | +| ingress | object | `{"annotations":{},"enabled":false,"hosts":[{"host":"falco-talon.local","paths":[{"path":"/"}]}],"tls":[]}` | ingress parameters | +| ingress.annotations | object | `{}` | annotations of the ingress | +| ingress.enabled | bool | `false` | enable the ingress | +| ingress.hosts | list | `[{"host":"falco-talon.local","paths":[{"path":"/"}]}]` | hosts | +| ingress.tls | list | `[]` | tls | +| nameOverride | string | `""` | override name | +| nodeSelector | object | `{}` | node selector | +| podAnnotations | object | `{}` | pod annotations | +| podSecurityContext | object | `{"fsGroup":1234,"runAsUser":1234}` | pod security context | +| podSecurityContext.fsGroup | int | `1234` | group | +| podSecurityContext.runAsUser | int | `1234` | user id | +| podSecurityPolicy | object | `{"create":false}` | pod security policy | +| podSecurityPolicy.create | bool | `false` | enable the creation of the PSP | +| priorityClassName | string | `""` | priority class name | +| rbac | object | `{"caliconetworkpolicies":["get","update","patch","create"],"ciliumnetworkpolicies":["get","update","patch","create"],"clusterroles":["get","delete"],"configmaps":["get","delete"],"daemonsets":["get","delete"],"deployments":["get","delete"],"events":["get","update","patch","create"],"leases":["get","update","patch","watch","create"],"namespaces":["get","delete"],"networkpolicies":["get","update","patch","create"],"nodes":["get","update","patch","watch","create"],"pods":["get","update","patch","delete","list"],"podsEphemeralcontainers":["patch","create"],"podsEviction":["get","create"],"podsExec":["get","create"],"podsLog":["get"],"replicasets":["get","delete"],"roles":["get","delete"],"secrets":["get","delete"],"statefulsets":["get","delete"]}` | rbac | +| replicaCount | int | `2` | number of running pods | +| resources | object | `{}` | resources | +| service | object | `{"annotations":{},"port":2803,"type":"ClusterIP"}` | service parameters | +| service.annotations | object | `{}` | annotations of the service | +| service.port | int | `2803` | port of the service | +| service.type | string | `"ClusterIP"` | type of service | +| serviceMonitor | object | `{"additionalLabels":{},"enabled":false,"interval":"30s","path":"/metrics","relabelings":[],"scheme":"http","scrapeTimeout":"10s","targetLabels":[],"tlsConfig":{}}` | serviceMonitor holds the configuration for the ServiceMonitor CRD. | +| serviceMonitor.additionalLabels | object | `{}` | additionalLabels specifies labels to be added on the Service Monitor. | +| serviceMonitor.enabled | bool | `false` | enable the deployment of a Service Monitor for the Prometheus Operator. | +| serviceMonitor.interval | string | `"30s"` | interval specifies the time interval at which Prometheus should scrape metrics from the service. | +| serviceMonitor.path | string | `"/metrics"` | path at which the metrics are expose | +| serviceMonitor.relabelings | list | `[]` | relabelings configures the relabeling rules to apply the target’s metadata labels. | +| serviceMonitor.scheme | string | `"http"` | scheme specifies network protocol used by the metrics endpoint. In this case HTTP. | +| serviceMonitor.scrapeTimeout | string | `"10s"` | scrapeTimeout determines the maximum time Prometheus should wait for a target to respond to a scrape request. If the target does not respond within the specified timeout, Prometheus considers the scrape as failed for that target. | +| serviceMonitor.targetLabels | list | `[]` | targetLabels defines the labels which are transferred from the associated Kubernetes service object onto the ingested metrics. | +| serviceMonitor.tlsConfig | object | `{}` | tlsConfig specifies TLS (Transport Layer Security) configuration for secure communication when scraping metrics from a service. It allows you to define the details of the TLS connection, such as CA certificate, client certificate, and client key. Currently, the k8s-metacollector does not support TLS configuration for the metrics endpoint. | +| tolerations | list | `[]` | tolerations | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/deployment/helm/templates/_helpers.tpl b/deployment/helm/templates/_helpers.tpl index 83d61bce..70e9bb80 100644 --- a/deployment/helm/templates/_helpers.tpl +++ b/deployment/helm/templates/_helpers.tpl @@ -34,8 +34,10 @@ helm.sh/chart: {{ include "falco-talon.chart" . }} app.kubernetes.io/part-of: {{ include "falco-talon.name" . }} app.kubernetes.io/managed-by: {{ .Release.Name }} {{ include "falco-talon.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- if .Values.image.tag }} +app.kubernetes.io/version: {{ .Values.image.tag }} +{{- else }} +app.kubernetes.io/version: {{ .Chart.AppVersion }} {{- end }} {{- end }} diff --git a/deployment/helm/templates/deployment.yaml b/deployment/helm/templates/deployment.yaml index dc203a65..5cd73864 100644 --- a/deployment/helm/templates/deployment.yaml +++ b/deployment/helm/templates/deployment.yaml @@ -32,7 +32,7 @@ spec: restartPolicy: Always containers: - name: {{ .Chart.Name }} - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} args: ["server", "-c", "/etc/falco-talon/config.yaml", "-r", "/etc/falco-talon/rules.yaml"] ports: diff --git a/deployment/helm/templates/rbac.yaml b/deployment/helm/templates/rbac.yaml index dce58f6d..50080a12 100644 --- a/deployment/helm/templates/rbac.yaml +++ b/deployment/helm/templates/rbac.yaml @@ -58,6 +58,7 @@ rules: verbs: {{ toYaml .Values.rbac.podsLog | indent 6 }} {{- end }} + {{- if .Values.rbac.podsExec }} - apiGroups: - "" resources: diff --git a/deployment/helm/values.yaml b/deployment/helm/values.yaml index 96593e27..1cbee65b 100644 --- a/deployment/helm/values.yaml +++ b/deployment/helm/values.yaml @@ -11,8 +11,8 @@ image: registry: falco.docker.scarf.sh # -- The image repository to pull from repository: issif/falco-talon - # -- The image tag to pull - tag: latest + # -- Override the image tag to pull + tag: "" # -- The image pull policy pullPolicy: Always