Security Azure

Tetragon on Ubuntu 24.04 on Azure User Guide

| Product: Tetragon on Ubuntu 24.04 LTS on Azure

Overview

Tetragon is Cilium's eBPF-based runtime security observability and enforcement engine. It observes what actually happens on a host - process execution, file access, network activity and privileged system calls - directly from the Linux kernel using eBPF, with rich process context and negligible overhead.

Tetragon is most often deployed on Kubernetes, but it also runs standalone on a single host as a systemd service watching that host's own kernel - and that is how this cloudimg image runs it. You get kernel-level runtime security on one Linux machine, no cluster required.

The cloudimg image is a ready-to-run host-runtime security appliance, not just the binary. It ships hardened defaults, a sensible TracingPolicy set so it emits meaningful events out of the box, structured JSON export for your SIEM or log shipper, and a self-test that proves a monitored action produces an event. Backed by 24/7 cloudimg support.

What is included:

  • Tetragon 1.7.0 (/usr/local/bin/tetragon + the tetra CLI), installed from the official release tarball and verified against the upstream SHA256 checksum
  • The daemon running as tetragon.service, exporting structured JSON events to /var/log/tetragon/tetragon.log
  • A default TracingPolicy set in /etc/tetragon/tetragon.tp.d/ - sensitive-file access monitoring and privileged-syscall (setuid) monitoring - on top of Tetragon's always-on process execution and exit events
  • tetragon-selftest - a bounded self-test that triggers a monitored action and confirms the matching event is produced
  • A loopback-only control surface (gRPC unix socket; health port pinned to loopback and guarded by nftables)
  • 24/7 cloudimg support

This is a headless product: no web UI, no admin account and no password. SSH on port 22 is the only open port, and the SSH key you choose at launch is the only way in.

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point. NSG inbound: allow 22/tcp from your management network only - no inbound application ports are needed. Tetragon requires a modern kernel exposing BTF (/sys/kernel/btf/vmlinux); the Ubuntu 24.04 base image provides this out of the box.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Tetragon by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22). Then Review + create -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name tetragon \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

There is no password and no console to log in to - this product has no credentials. /etc/tetragon/credentials on the VM is an informational note that says exactly that and points at the paths below.

Step 4 - Confirm Tetragon is running

tetragon version
level=info msg="Starting tetragon" version=v1.7.0

Check the service and the tetra CLI:

systemctl is-active tetragon
active

Tetragon version, hardened configuration and the loopback-only control surface

Step 5 - Prove it works end to end

tetragon-selftest triggers a monitored action on the host - a read of the watched sensitive file /etc/shadow - and confirms Tetragon produced the corresponding event. It is the honest proof that the engine is loaded and observing, not just running:

sudo tetragon-selftest
Tetragon self-test: proving a monitored action produces an event...
default TracingPolicy 'file-monitoring' is loaded
PASS: Tetragon observed the read of /etc/shadow. Most recent matching event:
{"process_kprobe":{"process":{"binary":"/usr/bin/cat","arguments":"/etc/shadow", ...},"function_name":"security_file_permission","args":[{"file_arg":{"path":"/etc/shadow","permission":"-rw-r-----"}},{"int_arg":4}],"action":"KPROBE_ACTION_POST","policy_name":"file-monitoring"}}

The event carries the full process context - the binary (/usr/bin/cat), its arguments, the user, and the parent process - so you can see exactly who read the file, not just that it was read.

The self-test triggering a monitored action and Tetragon reporting the event

Step 6 - Read the events

Every event Tetragon observes is exported as one JSON object per line to /var/log/tetragon/tetragon.log. Confirm process-execution events are flowing:

sudo grep -c '"process_exec"' /var/log/tetragon/tetragon.log
128

To watch events live as they happen, stream them from the daemon with the tetra CLI - -o compact gives a one-line-per-event summary:

sudo tetra --server-address unix:///var/run/tetragon/tetragon.sock getevents -o compact
🚀 process default/tetragon-host /usr/bin/cat /etc/shadow
📚 syscall default/tetragon-host /usr/bin/cat security_file_permission
🚀 process default/tetragon-host /usr/bin/sshd

Point your log shipper or SIEM at /var/log/tetragon/tetragon.log and you have a kernel-level audit trail of process activity, sensitive-file access and privilege changes on the host.

Structured JSON events and the loaded default TracingPolicy set

Step 7 - The default TracingPolicy set

Tetragon always emits process execution and exit events. Everything else is driven by TracingPolicies - YAML that tells the kernel-side engine what to observe (and optionally enforce). This image loads its default policies from /etc/tetragon/tetragon.tp.d/:

ls -1 /etc/tetragon/tetragon.tp.d/
file-monitoring.yaml
privileged-syscalls.yaml

List what the daemon has loaded:

sudo tetra --server-address unix:///var/run/tetragon/tetragon.sock tracingpolicy list
ID   NAME                  STATE     SENSORS
1    file-monitoring       enabled   generic_kprobe
2    privileged-syscalls   enabled   generic_kprobe
  • file-monitoring - reports reads of credential and authentication files (/etc/shadow, /etc/sudoers, /root/.ssh, /boot) and writes to system binary and configuration directories.
  • privileged-syscalls - reports setuid calls, so privilege changes are visible.

Step 8 - Add your own policy

Drop any TracingPolicy YAML into /etc/tetragon/tetragon.tp.d/ and restart the service to load it. For example, to also monitor reads of /etc/ssh/sshd_config, create /etc/tetragon/tetragon.tp.d/my-policy.yaml:

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: "sshd-config-reads"
spec:
  kprobes:
  - call: "security_file_permission"
    syscall: false
    args:
    - index: 0
      type: "file"
    - index: 1
      type: "int"
    selectors:
    - matchArgs:
      - index: 0
        operator: "Equal"
        values:
        - "/etc/ssh/sshd_config"

Then reload:

sudo cp my-policy.yaml /etc/tetragon/tetragon.tp.d/
sudo systemctl restart tetragon

The Tetragon documentation covers the full policy language, including in-kernel filtering and enforcement actions (for example, sending SIGKILL when a policy matches).

Configuration

The daemon configuration is a set of drop-in files under /etc/tetragon/tetragon.conf.d/ (one file per setting). This image's hardened defaults:

for k in server-address health-server-address export-filename tracing-policy-dir; do printf '%-22s %s\n' "$k" "$(cat /etc/tetragon/tetragon.conf.d/$k)"; done
server-address         unix:///var/run/tetragon/tetragon.sock
health-server-address  localhost:6789
export-filename        /var/log/tetragon/tetragon.log
tracing-policy-dir     /etc/tetragon/tetragon.tp.d
  • server-address - the gRPC control interface, a loopback-only unix socket.
  • health-server-address - pinned to localhost so the health port is never reachable off-box.
  • export-filename - where JSON events are written.
  • tracing-policy-dir - where TracingPolicies are loaded from at startup.

To change a setting, edit the relevant file (or add a new one) and restart tetragon.

Security

This image is hardened for a security tool:

  • SSH only. Nothing listens on the network except sshd on port 22. Confirm it:
ss -tlnp 2>/dev/null | awk 'NR==1 || /:22 /'
  • Loopback-only control surface. The gRPC interface is a unix socket, and the health port (tcp/6789, which upstream binds to all interfaces by default) is pinned to loopback and guarded by an nftables rule that drops any off-box access. Confirm the guard:
sudo nft list table inet tetragon_guard | grep -E 'dport 6789'
tcp dport 6789 drop
  • No baked credential. The image ships no password of any kind. Per-VM uniqueness comes from the SSH host keys each instance regenerates on first boot.
  • Patched and self-updating. The OS is fully patched at capture and unattended security upgrades remain enabled.

The nftables health-port guard and the SSH-only listener set

Maintenance

  • Events: structured JSON at /var/log/tetragon/tetragon.log (rotated automatically). Stream live with sudo tetra --server-address unix:///var/run/tetragon/tetragon.sock getevents.
  • Policies: add or edit YAML in /etc/tetragon/tetragon.tp.d/ and sudo systemctl restart tetragon. List loaded policies with tetra ... tracingpolicy list.
  • Service: systemctl status tetragon; logs with journalctl -u tetragon.
  • Upgrades: download a newer release from the Tetragon releases, verify it against the published .sha256sum, and re-run its install.sh.
  • Security patches: unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.

Support

cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.