Command Palette

Search for a command to run...

Hectal
Lab 2.2·Containers & InfrastructureCRITICAL

The log shipper that owned the host

The observability lab mounts /var/run/docker.sock into Alloy so it can read container logs. That socket is full control of the Docker host.

Weakness
CWE-269 · Improper privilege management · CIS Docker 5.31
Target
the alloy service in obs-lab/docker-compose.yml (Observability course)
what the Docker socket grantsfinding socket mountssocket proxies with an API allowlistlog collection without the socket

Run these techniques only against the lab you own. Using them on systems you don't have permission to test is illegal.

The threat

  1. 01The socket is the Docker API — all of it

    The Docker daemon runs as root and trusts anything that can talk to its socket. The API can start containers with any configuration, including privileged containers or ones that mount the host's filesystem. Access to the socket is therefore equivalent to root on the host, even with :ro on the mount, because read-only applies to the socket FILE, not to the API calls made through it.

    A compromised log shipper, metrics agent, or CI helper that holds the socket is a compromised host.

What's at risk

  • Root-equivalent control of the host and every container on it.

Detect

  1. 01Find every container with the socket mounted

    terminal
    $ docker ps -q | xargs docker inspect --format '{{.Name}} {{range .Mounts}}{{.Source}} {{end}}' | grep docker.sock
    ── output ──
    /obs-lab-alloy-1 /var/run/docker.sock /home/priya/obs-lab/alloy/config.alloy
  2. 02Catch it in review with a scanner

    Policy scanners flag socket mounts in compose files and Kubernetes manifests (as hostPath volumes). Checkov's CKV_K8S_27 ('Do not expose the docker daemon socket to containers') is one example; trivy config has equivalent checks for Kubernetes.

Defend

  1. 01Put an allowlisting proxy in front of the socket

    A socket proxy exposes only the API endpoints the tool needs. Alloy's Docker discovery and log source need to LIST containers and READ their logs, not create, exec, or change anything. Only the proxy container touches the real socket, and it forbids everything else.

    Vulnerable

    obs-lab/docker-compose.ymladd to fileyaml
      alloy:
        image: grafana/alloy:v1.10.0
        volumes:
          - ./alloy/config.alloy:/etc/alloy/config.alloy:ro
          - /var/run/docker.sock:/var/run/docker.sock:ro

    Hardened

    obs-lab/docker-compose.ymladd to fileyaml
      docker-proxy:
        image: tecnativa/docker-socket-proxy:v0.3.0
        environment:
          CONTAINERS: 1      # allow GET /containers/* (list, inspect, logs)
          POST: 0            # deny every write (create, start, exec, ...)
        volumes: ["/var/run/docker.sock:/var/run/docker.sock:ro"]
        read_only: true
    
      alloy:
        image: grafana/alloy:v1.10.0
        volumes: ["./alloy/config.alloy:/etc/alloy/config.alloy:ro"]
        # in config.alloy: host = "tcp://docker-proxy:2375"
  2. 02Better still: don't need the API

    In Kubernetes, log agents read container log FILES from the node (/var/log/pods) through a narrow read-only hostPath rather than the runtime socket. Apps can also ship telemetry directly with OTLP. Grant the smallest interface that does the job.

Verify

  1. 01Logs still flow; writes through the proxy are refused

    Loki keeps receiving container logs. A write request through the proxy (any POST) gets HTTP 403 from the proxy before it ever reaches Docker.

    terminal
    $ docker compose exec alloy wget -qO- --post-data='' http://docker-proxy:2375/containers/create 2>&1 | head -1
    ── output ──
    wget: server returned error: HTTP/1.1 403 Forbidden

The concepts

Ambient authority

The socket is 'ambient authority': whoever holds it can do anything the daemon can, with no finer-grained check. Security improves when authority is explicit and narrow: a proxy with an allowlist, a scoped API token, a read-only file mount. Look for other ambient-authority mounts too: the containerd socket, the kubelet's credentials, cloud metadata access from containers (Chapter 3).

Your turn

01

Which other commonly deployed tools often request the Docker socket, and what's the safer alternative for each?

Interview questions

01

Why is mounting the Docker socket into a container dangerous?

0/4 · 0%