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.
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
cshargplugin is bundled with the release artifacts in the siemens/edgeshark repository. - OpenSSH client (
ssh,ssh-keygen) inPATH. - For Linux workstations,
setcap cap_net_raw,cap_net_admin+ep $(which dumpcap)is not required because capture is performed remotely; however, the localwiresharkbinary 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.
- 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 - Inspect the compose file. The default compose file starts two services on a shared
edgesharknetwork and exposes the SSH capture port on host port 22 and the UI on host port 5000. - Start the stack:
Thedocker compose up -d docker compose pspsoutput should show both services in therunningstate. - Confirm the discovery API is reachable:
A JSON document containing thecurl -s http://localhost:5000/api/discover | jq .id,names, andnetworksof every container on the host is returned. - Retrieve the auto-generated SSH private key that the
cshargplugin will use:
Copy this key to the workstation path expected bydocker compose exec edgeshark-discover cat /etc/edgeshark/id_ed25519csharg(see the plugin section below).
/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.
- Download the release archive that matches your Wireshark major version from the siemens/edgeshark releases page.
- 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\
- Linux:
- Mark the
cshargbinary as executable (chmod +x cshargon POSIX systems). - Place the private key retrieved in the previous section in
~/.config/wireshark/csharg_id_ed25519with permissions0600. - 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.
- Open Wireshark and select Capture → Options.
- From the interface list, choose
cshargand click Options next to it. Enter the host address, SSH port, and container name filter. - Apply a display filter such as
mqttoropcuato focus on industrial protocol traffic. - Click Start. The status bar shows
csharg: connected to container plc-runtime-1when the tunnel is established. - 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
tsharkoreditcap.
| 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.labelsconstraint 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, orcilium. For Kubernetes clusters, use a CNI-aware solution such as Wireshark on ahostPathmount of the node, or run Edgeshark inside a privilegedDaemonSetthat 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 showinside the LXC shows the same veth pair thatdocker network inspectreports.
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.
- 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.
- 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.
-
Read-only file systems. Mount
/etc/edgesharkand the SSH key directory as:rowhen the analyst only needs to view topology without starting captures. -
Disable
internal:truediscovery for production stacks by setting theEDGESHARK_NETWORK_FILTERenvironment variable to a comma-separated list of bridge names. -
Audit logging. Enable Docker's
log-driver: json-filewith a size cap and forward the Edgeshark container logs to a central syslog server for forensic review. -
TLS for the topology UI. Place Edgeshark behind a reverse proxy that terminates TLS, such as the
nginxortraefikcontainers 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.