Skip to content

Latest commit

 

History

History
269 lines (206 loc) · 9.71 KB

README.md

File metadata and controls

269 lines (206 loc) · 9.71 KB

Packetflix

Siemens Industrial Edge Edgeshark

Packetflix

PkgGoDev GitHub build and test Go Report Card

Finally! Container "binge watching" live packet streams for Wireshark(nado) nerds!

Or much less nerdy: capture network traffic inside (Docker, &c.) container hosts and Kubernetes-in-Docker clusters ... and stream it live into your Desktop Wireshark for Windows/Linux.

But Packetflix is not limited to Wireshark scenarios, but could be used also in other applications, such as AI-based network traffic analysis, et cetera.

Packetflix...

  • ...is a micro service which runs on container hosts.
  • ..."understands" containers so it can capture from them without preparing or modifying your containers beforehand for capturing.
  • ...no container restarts required to start capturing, just let "El Shark" bite into your containers as you please.
  • ...streams packet capture data via websocket connections, thus being compatible with HTTP/websocket proxies.
  • ...is not a containerized Wireshark.
  • ...works on amd64 and arm64.

Quick Start

We provide multi-architecture Docker images for linux/amd64 and linux/arm64. First, ensure that you have the Docker compose plugin v2 installed. For Debian users it is strongly recommended to install docker-ce instead of docker.io packages, as these are updated on a regular basis.

wget -q --no-cache -O - \
  https://github.com/siemens/edgeshark/raw/main/deployments/wget/docker-compose.yaml \
  | docker compose -f - up

Finally, visit http://localhost:5001 and start looking around Linux kernel namespaces, as well as mount points with their hierarchies.

⚠ This quick start deployment will expose TCP port 5001 also to clients external to your host. Make sure to have proper network protection in place.

Eye Candy

Since micro services never look cool, here's a screenshot of a Desktop Wireshark session instead: here, we're going to capture from containers in a Docker host:

Binge Watching Packet Captures

No more ugly command lines, no "poking" around in container details ... just four clicks (well, five) and you're capturing live network traffic from inside any container. And without having to prepare or modify your containers beforehand.

Project Map

The Containershark extcap plugin is part of the "Edgeshark" project that consist of several repositories:

Deploying Packetflix

Building the Packetflix service requires the Go toolchain, make, a C compiler (used by cgeo), and finally Docker installed.

After deploying the Ghostwire service first, Packetflix can be deployed in the same way:

make deploy

⚠️ Packetflix does not have any integrated support for TLS (HTTPS). Instead, deploy a TLS-terminating and authenticating proxy in front of Packetflix with single-host container hosts.

Packetflix Service Args

  • --port, -p: port to expose the capture service on, defaults to port 6666.

  • --gw-port: local port where the GhostWire discovery service can be reached, defaults to port 5000.

  • --proxy-discovery: enables forwarding HTTP requests to the Ghostwire discovery service at /, unless they're part of the Packetflix API.

  • --debug: enables debugging messages.

  • --log-requests: log HTTP/WS requests.

  • --log-headers: log HTTP/WS request headers.

  • --version: show version string.

  • --help, -h: show help with available flag paremeters.

Container Deployment Notes

Packetflix in a Container

Packetflix must be run in the initial PID namespace, there's no way around it – it is how PID namespaces are designed to work, not allowing child (that iss, container) PID namespaces to touch any parent PID namespace or any sibling PID namespace of a parent.

services:
  packetflix:
    # Essential since we need full PID view.
    pid: host

Put Your Caps On

Packetflix requires the following Linux capabilities (and yes, CAP_SYS_ADMIN and CAP_SYS_PTRACE make any Marvel universe figure look powerless) listed below. Some capabilities are required when running packetflix as a non-root process (that is, not as UID0).

  • packetflix:

    • CAP_SYS_ADMIN is needed in order to switch into other namespaces, such as the network namespaces of containers. See also man 7 setns.

    • CAP_CHROOT is additionally needed to switch into mount namespaces of containers, in order to read their DNS configuration files (such as /etc/host, /etc/resolve, et cetera). See also man 7 setns.

    • CAP_SYS_PTRACE in order to be able to reference namespaces: the nsfs (namespace) filesystem requires this "god" capability in order to access namespace-related /proc nodes, such as /proc/$PID/ns/*. And GhostWire does not even use any ptrace(2) syscalls, it just reads from /proc. Another clear victory for the capabilities architecture: in order to discover namespaces, give the process process tracing and modification powers. Please see also Access /proc/pid/ns/net without running query process as root? for details and references to the nsfs filesystem involved.

  • dumpcap:

    • CAP_NET_ADMIN is needed in order to configure network interfaces for promiscuous mode, et cetera.

    • CAP_NET_RAW is required in order to capture network traffic.

services:
  packetflix:
    cap_drop:
      - ALL
    cap_add:
      - SYS_ADMIN # change namespaces
      - SYS_CHROOT # change mount namespaces
      - SYS_PTRACE # access nsfs namespace information
      - CAP_NET_ADMIN # to configure network interface capturing
      - CAP_NET_RAW # for, erm, well, capturing?

Root(h)less

Packetflix can be run as a non-root user process, when given the above mentioned capabilities. The required (effective) capabilities can be given to a non-root process by using file capabilities:

  • /packetflix
  • /usr/bin/dumpcap

Packetflix Container and AppArmor

Docker's default container AppArmor profile breaks Packetflix's and the namespace discovery process, causing kernel log messages of this kind:

audit: type=1400 audit(...): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=... comm="gw" requested_mask="read" denied_mask="read" peer="unconfined"

This is caused by Docker's default AppArmor template profile, which allows ptrace operations only within the same container, by specifying the container-specific AppArmor profile name:

# suppress ptrace denials when using 'docker ps' or using 'ps' inside a container
ptrace (trace,read,tracedby,readby) peer={{.Name}},

Packetflix containers thus need to be deployed with either an especially adapted AppArmor profile or as an unconstrained container. In your docker-compose.yaml, add the following settings for the packetflix service/container:

services:
  packetflix:
    security_opt:
      - apparmor:unconfined

Packetflix Container and Seccomp

Docker's default container seccomp profile luckily doesn't interfere with Packetflix's workings, as it actually allows the evil haxxor setns syscall, contrary to any claims in Docker's documentation that setns is blocked. In fact, the code repository profiles/seccomp/default.json shows that setns is in fact allowed:

  {
    "names": [
      "bpf",
      "clone",
      "fanotify_init",
      "lookup_dcookie",
      "mount",
      "name_to_handle_at",
      "perf_event_open",
      "quotactl",
      "setdomainname",
      "sethostname",
      "setns",
      "syslog",
      "umount",
      "umount2",
      "unshare"
    ],
    "action": "SCMP_ACT_ALLOW",
    "args": [],
    "comment": "",
    "includes": {
      "caps": [
        "CAP_SYS_ADMIN"
      ]
    },
    "excludes": {}
  },

Technical Details

Contributing

Please see CONTRIBUTING.md.

License and Copyright

(c) Siemens AG 2023

SPDX-License-Identifier: MIT