diff --git a/docs/content/en/docs/concepts/tracing-policy/example.md b/docs/content/en/docs/concepts/tracing-policy/example.md index e97892fa328..07c6e1a2eef 100644 --- a/docs/content/en/docs/concepts/tracing-policy/example.md +++ b/docs/content/en/docs/concepts/tracing-policy/example.md @@ -115,8 +115,8 @@ echo eBPF! > /tmp/tetragon Starting Tetragon with the above `TracingPolicy`, for example putting the policy in the `example.yaml` file, compiling the project locally and starting Tetragon with (you can do similar things with container image releases, see the -docker run command in the [Try Tetragon on Linux guide]({{< ref -"/docs/getting-started/try-tetragon-linux#observability-with-tracingpolicy" >}}): +docker run command in the [Try Tetragon on Linux guide] + ```shell-session sudo ./tetragon --bpf-lib bpf/objs --tracing-policy example.yaml ``` diff --git a/docs/content/en/docs/getting-started/install-tetragon/_index.md b/docs/content/en/docs/getting-started/install-tetragon/_index.md new file mode 100644 index 00000000000..f79f2785f7c --- /dev/null +++ b/docs/content/en/docs/getting-started/install-tetragon/_index.md @@ -0,0 +1,9 @@ +--- +title: "Quick Install Tetragon" +linkTitle: "Quick Install" +isShownInList: false +weight: 1 +description: > + Quick install quide for Tetragon. +--- + diff --git a/docs/content/en/docs/getting-started/install-tetragon/install-docker.md b/docs/content/en/docs/getting-started/install-tetragon/install-docker.md new file mode 100644 index 00000000000..0354a192ed1 --- /dev/null +++ b/docs/content/en/docs/getting-started/install-tetragon/install-docker.md @@ -0,0 +1,32 @@ +--- +title: "Try Tetragon locally " +weight: 1 +description: "Discover and experiment with Tetragon on your local Linux host" +--- + +{{< note >}} +This guide has been tested on Ubuntu 22.04 and 22.10 with respectively kernel +`5.15.0` and `5.19.0` on amd64 and arm64 but +[any recent distribution](https://github.com/libbpf/libbpf#bpf-co-re-compile-once--run-everywhere) +shipping with a relatively recent kernel should work. See the FAQ for further details on +the [recommended kernel versions]({{< ref "/docs/faq#what-is-the-minimum-linux-kernel-version-to-run-tetragon" >}}). + +Note that you cannot run Tetragon using Docker Desktop on macOS because of a +limitation of the Docker Desktop Linux virtual machine. Learn more about this issue +and how to run Tetragon on a Mac computer in [this section of the FAQ page](/docs/faq/#can-i-run-tetragon-on-mac-computers). +{{< /note >}} + +## Start Tetragon + +The easiest way to start experimenting with Tetragon is to run it via Docker +using the released container images. + +```shell +docker run --name tetragon-container --rm --pull always \ + --pid=host --cgroupns=host --privileged \ + -v /sys/kernel/btf/vmlinux:/var/lib/tetragon/btf \ + quay.io/cilium/tetragon-ci:latest +``` + +This will start Tetragon in a privileged container. Priviliges are required +to load and attach BPF programs. See Installation section for more details. diff --git a/docs/content/en/docs/getting-started/install-tetragon/install-k8s.md b/docs/content/en/docs/getting-started/install-tetragon/install-k8s.md new file mode 100644 index 00000000000..44751ed8bd9 --- /dev/null +++ b/docs/content/en/docs/getting-started/install-tetragon/install-k8s.md @@ -0,0 +1,74 @@ +--- +title: "Try Tetragon on Kubernetes" +weight: 1 +description: "Discover and experiment with Tetragon in a kubernetes environment" +--- + +### Create a cluster + +If you don’t have a Kubernetes Cluster yet, you can use the instructions below to create a Kubernetes cluster locally or using a managed Kubernetes service: + +TBD tabplane this... + +#### Kind + +Run the following command to create the Kubernetes cluster: +``` +kind create cluster +``` + +#### GKE + +Run the following command to create a GKE cluster: + +```shell +export NAME="$(whoami)-$RANDOM" +gcloud container clusters create "${NAME}" \ + --zone us-west2-a \ + --num-nodes 1 +``` + +### Deploy Tetragon + +To install and deploy Tetragon, run the following commands: + +```shell +helm repo add cilium https://helm.cilium.io +helm repo update +helm install tetragon cilium/tetragon -n kube-system +kubectl rollout status -n kube-system ds/tetragon -w +``` + +By default, Tetragon will filter kube-system events to reduce noise in the +event logs. See concepts and advanced configuration to configure these +parameters. + +### Deploy demo application + +To explore Tetragon its helpful to have a sample workload. Here wu use the Cilium +HTTP application, but any workload would work equally well. + +To use our [demo +application](https://docs.cilium.io/en/v1.11/gettingstarted/http/#deploy-the-demo-application) + +```shell +kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.11/examples/minikube/http-sw-app.yaml +``` + +Before going forward, verify that all pods are up and running - it might take +several seconds for some pods until they satisfy all the dependencies: + +```shell +kubectl get pods +``` + +The output should be similar to: +``` +NAME READY STATUS RESTARTS AGE +deathstar-6c94dcc57b-7pr8c 1/1 Running 0 10s +deathstar-6c94dcc57b-px2vw 1/1 Running 0 10s +tiefighter 1/1 Running 0 10s +xwing 1/1 Running 0 10s +``` + + diff --git a/docs/content/en/docs/getting-started/kubernetes-quickstart-guide.md b/docs/content/en/docs/getting-started/kubernetes-quickstart-guide.md deleted file mode 100644 index 4614f3c60b0..00000000000 --- a/docs/content/en/docs/getting-started/kubernetes-quickstart-guide.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Kubernetes quickstart guide" -weight: 2 -icon: "overview" -description: "Deploy Tetragon on a Kubernetes cluster" ---- - -This quickstart guide uses a Kind cluster and a helm-based installation to -provide a simple way to get a hands on experience with Tetragon and -the generated events. These events include monitoring process execution, -network sockets, and file access to see what binaries are executing and making -network connections or writing to sensitive files. - -In this scenario, we are going to install a demo application, - -* observe all process execution happening inside a Kubernetes workload -* detect file access and writes -* observe network connections that a Kubernetes workload is making -* detect privileged processes inside a Kubernetes workload - -While, we use a Kubernetes Kind cluster in this guide, users can also apply -the same concepts in other Kubernetes platforms, bare-metal, or VM environments. - -### Requirements - -The base kernel should support [BTF](#btf-requirement) or the BTF file should -be placed where Tetragon can read it. - -For reference, the examples below use this [Vagrantfile](#btf-requirement) and we -created our [Kind](https://kind.sigs.k8s.io/docs/user/quick-start/) cluster using -the defaults options. - -### Create a cluster - -Create a Kubernetes cluster using Kind or GKE. - -#### Kind - -Run the following command to create the Kubernetes cluster: -``` -kind create cluster -``` - -#### GKE - -Run the following command to create a GKE cluster: - -```shell -export NAME="$(whoami)-$RANDOM" -gcloud container clusters create "${NAME}" \ - --zone us-west2-a \ - --num-nodes 1 -``` - -### Deploy Tetragon - -To install and deploy Tetragon, run the following commands: - -```shell -helm repo add cilium https://helm.cilium.io -helm repo update -helm install tetragon cilium/tetragon -n kube-system -kubectl rollout status -n kube-system ds/tetragon -w -``` - -By default, kube-system pods are filtered. For the examples below, we use the demo -deployment from [Cilium](https://docs.cilium.io/en/v1.11/gettingstarted/http/#gs-http) -to generate events. - -### Deploy the demo application - -Once Tetragon is installed, you can use our [demo -application](https://docs.cilium.io/en/v1.11/gettingstarted/http/#deploy-the-demo-application) -to explore the Security Observability Events: - -```shell -kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.11/examples/minikube/http-sw-app.yaml -``` - -Before going forward, verify that all pods are up and running - it might take -several seconds for some pods until they satisfy all the dependencies: - -```shell -kubectl get pods -``` - -The output should be similar to: -``` -NAME READY STATUS RESTARTS AGE -deathstar-6c94dcc57b-7pr8c 1/1 Running 0 10s -deathstar-6c94dcc57b-px2vw 1/1 Running 0 10s -tiefighter 1/1 Running 0 10s -xwing 1/1 Running 0 10s -``` - -### What's next - -- Learn how to checks this events in the next section [Explore security -observability events](/docs/getting-started/explore-security-observability-events). diff --git a/docs/content/en/docs/getting-started/tetragon-enforcement.md b/docs/content/en/docs/getting-started/tetragon-enforcement.md new file mode 100644 index 00000000000..00d9ab1747a --- /dev/null +++ b/docs/content/en/docs/getting-started/tetragon-enforcement.md @@ -0,0 +1,45 @@ +--- +title: "Policy Enforcement" +weight: 2 +description: "Policy Enforcement" +--- + +This adds a network and file policy enforcement on top of execution, file tracing +and networking policy already deployed in the quick start. In this use case we +use a namespace and pod labels to limit the scope of where the network, file +and some security policies will be applied. This highlights two important concepts +of Tetragon. First in kernel filter provides performance advantages, but also allows for +enforcing policies inline with the action. Second, by including kubernetes +filters, such as namespace and labels we can segment a policy to apply to +targeted pods. For implementation details see Enforcement section and for +modifying and creating additional policies see Tracing Policies. + +# Enforcement + +To apply the policy + +{{< tabpane >}} +{{< tab header="K8s" >}} +kubectl apply -f tbd.base-enforce.yaml +{{< /tab >}} +{{< tab header="Docker" >}} +{{< /tab >}} +{{< tab header="Systemd" >}} +{{< /tab >}} +{{< /tabpane >}} + +With the file applied we can attach tetra to observe events again, + +``` + kubectl exec -ti xwing -- bash -c 'curl https://ebpf.io/applications/#tetragon +``` + +And once again execute a curl command in the xwing, + +``` + kubectl exec -ti xwing -- bash -c 'curl https://ebpf.io/applications/#tetragon +``` + +The CLI will print the exec tracing and file access as before, but will additional show the network connection outside the K8s cluster. + +# diff --git a/docs/content/en/docs/getting-started/tetragon-execution.md b/docs/content/en/docs/getting-started/tetragon-execution.md new file mode 100644 index 00000000000..9e1b81bdf12 --- /dev/null +++ b/docs/content/en/docs/getting-started/tetragon-execution.md @@ -0,0 +1,140 @@ +--- +title: "Execution monitoring" +weight: 2 +description: "Execution Traces with Tetragon" +--- + +At the core of Tetragon is the tracking of all executions in a kubernetes cluster, +virtual machines, and baremetal systems. This creates the foundation that allows +Tetragon to attribute all system behavior back to a specific binary and its +associated metadata (container, pod, node, and cluster). + +## Observe Tetragon Execution Events + +Tetragon exposes the execution trace over JSON logs and GRPC stream. The user +can then observe all executions in the system. + +The following command can be used to observe exec events. + +{{< tabpane >}} +{{< tab header="K8s" >}} +kubectl exec -ti -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact +{{< /tab >}} +{{< tab header="Docker" >}} +docker exec tetragon-container tetra getevents -o compact +{{< /tab >}} +{{< tab header="Systemd" >}} +{{< /tab >}} +{{< /tabpane >}} + +This will print a compact form of the exec logs. For an example we do the following +with the demo application. + +``` + kubectl exec -ti xwing -- bash -c 'curl https://ebpf.io/applications/#tetragon +``` +The CLI will print a compact form of the event to the terminal + +``` +πŸš€ process default/xwing /bin/bash -c "curl https://ebpf.io/applications/#tetragon" +πŸš€ process default/xwing /usr/bin/curl https://ebpf.io/applications/#tetragon +πŸ’₯ exit default/xwing /usr/bin/curl https://ebpf.io/applications/#tetragon 60 + +``` + +The compact exec event contains the event type, the pod name, the binary and the args. The exit event will include the return code, in the case of curl `60` above. + +For the complete exec event in JSON format remove the compact option. + +{{< tabpane >}} +{{< tab header="K8s" >}} +kubectl exec -ti -n kube-system ds/tetragon -c tetragon -- tetra getevents +{{< /tab >}} +{{< tab header="Docker" >}} +docker exec tetragon-container tetra getevents +{{< /tab >}} +{{< tab header="Systemd" >}} +{{< /tab >}} +{{< /tabpane >}} + +This will include a lot more details related the binary and event. A full example of the above curl is hown here, + +``` +{ + "process_exec": { + "process": { + "exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4Njc0MzIxMzczOjUyNjk5", + "pid": 52699, + "uid": 0, + "cwd": "/", + "binary": "/usr/bin/curl", + "arguments": "https://ebpf.io/applications/#tetragon", + "flags": "execve rootcwd", + "start_time": "2023-10-06T22:03:57.700327580Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "xwing", + "container": { + "id": "containerd://551e161c47d8ff0eb665438a7bcd5b4e3ef5a297282b40a92b7c77d6bd168eb3", + "name": "spaceship", + "image": { + "id": "docker.io/tgraf/netperf@sha256:8e86f744bfea165fd4ce68caa05abc96500f40130b857773186401926af7e9e6", + "name": "docker.io/tgraf/netperf:latest" + }, + "start_time": "2023-10-06T21:52:41Z", + "pid": 49 + }, + "pod_labels": { + "app.kubernetes.io/name": "xwing", + "class": "xwing", + "org": "alliance" + }, + "workload": "xwing" + }, + "docker": "551e161c47d8ff0eb665438a7bcd5b4", + "parent_exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4NjcwODgzMjk5OjUyNjk5", + "tid": 52699 + }, + "parent": { + "exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4NjcwODgzMjk5OjUyNjk5", + "pid": 52699, + "uid": 0, + "cwd": "/", + "binary": "/bin/bash", + "arguments": "-c \"curl https://ebpf.io/applications/#tetragon\"", + "flags": "execve rootcwd clone", + "start_time": "2023-10-06T22:03:57.696889812Z", + "auid": 4294967295, + "pod": { + "namespace": "default", + "name": "xwing", + "container": { + "id": "containerd://551e161c47d8ff0eb665438a7bcd5b4e3ef5a297282b40a92b7c77d6bd168eb3", + "name": "spaceship", + "image": { + "id": "docker.io/tgraf/netperf@sha256:8e86f744bfea165fd4ce68caa05abc96500f40130b857773186401926af7e9e6", + "name": "docker.io/tgraf/netperf:latest" + }, + "start_time": "2023-10-06T21:52:41Z", + "pid": 49 + }, + "pod_labels": { + "app.kubernetes.io/name": "xwing", + "class": "xwing", + "org": "alliance" + }, + "workload": "xwing" + }, + "docker": "551e161c47d8ff0eb665438a7bcd5b4", + "parent_exec_id": "Z2tlLWpvaG4tNjMyLWRlZmF1bHQtcG9vbC03MDQxY2FjMC05czk1OjEzNTQ4NjQ1MjQ1ODM5OjUyNjg5", + "tid": 52699 + } + }, + "node_name": "gke-john-632-default-pool-7041cac0-9s95", + "time": "2023-10-06T22:03:57.700326678Z" +} + +``` + +## What's next diff --git a/docs/content/en/docs/getting-started/tetragon-file-events.md b/docs/content/en/docs/getting-started/tetragon-file-events.md new file mode 100644 index 00000000000..ae538d14154 --- /dev/null +++ b/docs/content/en/docs/getting-started/tetragon-file-events.md @@ -0,0 +1,63 @@ +--- +title: "File Access Monitoring" +weight: 2 +description: "File Access Traces with Tetragon" +--- + +Tracing Policies can be added to Tetragon through YAML configuration files +that extend Tetragon's base execution tracing capabilities. These policies +do filtering in kernel to ensure only interesting events are published +to userspace from the BPF programs running in kernel. This ensures overhead +remains low even on busy systems. + +# File Access Monitoring + +The following extends the example from Execution Tracing with a policy to +monitor sensitive files in Linux. The policy can be reviewed and extended +here []. Files monitored here serve as a good base set of files to monitor +for Kubernetes environments. + +To apply the policy + +{{< tabpane >}} +{{< tab header="K8s" >}} +kubectl apply -f http://github.com/cilium/tetragon/quickstart/file-monitoring.yaml +{{< /tab >}} +{{< tab header="Docker" >}} +{{< /tab >}} +{{< tab header="Systemd" >}} +{{< /tab >}} +{{< /tabpane >}} + +With the file applied we can attach tetra to observe events again, + +``` + kubectl exec -ti -n kube-system ds/tetragon -c tetragon -- tetra getevents -o compact --namespaces default +``` +Then reading a sensitive file, + +``` + kubectl exec -ti xwing -- bash -c 'cat /etc/shadow' +``` + +This will generate a read event, + +``` +πŸš€ process default/xwing /bin/bash -c "cat /etc/shadow" +πŸš€ process default/xwing /bin/cat /etc/shadow +πŸ“š read default/xwing /bin/cat /etc/shadow +πŸ’₯ exit default/xwing /bin/cat /etc/shadow 0 +``` + +Attempts to write in sensitive directories will similar create an event. For example attempting to write in '/etc'. + +``` +πŸš€ process default/xwing /bin/bash -c "echo foo >> /etc/bar +" +πŸ“ write default/xwing /bin/bash /etc/bar +πŸ“ write default/xwing /bin/bash /etc/bar +πŸ’₯ exit default/xwing /bin/bash -c "echo foo >> /etc/bar + +``` + +# What's next diff --git a/docs/content/en/docs/getting-started/tetragon-network.md b/docs/content/en/docs/getting-started/tetragon-network.md new file mode 100644 index 00000000000..7c83f36f1c6 --- /dev/null +++ b/docs/content/en/docs/getting-started/tetragon-network.md @@ -0,0 +1,39 @@ +--- +title: "Network Monitoring" +weight: 2 +description: "Network Access Traces with Tetragon" +--- + +This adds a network policy on top of execution and file tracing +already deployed in the quick start. In this case we monitor +all network traffic outside the Kubernetes CIDR. + +# Network Access Monitoring + +To apply the policy + +{{< tabpane >}} +{{< tab header="K8s" >}} +kubectl apply -f tbd.network.yaml +{{< /tab >}} +{{< tab header="Docker" >}} +{{< /tab >}} +{{< tab header="Systemd" >}} +{{< /tab >}} +{{< /tabpane >}} + +With the file applied we can attach tetra to observe events again, + +``` + kubectl exec -ti xwing -- bash -c 'curl https://ebpf.io/applications/#tetragon +``` + +And once again execute a curl command in the xwing, + +``` + kubectl exec -ti xwing -- bash -c 'curl https://ebpf.io/applications/#tetragon +``` + +The CLI will print the exec tracing and file access as before, but will additional show the network connection outside the K8s cluster. + +# diff --git a/docs/content/en/docs/getting-started/try-tetragon-linux.md b/docs/content/en/docs/getting-started/try-tetragon-linux.md deleted file mode 100644 index 39bbe741bcf..00000000000 --- a/docs/content/en/docs/getting-started/try-tetragon-linux.md +++ /dev/null @@ -1,391 +0,0 @@ ---- -title: "Try Tetragon on Linux" -weight: 1 -description: "Discover and experiment with Tetragon on your local Linux host" ---- - -{{< note >}} -This guide has been tested on Ubuntu 22.04 and 22.10 with respectively kernel -`5.15.0` and `5.19.0` on amd64 and arm64 but -[any recent distribution](https://github.com/libbpf/libbpf#bpf-co-re-compile-once--run-everywhere) -shipping with a relatively recent kernel should work. See the FAQ for further details on -the [recommended kernel versions]({{< ref "/docs/faq#what-is-the-minimum-linux-kernel-version-to-run-tetragon" >}}). - -Note that you cannot run Tetragon using Docker Desktop on macOS because of a -limitation of the Docker Desktop Linux virtual machine. Learn more about this issue -and how to run Tetragon on a Mac computer in [this section of the FAQ page](/docs/faq/#can-i-run-tetragon-on-mac-computers). -{{< /note >}} - -## Start Tetragon - -The easiest way to start experimenting with Tetragon is to run it via Docker -using the released container images. If you prefer running directly the -binaries without Docker, please refer to the -[development setup](/docs/contribution-guide/development-setup) to see how to -build the binaries. - -```shell -docker run --name tetragon-container --rm --pull always \ - --pid=host --cgroupns=host --privileged \ - -v /sys/kernel/btf/vmlinux:/var/lib/tetragon/btf \ - quay.io/cilium/tetragon-ci:latest -``` - -Let's break down the previous command: -- `--name tetragon-container` names our container so that we can refer to it - later via a simple name. -- `--rm` will make Docker delete the container once it exists. -- `--pull always` will force Docker to download the latest existing image - corresponding to the `latest` mutable tag. -- `--pid=host` is needed to read the procfs for gathering context on processes - started before Tetragon. -- `--cgroupns=host` is needed to detect container feature. -- `--privileged` is needed for Tetragon to load its BPF programs. -- `-v /sys/kernel/btf/vmlinux:/var/lib/tetragon/btf` mounts the BTF file inside - the Tetragon container filesystem. Tetragon needs a BTF file corresponding to - your kernel version to load its BPF programs. -- `quay.io/cilium/tetragon-ci:latest` is the latest version of Tetragon built - from the main branch. - -## Observe Tetragon base events - -With this default configuration, Tetragon already loaded its base sensors to -perform [process lifecycle observability]({{< ref "docs/use-cases/process-lifecycle" >}}). - -To quickly see the events, you can use the `tetra` CLI already shipped in the -Tetragon container that was just started, it will connect to the Tetragon gRPC -server listening on `localhost:54321`. In another terminal, type the following -command: - -```shell -docker exec tetragon-container tetra getevents -o compact -``` - -In a different terminal, you can start a shell like `sh` and start executing -programs. Here, the commands executed in the shell where `ls`, `uname -a`, -`whoami`, and `exit`, the output should be similar to this: - -``` -πŸš€ process /usr/bin/sh -πŸš€ process /usr/bin/ls -πŸ’₯ exit /usr/bin/ls 0 -πŸš€ process /usr/bin/uname -a -πŸ’₯ exit /usr/bin/uname -a 0 -πŸš€ process /usr/bin/whoami -πŸ’₯ exit /usr/bin/whoami 0 -πŸ’₯ exit /usr/bin/sh 0 -``` - -You can see the start of `sh` first, then the execution of the multiple -programs, `ls`, `uname` and `whoami`, and finally the exit of `sh`. - -{{< note >}} -Since Tetragon monitors all processes on the host, you may observe events -unrelated to what was typed in the shell session. Indeed, Tetragon is -monitoring every process start and exit in your environment. -{{< /note >}} - -## Write a TracingPolicy to extend Tetragon events - -Tetragon by default observes only process lifecycles. More advanced use-cases, -require configuring Tetragon via TracingPolicies. A TracingPolicy is a -user-configurable Kubernetes custom resource (CR) that allows users to access -additional functionality, such as tracing arbitrary events in the kernel and, -optionally, define actions to take on a match. These actions can be, for -example, used to implement enforcement. - -{{< note >}} -For more details about TracingPolicies and how to write them, refer to the -[TracingPolicy documentation]({{< ref "/docs/concepts/tracing-policy" >}}). -{{< /note >}} - -### Observability with TracingPolicy - -Let's start with a simple policy: - -```yaml -apiVersion: cilium.io/v1alpha1 -kind: TracingPolicy -metadata: - name: "cat-open" -spec: - kprobes: - - call: "sys_openat" - syscall: true - args: - - index: 0 - type: "int" - - index: 1 - type: "string" - - index: 2 - type: "int" - selectors: - - matchBinaries: - - operator: In - values: - - "/usr/bin/cat" -``` - -Copy this policy in a file named `tracing_policy.yaml` in your current working -directory and restart Tetragon with the following command: - -```shell -docker run --name tetragon-container --rm --pull always \ - --pid=host --cgroupns=host --privileged \ - -v $PWD/tracing_policy.yaml:/tracing_policy.yaml \ - -v /sys/kernel/btf/vmlinux:/var/lib/tetragon/btf \ - quay.io/cilium/tetragon-ci:latest \ - --tracing-policy /tracing_policy.yaml -``` - -We added two flags to our commands: -- `-v $(pwd)/tracing_policy.yaml:/tracing_policy.yaml` mounts the created local - file into the container filesystem. -- `--tracing-policy /tracing_policy.yaml` indicates Tetragon to load the policy in - the provided file. - -Now again, in another terminal, open the `tetra` CLI to see the new events -generated by Tetragon, monitoring the `openat` system call. - -```shell -docker exec tetragon-container tetra getevents -o compact -``` - -And in the third terminal, just read the `tracing_policy.yaml` file we created -using cat with: -```shell -cat tracing_policy.yaml -``` - -The output from the `tetra` CLI should be similar to: - -``` -πŸš€ process /usr/bin/cat tracingpolicy.yaml -πŸ“¬οΈ openat /usr/bin/cat /etc/ld.so.cache -πŸ“¬οΈ openat /usr/bin/cat /lib/aarch64-linux-gnu/libc.so.6 -πŸ“¬οΈ openat /usr/bin/cat tracingpolicy.yaml -πŸ’₯ exit /usr/bin/cat tracingpolicy.yaml 0 -``` - -{{< note >}} -The syscall we choose is `openat` and not `open` because the glibc and most of -the implementations of the standard C library use the `openat` syscall for -their `open` wrapper. So `cat` on Linux is using `openat`. -{{< /note >}} - -We can see that during the execution of `cat`, because it is dynamically -linked, it used the `openat` syscall to open: -- the cache file for shared libraries `ld.so.cache`; -- the `libc.so.6` library; -- the file we actually wanted to read `tracing_policy.yaml`. - -This is the kind of information we could obtain by executing the program with -`strace` for example, but here Tetragon obtains this information directly from -the kernel, transparently for the executed program. - -Please note that `tetra` CLI, with the `-o compact` output format, -automatically tried to decode the second argument as a string and printed it -because it has the hardcoded knowledge that the `openat` syscall has an -interesting string as second argument. - -You can use `tetra getevents` to retrieve the whole JSON events and see the -complete fields and values retrieved from the event. In our situation the -output should be similar to the following. - -```json -{ - "process_kprobe": { - "process": { - "exec_id": "OjEwMTgzOTUyNjg1NjcwNDoyNjIzNw==", - "pid": 26237, - "uid": 1000, - "cwd": "/home/ubuntu", - "binary": "/usr/bin/cat", - "arguments": "tracing_policy.yaml", - "flags": "execve clone", - "start_time": "2023-04-06T18:30:03.405730761Z", - "auid": 1000, - "parent_exec_id": "OjEwMTczMDEyNTQ3MjUxMDoyNjIwOA==", - "refcnt": 1 - }, - "parent": { - "exec_id": "OjEwMTczMDEyNTQ3MjUxMDoyNjIwOA==", - "pid": 26208, - "uid": 1000, - "cwd": "/home/ubuntu", - "binary": "/bin/bash", - "flags": "execve clone", - "start_time": "2023-04-06T18:28:14.004347210Z", - "auid": 1000, - "parent_exec_id": "OjEwMTczMDEwMjc2NTg0NjoyNjIwNw==", - "refcnt": 2 - }, - "function_name": "__x64_sys_openat", - "args": [ - { - "int_arg": -100 - }, - { - "string_arg": "tracing_policy.yaml" - }, - { - "int_arg": 0 - } - ], - "action": "KPROBE_ACTION_POST" - }, - "time": "2023-04-06T18:30:03.406205829Z" -} -``` - -You can see that Tetragon collected information on the process itself, with for -example, the uid, the binary name, the start_time and much more. It also -indicates process parent, `/bin/bash` in this case. This is the common base of -information we also get from the process lifecycle sensors. Finally, we can see -that Tetragon hooked the function `__x64_sys_openat` (for an arm64 host it -would be `__arm64_sys_openat`) and that it also collected the arguments' value. - -### Enforcement with TracingPolicy - -Let's see how we can modify the previous TracingPolicy to do enforcement with -Tetragon. - -{{< warning >}} -This example is just an illustration and should not be used in a production -environment. There are many challenges in building a production-grade policy, -that go beyond the scope of this guide. For example, filtering an argument for -security can be difficult, especially with file paths. The `openat` syscall can -take relative paths as arguments and even absolute path filtering can often be -bypassed by pseudo filesystems like procfs, for example using a prefix like -`/proc/self/root/` to access `/`. -{{< /warning >}} - -#### Overriding return values - -First, let's say we don't want to stop any program that would try to open the -`tracing_policy.yaml` but just stop them from actually using the syscall to -open the file, as if they were not unauthorized to access the file. We could -write the following TracingPolicy. - -```yaml -apiVersion: cilium.io/v1alpha1 -kind: TracingPolicy -metadata: - name: "file-access" -spec: - kprobes: - - call: "sys_openat" - syscall: true - args: - - index: 0 - type: "int" - - index: 1 - type: "string" - selectors: - - matchBinaries: - - operator: In - values: - - "/usr/bin/cat" - matchArgs: - - index: 1 - operator: "Equal" - values: - - "tracing_policy.yaml\0" - matchActions: - - action: Override - argError: -1 -``` - -In the above TracingPolicy, we removed the third argument because we don't -need to extract it specifically, and we added two filters in our existing -selector. One `matchArgs` to filter on the value of the index 1 argument, which -contains the pathname to access, and one `matchActions` to perform on action on -a such match. - -Replace the content of the policy in the `tracing_policy.yaml` file with the -above and restart Tetragon with the same command as before. If we open tetra -with `docker exec tetragon-container tetra getevents -o compact` and perform a -`cat tracing_policy.yaml` on the side, we should now observe an output similar -to: - -``` -πŸš€ process /usr/bin/cat tracing_policy.yaml -πŸ“¬οΈ openat /usr/bin/cat tracing_policy.yaml -πŸ’₯ exit /usr/bin/cat tracing_policy.yaml 1 -``` - -And the `cat tracing_policy.yaml` should return the following error: - -``` -cat: tracing_policy.yaml: Operation not permitted -``` - - -#### Synchronously stopping the process - -Now, let's say that accessing this file in this manner is critical and we want -to stop any process that tries to perform such action immediately. We just need -to modify the `action` in the `matchActions` filter from `Override` to -`Sigkill`. - -```yaml -apiVersion: cilium.io/v1alpha1 -kind: TracingPolicy -metadata: - name: "file-access" -spec: - kprobes: - - call: "sys_openat" - syscall: true - args: - - index: 0 - type: "int" - - index: 1 - type: "string" - selectors: - - matchBinaries: - - operator: In - values: - - "/usr/bin/cat" - matchArgs: - - index: 1 - operator: "Equal" - values: - - "tracing_policy.yaml\0" - matchActions: - - action: Sigkill -``` - -Again, replace the content of the policy in the `tracing_policy.yaml` file with -the above and restart Tetragon with the same command as before. If we open -tetra with `docker exec tetragon-container tetra getevents -o compact` and -perform a `cat tracing_policy.yaml` on the side, we should now observe an -output similar to: - -``` -πŸš€ process /usr/bin/cat tracing_policy.yaml -πŸ“¬οΈ openat /usr/bin/cat tracing_policy.yaml -πŸ’₯ exit /usr/bin/cat tracing_policy.yaml SIGKILL -``` - -And the `cat tracing_policy.yaml` should return an error (that is actually -returned by the shell that invoked the program): - -``` -Killed -``` - -Now the process will not have the time to catch the error and will be -synchronously terminated as soon as he triggers the kernel function we hooked -with our specified argument values. - -{{< caution >}} -Again, the specific filtering is only given as an example, just reading the -file using `cat ./tracing_policy.yaml` will bypass the policies presented here. -{{< /caution >}} - -## What's next - -- Try Tetragon in [Kubernetes environments]({{< ref "docs/getting-started/kubernetes-quickstart-guide" >}}). -- Learn more about [TracingPolicy]({{< ref "/docs/concepts/tracing-policy" >}}). -- See more use cases for observability in the [Use cases section]({{< ref "docs/use-cases" >}}). diff --git a/quickstart/file_monitoring.yaml b/quickstart/file_monitoring.yaml new file mode 100644 index 00000000000..f7e749a07a6 --- /dev/null +++ b/quickstart/file_monitoring.yaml @@ -0,0 +1,176 @@ +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "file-monitoring-filtered" +spec: + kprobes: + - call: "security_file_permission" + syscall: false + return: true + args: + - index: 0 + type: "file" # (struct file *) used for getting the path + - index: 1 + type: "int" # 0x04 is MAY_READ, 0x02 is MAY_WRITE + returnArg: + index: 0 + type: "int" + returnArgAction: "Post" + selectors: + - matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/boot" # Reads to sensitive directories + - "/root/.ssh" # Reads to sensitive files we want to know about + - "/etc/shadow" + - "/etc/profile" + - "/etc/sudoers" + - "/etc/pam.conf" # Reads global shell configs bash/csh supported + - "/etc/bashrc" + - "/etc/csh.cshrc" + - "/etc/csh.login" # Add additional sensitive files here + - index: 1 + operator: "Equal" + values: + - "4" # MAY_READ + - matchArgs: + - index: 0 + operator: "Postfix" + values: + - ".bashrc" # Reads to shell config files bash, csh supported + - ".bash_profile" # add any other shell support here. + - ".bash_login" + - ".bash_logout" + - ".cshrc" + - ".cshdirs" + - ".profile" # Reads to common environments files + - ".login" + - ".logout" + - ".history" # Add additional sensitive files here + - index: 1 + operator: "Equal" + values: + - "4" # MAY_READ + - matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc" # Writes to sensitive directories + - "/boot" + - "/lib" + - "/lib64" + - "/bin" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/bin" + - "/usr/sbin" + - "/var/log" # Writes to logs + - "/dev/log" + - "/root/.ssh" # Writes to sensitive files add here. + - index: 1 + operator: "Equal" + values: + - "2" # MAY_WRITE + - call: "security_mmap_file" + syscall: false + return: true + args: + - index: 0 + type: "file" # (struct file *) used for getting the path + - index: 1 + type: "uint32" # the prot flags PROT_READ(0x01), PROT_WRITE(0x02), PROT_EXEC(0x04) + - index: 2 + type: "uint32" # the mmap flags (i.e. MAP_SHARED, ...) + returnArg: + index: 0 + type: "int" + returnArgAction: "Post" + selectors: + - matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/boot" # Reads to sensitive directories + - "/root/.ssh" # Reads to sensitive files we want to know about + - "/etc/shadow" + - "/etc/sudoers" + - "/etc/pam.conf" # Reads global shell configs bash/csh supported + - "/etc/profile" + - "/etc/bashrc" + - "/etc/csh.cshrc" + - "/etc/csh.login" + - ".bashrc" # Reads to shell config files bash, csh supported + - ".bash_profile" # add any other shell support here. + - ".bash_login" + - ".bash_logout" + - ".cshrc" + - ".cshdirs" + - ".profile" # Reads to common environments files + - ".login" + - ".logout" + - ".history" # Add additional sensitive mmap files here + - index: 1 + operator: "Equal" + values: + - "1" # MAY_READ + - index: 2 + operator: "Mask" + values: + - "1" # MAP_SHARED + - matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc" # Writes to sensitive directories + - "/boot" + - "/lib" + - "/lib64" + - "/bin" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/bin" + - "/usr/sbin" + - "/var/log" # Writes to logs + - "/dev/log" + - "/root/.ssh" # Writes to sensitive files add here. + - index: 1 + operator: "Mask" + values: + - "2" # PROT_WRITE + - index: 2 + operator: "Mask" + values: + - "1" # MAP_SHARED + - call: "security_path_truncate" + syscall: false + return: true + args: + - index: 0 + type: "path" # (struct path *) used for getting the path + returnArg: + index: 0 + type: "int" + returnArgAction: "Post" + selectors: + - matchArgs: + - index: 0 + operator: "Prefix" + values: + - "/etc" # Truncate to sensitive directories + - "/boot" + - "/lib" + - "/lib64" + - "/usr/lib" + - "/usr/local/lib" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/bin" + - "/usr/sbin" + - "/var/log" # Truncate to logs + - "/dev/log" + - "/root/.ssh" # Truncate to sensitive files add here.