This plugin extends Falco to support Kubernetes Audit Events from OVHcloud MKS clusters as a new data source. For more details about what Audit logs are, see the README of k8saudit plugin.
This plugin supports consuming Kubernetes Audit Events stored in OVHcloud Log Data Platform (LDP) for the MKS Clusters, see OVHcloud official documentation for details.
The k8saudit-ovh
uses the field extraction methods of the k8saudit
plugin as the format for the Audit Logs is same.
The event source for Kubernetes Audit Events from OVHcloud is k8s_audit
, it allows to use same rules than k8saudit
plugin.
Here is the current set of supported fields (from k8saudit
plugin's extractor):
NAME | TYPE | ARG | DESCRIPTION |
---|---|---|---|
ka.auditid |
string |
None | The unique id of the audit event |
ka.stage |
string |
None | Stage of the request (e.g. RequestReceived, ResponseComplete, etc.) |
ka.auth.decision |
string |
None | The authorization decision |
ka.auth.reason |
string |
None | The authorization reason |
ka.auth.openshift.decision |
string |
None | The authentication decision of the openshfit apiserver extention. Only available on openshift clusters |
ka.auth.openshift.username |
string |
None | The user name performing the openshift authentication operation. Only available on openshift clusters |
ka.user.name |
string |
None | The user name performing the request |
ka.user.groups |
string (list) |
None | The groups to which the user belongs |
ka.impuser.name |
string |
None | The impersonated user name |
ka.verb |
string |
None | The action being performed |
ka.uri |
string |
None | The request URI as sent from client to server |
ka.uri.param |
string |
Key, Required | The value of a given query parameter in the uri (e.g. when uri=/foo?key=val, ka.uri.param[key] is val). |
ka.target.name |
string |
None | The target object name |
ka.target.namespace |
string |
None | The target object namespace |
ka.target.resource |
string |
None | The target object resource |
ka.target.subresource |
string |
None | The target object subresource |
ka.target.pod.name |
string |
None | The target pod name |
ka.req.binding.subjects |
string (list) |
None | When the request object refers to a cluster role binding, the subject (e.g. account/users) being linked by the binding |
ka.req.binding.role |
string |
None | When the request object refers to a cluster role binding, the role being linked by the binding |
ka.req.binding.subject.has_name |
string |
Key, Required | Deprecated, always returns "N/A". Only provided for backwards compatibility |
ka.req.configmap.name |
string |
None | If the request object refers to a configmap, the configmap name |
ka.req.configmap.obj |
string |
None | If the request object refers to a configmap, the entire configmap object |
ka.req.pod.containers.image |
string (list) |
Index | When the request object refers to a pod, the container's images. |
ka.req.container.image |
string |
None | Deprecated by ka.req.pod.containers.image. Returns the image of the first container only |
ka.req.pod.containers.image.repository |
string (list) |
Index | The same as req.container.image, but only the repository part (e.g. falcosecurity/falco). |
ka.req.container.image.repository |
string |
None | Deprecated by ka.req.pod.containers.image.repository. Returns the repository of the first container only |
ka.req.pod.host_ipc |
string |
None | When the request object refers to a pod, the value of the hostIPC flag. |
ka.req.pod.host_network |
string |
None | When the request object refers to a pod, the value of the hostNetwork flag. |
ka.req.container.host_network |
string |
None | Deprecated alias for ka.req.pod.host_network |
ka.req.pod.host_pid |
string |
None | When the request object refers to a pod, the value of the hostPID flag. |
ka.req.pod.containers.host_port |
string (list) |
Index | When the request object refers to a pod, all container's hostPort values. |
ka.req.pod.containers.privileged |
string (list) |
Index | When the request object refers to a pod, the value of the privileged flag for all containers. |
ka.req.container.privileged |
string |
None | Deprecated by ka.req.pod.containers.privileged. Returns true if any container has privileged=true |
ka.req.pod.containers.allow_privilege_escalation |
string (list) |
Index | When the request object refers to a pod, the value of the allowPrivilegeEscalation flag for all containers |
ka.req.pod.containers.read_only_fs |
string (list) |
Index | When the request object refers to a pod, the value of the readOnlyRootFilesystem flag for all containers |
ka.req.pod.run_as_user |
string |
None | When the request object refers to a pod, the runAsUser uid specified in the security context for the pod. See ....containers.run_as_user for the runAsUser for individual containers |
ka.req.pod.containers.run_as_user |
string (list) |
Index | When the request object refers to a pod, the runAsUser uid for all containers |
ka.req.pod.containers.eff_run_as_user |
string (list) |
Index | When the request object refers to a pod, the initial uid that will be used for all containers. This combines information from both the pod and container security contexts and uses 0 if no uid is specified |
ka.req.pod.run_as_group |
string |
None | When the request object refers to a pod, the runAsGroup gid specified in the security context for the pod. See ....containers.run_as_group for the runAsGroup for individual containers |
ka.req.pod.containers.run_as_group |
string (list) |
Index | When the request object refers to a pod, the runAsGroup gid for all containers |
ka.req.pod.containers.eff_run_as_group |
string (list) |
Index | When the request object refers to a pod, the initial gid that will be used for all containers. This combines information from both the pod and container security contexts and uses 0 if no gid is specified |
ka.req.pod.containers.proc_mount |
string (list) |
Index | When the request object refers to a pod, the procMount types for all containers |
ka.req.role.rules |
string (list) |
None | When the request object refers to a role/cluster role, the rules associated with the role |
ka.req.role.rules.apiGroups |
string (list) |
Index | When the request object refers to a role/cluster role, the api groups associated with the role's rules |
ka.req.role.rules.nonResourceURLs |
string (list) |
Index | When the request object refers to a role/cluster role, the non resource urls associated with the role's rules |
ka.req.role.rules.verbs |
string (list) |
Index | When the request object refers to a role/cluster role, the verbs associated with the role's rules |
ka.req.role.rules.resources |
string (list) |
Index | When the request object refers to a role/cluster role, the resources associated with the role's rules |
ka.req.pod.fs_group |
string |
None | When the request object refers to a pod, the fsGroup gid specified by the security context. |
ka.req.pod.supplemental_groups |
string (list) |
None | When the request object refers to a pod, the supplementalGroup gids specified by the security context. |
ka.req.pod.containers.add_capabilities |
string (list) |
Index | When the request object refers to a pod, all capabilities to add when running the container. |
ka.req.service.type |
string |
None | When the request object refers to a service, the service type |
ka.req.service.ports |
string (list) |
Index | When the request object refers to a service, the service's ports |
ka.req.pod.volumes.hostpath |
string (list) |
Index | When the request object refers to a pod, all hostPath paths specified for all volumes |
ka.req.volume.hostpath |
string |
Key, Required | Deprecated by ka.req.pod.volumes.hostpath. Return true if the provided (host) path prefix is used by any volume |
ka.req.pod.volumes.flexvolume_driver |
string (list) |
Index | When the request object refers to a pod, all flexvolume drivers specified for all volumes |
ka.req.pod.volumes.volume_type |
string (list) |
Index | When the request object refers to a pod, all volume types for all volumes |
ka.resp.name |
string |
None | The response object name |
ka.response.code |
string |
None | The response code |
ka.response.reason |
string |
None | The response reason (usually present only for failures) |
ka.useragent |
string |
None | The useragent of the client who made the request to the apiserver |
ka.sourceips |
string (list) |
Index | The IP addresses of the client who made the request to the apiserver |
ka.cluster.name |
string |
None | The name of the k8s cluster |
# Add scraly index
sudo falcoctl index add k8saudit-ovh https://raw.githubusercontent.com/scraly/k8saudit-ovh/refs/heads/main/index.yaml
# Install k8saudit-ovh Falco plugin
sudo falcoctl artifact install k8saudit-ovh
Here's an example of configuration of falco.yaml
:
plugins:
- name: k8saudit-ovh
library_path: /usr/share/falco/plugins/libk8saudit-ovh.so
open_params: "<OVH LDP WEBSOCKET URL>" # gra<x>.logs.ovh.com/tail/?tk=<ID>
- name: json
library_path: libjson.so
init_config: ""
load_plugins: [k8saudit-ovh, json]
Open Parameters
A string which contains the LDP WebSocket URL of your OVHcloud MKS Cluster (required).
Follow this guide to retrieve the OVHcloud LDP URL.
The k8saudit-ovh
plugin ships with no default rule for test purpose, you can use the same rules than those for k8saudit
plugin. See here.
To test if it works anyway, you can still use this one for example:
- required_engine_version: 15
- required_plugin_versions:
- name: k8saudit-ovh
version: 0.1.0
- rule: TEST
desc: >
Test rule
condition: >
ka.verb in (get,create,delete,update)
output: verb=%ka.verb name=%ka.target.name resp=%ka.response.code namespace=%ka.target.namespace
priority: NOTICE
source: k8s_audit
tags: [k8s]
This plugin requires Falco with version >= 0.35.0.
falco -c falco.yaml -r rules/k8s_audit_rules.yaml
12:29:51.895849000: Notice verb=get name=<NA> resp=200 namespace=<NA>
12:29:51.900789000: Notice verb=get name=<NA> resp=200 namespace=<NA>
^CEvents detected: 2
Rule counts by severity:
NOTICE: 2
Triggered rules by rule name:
TEST: 2
You can use the official Falco Helm chart to deploy it, with the following values.yaml
:
tty: true
kubernetes: false
# Just a Deployment with 1 replica (instead of a Daemonset) to have only one Pod that pulls the MKS Audit Logs from a OVHcloud LDP
controller:
kind: deployment
deployment:
replicas: 1
falco:
rules_files:
- /etc/falco/k8s_audit_rules.yaml
- /etc/falco/rules.d
plugins:
- name: k8saudit-ovh
library_path: libk8saudit-ovh.so
open_params: "gra<x>.logs.ovh.com/tail/?tk=<ID>" # Replace with your LDP Websocket URL
- name: json
library_path: libjson.so
init_config: ""
# Plugins that Falco will load. Note: the same plugins are installed by the falcoctl-artifact-install init container.
load_plugins: [k8saudit-ovh, json]
driver:
enabled: false
collectors:
enabled: false
# use falcoctl to install automatically the plugin and the rules
falcoctl:
artifact:
install:
enabled: true
follow:
enabled: true
config:
indexes:
- name: falcosecurity
url: https://falcosecurity.github.io/falcoctl/index.yaml
- name: k8saudit-ovh
url: https://raw.githubusercontent.com/scraly/k8saudit-ovh/refs/heads/main/index.yaml
artifact:
allowedTypes:
- plugin
- rulesfile
install:
resolveDeps: false
refs: [k8saudit-rules:0, k8saudit-ovh:0.1, json:0]
follow:
refs: [k8saudit-rules:0]
Note: You can also install Falcosidekick and enable the webUI to watch your events in an interface.