Deploying Edgeshark for Docker Network Packet Capture

David Krause12 min read
Industrial NetworkingSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview

Edgeshark is an open-source container observability stack developed and maintained by Siemens under the siemens/edgeshark GitHub organization. It provides two cooperating services that expose the live network topology of a Linux Docker host and enable remote packet capture from a desktop Wireshark installation. The project targets engineers running containerized workloads at the network edge, including industrial IoT gateways, OT/IT bridging hosts, and developer workstations emulating industrial edge environments.

Edgeshark is delivered as a pair of container images that cooperate with the Wireshark extcap plugin named csharg. The containerized side enumerates Docker networks, virtual Ethernet (veth) pairs, and bridge interfaces; the desktop side launches Wireshark and tunnels the capture stream through an SSH connection. Together the components replace the manual workflow of binding tcpdump into a sidecar container, copying .pcap files off the host, and correlating interface names to container identities by hand.

Industrial relevance. Edgeshark is commonly deployed in industrial contexts where a Docker host runs PLC runtime containers, MQTT brokers, OPC UA gateways, or SCADA historians on the same Linux kernel that bridges the OT and IT networks. The tool preserves the internal:true Docker network model that production stacks rely on, while still giving engineers a Wireshark-grade view of the wire.

Architecture and Components

An Edgeshark deployment consists of three runtime elements: a discovery/packet-capture service, a preferences service, and the csharg extcap plugin that runs on the analyst workstation. Communication between the workstation plugin and the container side uses a private SSH key generated on first launch.

Component Runtime Function Default Port
edgeshark-discover / packet-capture Container on Docker host Enumerates veth pairs, exposes topology REST API, runs tcpdump on demand 5000 (UI), 22/tcp (capture SSH)
edgeshark-preferences Container on Docker host Persists capture sessions and resolves container/interface mappings 5001
csharg extcap plugin Linux/macOS/Windows workstation Bridges Wireshark capture UI to Edgeshark via SSH n/a

The container side inspects the host's /proc/net/dev file and the Docker engine API (default unix:///var/run/docker.sock) to discover veth interfaces that connect each container namespace to the host bridge (typically docker0 or a user-defined bridge such as br-7f3a…). When a capture is requested, Edgeshark attaches tcpdump to the appropriate veth and streams the encoded PCAP-NG stream back over the SSH tunnel.

Prerequisites

Before deploying Edgeshark, verify that the target host and analyst workstation meet the following requirements.

Docker host requirements

  • Linux kernel 4.9 or newer (kernel 5.10+ recommended for proper BPF and veth statistics).
  • Docker Engine 20.10+ with the default bridge networking driver or a user-defined bridge.
  • At least 256 MB of free RAM for the Edgeshark services and additional headroom equal to the working-set of the largest container you intend to capture.
  • SSH connectivity from the analyst workstation to the Edgeshark capture port (default 22 on the host network namespace, forwarded to the container).

Analyst workstation requirements

  • Wireshark 3.6 or 4.0+. The csharg plugin is bundled with the release artifacts in the siemens/edgeshark repository.
  • OpenSSH client (ssh, ssh-keygen) in PATH.
  • For Linux workstations, setcap cap_net_raw,cap_net_admin+ep $(which dumpcap) is not required because capture is performed remotely; however, the local wireshark binary must still be able to spawn the extcap helper.

Network reachability

Open TCP/22 (or any port you map during deployment) between the workstation and the Docker host. Industrial sites that segment the engineering workstation VLAN from the OT VLAN should route the SSH port via the jump host used for vendor remote access.

Deployment Procedure

The reference deployment is a single docker-compose.yml file. The project repository publishes a ready-to-use compose file in the deployments directory of the siemens/edgeshark repository.

  1. Create a project directory and download the compose file:
    mkdir -p ~/edgeshark && cd ~/edgeshark
    wget -q --no-cache -O docker-compose.yml \
      https://raw.githubusercontent.com/siemens/edgeshark/main/deployments/docker-compose/docker-compose.yml
  2. Inspect the compose file. The default compose file starts two services on a shared edgeshark network and exposes the SSH capture port on host port 22 and the UI on host port 5000.
  3. Start the stack:
    docker compose up -d
    docker compose ps
    The ps output should show both services in the running state.
  4. Confirm the discovery API is reachable:
    curl -s http://localhost:5000/api/discover | jq .
    A JSON document containing the id, names, and networks of every container on the host is returned.
  5. Retrieve the auto-generated SSH private key that the csharg plugin will use:
    docker compose exec edgeshark-discover cat /etc/edgeshark/id_ed25519
    Copy this key to the workstation path expected by csharg (see the plugin section below).
Rootless Docker. When Docker is configured in rootless mode, replace the veth capture mechanism by granting the Edgeshark container access to /run/user/$(id -u)/docker.sock and adding network_mode: host. Rootless namespaces do not expose the same veth naming, so the edgeshark-discover service falls back to interface aliasing.

Wireshark Plugin Configuration

The csharg extcap plugin is the bridge between the Wireshark GUI and the Edgeshark capture backend. Install the plugin on the analyst workstation as follows.

  1. Download the release archive that matches your Wireshark major version from the siemens/edgeshark releases page.
  2. Extract the archive into the Wireshark extcap directory:
    • Linux: ~/.local/lib/wireshark/extcap/ or /usr/lib/x86_64-linux-gnu/wireshark/extcap/
    • macOS: ~/.config/wireshark/extcap/
    • Windows: %APPDATA%\Wireshark\extcap\
  3. Mark the csharg binary as executable (chmod +x csharg on POSIX systems).
  4. Place the private key retrieved in the previous section in ~/.config/wireshark/csharg_id_ed25519 with permissions 0600.
  5. Restart Wireshark. The capture options dialog will now show a new interface named csharg.

When the capture is started, csharg opens an SSH session to the Edgeshark host, requests the list of available interfaces, and presents each container's veth as a selectable interface. Selecting a veth automatically populates the BPF filter with the container's MAC address so that unrelated traffic is suppressed before it is streamed back to the workstation.

Capturing Container Traffic

After Wireshark is configured, capture proceeds through a normal Wireshark workflow with the additional csharg interface.

  1. Open Wireshark and select Capture → Options.
  2. From the interface list, choose csharg and click Options next to it. Enter the host address, SSH port, and container name filter.
  3. Apply a display filter such as mqtt or opcua to focus on industrial protocol traffic.
  4. Click Start. The status bar shows csharg: connected to container plc-runtime-1 when the tunnel is established.
  5. Stop the capture with the red square button. The capture file is saved locally as PCAP-NG with per-interface link types, allowing post-capture replay through tshark or editcap.
Industrial Protocol Wireshark Display Filter Default TCP/UDP Port Notes
Modbus TCP mbtcp or modbus 502/tcp Use mb.reg for register-level detail.
S7comm (Siemens) s7comm or tns 102/tcp Decodes PDU type, function group, and DB number.
PROFINET pn_rt or pn_dcp UDP 34962-34964 Real-time frames require veth capture, not bridge mirror.
EtherNet/IP enip or cip 44818/tcp, 2222/udp Encapsulated CIP requires cip decoder.
OPC UA Binary opcua 4840/tcp Decodes service IDs and security policy.
MQTT mqtt 1883, 8883 Topic filter via mqtt.topic.
DNP3 dnp3 20000/tcp Used in North American utility deployments.

Industrial Use Cases

Edgeshark's primary field of use is troubleshooting containerized industrial workloads. The following scenarios are common in production deployments.

Containerized PLC runtime capture

A Docker host running a soft-PLC such as the Siemens S7-PLCSIM Advanced instance, CODESYS Control for Raspberry Pi, or an open-source OpenPLC runtime often multiplexes multiple virtual PLCs on a single bridge. Edgeshark exposes each PLC's veth as a discrete capture interface, allowing the engineer to inspect S7comm or Modbus TCP traffic for a specific logical controller without mirroring the entire bridge.

OPC UA gateway inter-container inspection

An OPC UA gateway container typically publishes data from a south-bound protocol (S7, Modbus, EtherNet/IP) to a north-bound broker (MQTT, Kafka, AMQP). When the gateway behaves incorrectly, Edgeshark's web UI shows whether the connection between the gateway container and the broker container traverses a user-defined bridge, the default bridge, or a macvlan interface. The capture then confirms that the south-bound polling actually reaches the PLC by checking the S7comm service IDs in the trace.

Edge-to-cloud MQTT broker debugging

On edge hosts that publish telemetry to a cloud broker, Edgeshark can be co-located with the broker container to capture TLS handshakes. The SSH tunnel keeps the capture off the cloud network, which is critical when the broker container uses a self-signed certificate pinned by the application.

Network segmentation validation

Before commissioning an internal-only Docker network, an engineer can use Edgeshark's web UI to verify that no container has a published port that should remain private. The topology view displays every bridge, overlay, and macvlan attachment, including the auto-generated IPv6 link-local addresses that often expose services unintentionally.

Multi-Host and Cluster Considerations

Edgeshark is designed for a single Linux Docker host. Clustered environments require either multiple Edgeshark instances or alternative tooling.

  • Docker Swarm. Deploy one Edgeshark stack per Swarm worker that runs the workloads of interest. Use Swarm's node.labels constraint to pin the Edgeshark services to the targeted node, then expose the capture SSH port only on the overlay IP of that node.
  • Kubernetes. Edgeshark does not interpret CNI plugins such as flannel, calico, or cilium. For Kubernetes clusters, use a CNI-aware solution such as Wireshark on a hostPath mount of the node, or run Edgeshark inside a privileged DaemonSet that targets a single worker.
  • Proxmox / LXC nested. An LXC privileged container with Docker installed and a routed bridge can host Edgeshark, but the veth names inside the LXC differ from the host. Map the LXC network namespace carefully and verify that ip link show inside the LXC shows the same veth pair that docker network inspect reports.
Limit. Edgeshark will not aggregate traffic from multiple Docker hosts. If your deployment spans more than one host, deploy one instance per host and correlate captures with editcap --inject-secrets or with a SIEM that ingests Wireshark exports.

Security Hardening

Edgeshark exposes significant network visibility and must be treated as a privileged diagnostic tool. The following hardening steps are recommended for industrial environments.

  1. Restrict SSH key access. Regenerate the auto-generated Edgeshark SSH key on first launch, store it on a hardware token, and remove it from the container when capture sessions are not active.
  2. Network segmentation. Bind the Edgeshark UI and capture ports to a dedicated engineering VLAN. Do not expose port 5000 or 22 to the OT network.
  3. Read-only file systems. Mount /etc/edgeshark and the SSH key directory as :ro when the analyst only needs to view topology without starting captures.
  4. Disable internal:true discovery for production stacks by setting the EDGESHARK_NETWORK_FILTER environment variable to a comma-separated list of bridge names.
  5. Audit logging. Enable Docker's log-driver: json-file with a size cap and forward the Edgeshark container logs to a central syslog server for forensic review.
  6. TLS for the topology UI. Place Edgeshark behind a reverse proxy that terminates TLS, such as the nginx or traefik containers already common in industrial stacks.

Troubleshooting Matrix

Symptom Likely Cause Verification Resolution
Web UI shows No containers found Docker socket not mounted or wrong path docker compose exec edgeshark-discover ls -l /var/run/docker.sock Add /var/run/docker.sock:/var/run/docker.sock mount to the compose file
csharg lists no interfaces SSH key mismatch or wrong permissions ssh -i ~/.config/wireshark/csharg_id_ed25519 -p 22 edgeshark@<host> ls Re-copy the key, set chmod 0600
Capture shows only ARP veth misnamed; tcpdump attached to wrong interface docker exec -it <container> cat /proc/net/route Restart edgeshark-discover; verify kernel ≥ 4.9
Plugin appears in Wireshark but is greyed out Wireshark not in PATH for the extcap helper Run csharg --extcap-interfaces from a shell Reinstall the plugin into the user-level extcap directory
Topology page loads slowly on a 100+ container host Default polling interval too aggressive Check EDGESHARK_POLL_INTERVAL in the compose file Raise the interval to 10 s
Industrial protocol not decoded Wireshark version too old for the dissector wireshark --version Upgrade to Wireshark 4.0 or newer; install the industrial-protocols profile
Permission denied when tcpdump starts Container lacks CAP_NET_RAW and CAP_NET_ADMIN docker inspect edgeshark-discover | jq '.[0].HostConfig.CapAdd' Add cap_add: [NET_ADMIN, NET_RAW] to the compose service

Performance and Capacity Notes

Edgeshark streams captured frames over SSH and through a single veth. At a 1 Gbit/s link the bottleneck is the SSH encryption on the workstation, not Edgeshark itself. The following limits have been observed in field deployments.

  • Up to 200 Mbit/s sustained capture when the workstation is a quad-core x86 with AES-NI enabled.
  • Up to 50 containers simultaneously inspected in the topology view before the UI degrades; split the deployment across multiple Edgeshark instances for larger hosts.
  • Capture files larger than 2 GB should be rotated with editcap -c 1000 (1000 MB) to keep Wireshark responsive.

Alternatives and When to Choose Them

Edgeshark is not the only Docker visibility tool. Pick the right instrument based on the engineering question being asked.

Tool Primary Strength Limit Compared to Edgeshark When to Use
Edgeshark (Siemens) Wireshark-grade PCAP per container, with topology UI Single host, requires Wireshark on the analyst Deep packet inspection during commissioning or incident response
Sniffnet Lightweight per-process traffic in a noVNC container No Wireshark integration, no veth awareness Quick spot-check of bandwidth by process
Docker network CLI (docker network inspect) Native, no extra deployment No capture, no visualization Configuration-only verification
Headlamp (Kubernetes) Cluster-wide resource and topology view No PCAP, K8s only Kubernetes orchestration diagnostics
tcpdump in a sidecar No extra infrastructure Manual correlation, file transfer required One-off captures on a single container

Frequently Asked Questions

Does Edgeshark require root inside the container?

Edgeshark needs CAP_NET_RAW and CAP_NET_ADMIN to attach tcpdump to veth pairs. It does not require UID 0; you can set user: "0:0" in compose or grant the capabilities explicitly with cap_add: [NET_RAW, NET_ADMIN].

Can Edgeshark capture TLS-encrypted industrial traffic?

Yes, the capture is identical to a bare Wireshark session. Decryption requires the server's RSA private key or the session keys obtained from the application. For OPC UA, set the --keylogfile argument in the OPC UA stack and feed the file to Wireshark via Edit → Preferences → TLS.

Will Edgeshark break my internal:true Docker networks?

No. Edgeshark only reads from the Docker API and the host's network namespace. It does not modify iptables, bridge forwarding, or network drivers, so the isolation guarantees of internal:true networks remain intact.

What is the difference between Edgeshark and the csharg plugin alone?

The csharg plugin is the Wireshark extcap helper that ships in the siemens/edgeshark releases. Edgeshark is the container side that provides the topology UI and the veth discovery. Both are required for a working capture.

Does Edgeshark support rootless Docker?

Partially. Rootless Docker uses a different network namespace hierarchy, and the default Edgeshark compose file assumes the standard docker0 bridge. With network_mode: host and the user-level Docker socket mounted, Edgeshark can capture from a rootless host, but the topology view will be limited to the user-scoped networks.

Back to blog