Deepfence PacketStreamer is a high-performance remote packet capture and collection tool. It is used by Deepfence's ThreatStryker security observability platform to gather network traffic on demand from cloud workloads for forensic analysis.
Primary design goals:
- Stay light, capture and stream, no additional processing
- Portability, works across virtual machines, Kubernetes and AWS Fargate. Linux and Windows.
PacketStreamer sensors are started on the target servers. Sensors capture traffic, apply filters, and then stream the traffic to a central reciever. Traffic streams may be compressed and/or encrypted using TLS.
The PacketStreamer reciever accepts PacketStreamer streams from multiple remote sensors, and writes the packets to a local pcap
capture file
PacketStreamer sensors collect raw network packets on remote hosts. It selects packets to capture using a BPF filter, and forwards them to a central reciever process where they are written in pcap format. Sensors are very lightweight and impose little performance impact on the remote hosts. PacketStreamer sensors can be run on bare-metal servers, on Docker hosts, and on Kubernetes nodes.
The PacketStreamer receiver accepts network traffic from multiple sensors, collecting it into a single, central pcap
file. You can then process the pcap file or live feed the traffic to the tooling of your choice, such as Zeek
, Wireshark
Suricata
, or as a live stream for Machine Learning models.
PacketStreamer meets more general use cases than existing alternatives. For example, PacketBeat captures and parses the packets on multiple remote hosts, assembles transactions, and ships the processed data to a central ElasticSearch collector. ksniff captures raw packet data from a single Kubernetes pod.
Use PacketStreamer if you need a lightweight, efficient method to collect raw network data from multiple machines for central logging and analysis.
- Deepfence ThreatStryker uses PacketStreamer to capture traffic from production platforms for forensics and anomaly detection.
Build the packetstreamer
binary using the go
toolchain as follows:
make
packetstreamer receiver --config [configuration_file]
You can use an example configuration file:
packetstreamer receiver --config ./contrib/config/receiver-local.yaml
You can process the pcap
output in a variety of ways:
# pass the output file /tmp/dump_file to tcpdump:
tail -c +1 -f /tmp/dump_file | tcpdump -r -
# Edit the configuration to write to /dev/stdout, and pipe output to tcpdump:
./packet-streamer receiver --config contrib/receiver-stdout.yaml | tcpdump -r -
sudo packetstreamer sensor --config [configuration_file]
You can use an example configuration file:
sudo packetstreamer sensor --config ./contrib/config/sensor-local.yaml
When running the sensor remotely, edit the configuration file to target the remote receiver.
You can generate some test traffic using your favorite load generator - ab
, wrk
, httperf
, vegeta
. For example, to use vegeta:
# install vegeta
go install github.com/tsenart/vegeta@latest
echo 'GET http://some_ip:80' | vegeta attack -rate 100 -duration 5m | tee results.bin | vegeta report
Use the RELEASE
parameter to strip the binary for a production environment:
make RELEASE=1
Use the STATIC
parameter to statically-link the binary:
make STATIC=1
Use the docker-bin
target to build packetstreamer
with Docker. The binary will be statically linked with musl
and libpcap
, making it portable across Linux distributions:
make docker-bin
# Alternatively, build a stripped release binary
make docker-bin RELEASE=1
Use the docker-image
target to build a container image:
make docker-image
# Alternatively, build a stripped release binary
make docker-image RELEASE=1
PacketStreamer can be deployed on Kubernetes using Helm:
kubectl apply -f ./contrib/kubernetes/namespace.yaml
helm install packetstreamer ./contrib/helm/ --namespace packetstreamer
By default, the Helm chart deploys a DaemonSet with sensor on all nodes and one receiver instance. For the custom configuration values, please refer to the values.yaml file.
PacketStreamer container images can be tested locally on Docker.
docker run --rm -it \
-v $(pwd)/contrib/config:/etc/packetstreamer \
-v $HOME/container_tmp:/tmp \
-p 8081:8081 \
deepfenceio/deepfence_packetstreamer \
receiver --config /etc/packetstreamer/receiver.yaml
docker run --rm -it \
--cap-add=NET_ADMIN --net=host \
-v $(pwd)/contrib/config:/etc/packetstreamer \
deepfenceio/deepfence_packetstreamer \
sensor --config /etc/packetstreamer/sensor-local.yaml
The sensor requires --net=host
and NET_ADMIN
capability in order to capture all of the packets on the host.
echo 'GET http://some_ip:80' | vegeta attack -rate 100 -duration 5m | tee results.bin | vegeta report
The pcap
dump file is available in $HOME/container_tmp/dump_file
.
On a single host, you may use Vagrant to run sensor and receiver hosts easily:
Install Vagrant according to the official instructions. By default, Vagrant uses Virtualbox; you should install vagrant-libvirt, using vagrant plugin install vagrant-libvirt
.
Start the two Vagrant VMs, receiver
and sensor
:
vagrant up
vagrant status
# Current machine states:
#
# receiver running (libvirt)
# sensor running (libvirt)
SSH to those VMs (in separate terminals) by using the following commands:
vagrant ssh receiver
vagrant ssh sensor
On each, enter the source code directory:
cd PacketStreamer
./packetstreamer receiver --config ./contrib/config/receiver-vagrant.yaml
cd PacketStreamer
sudo ./packetstreamer --config ./contrib/config/sensor-vagrant.yaml
Generate some live traffic
echo 'GET http://some_ip:80' | vegeta attack -rate 100 -duration 5m | tee results.bin | vegeta report
packetstreamer
is configured using a yaml-formatted configuration file.
input: # required in 'receiver' mode
address: _ip-address_
port: _listen-port_
output:
server: # required in 'sensor' mode
address: _ip-address_
port: _listen-port_
file: # required in 'receiver' mode
path: _filename_
tls: # optional
enable: _true_|_false_
certfile: _filename_
keyfile: _filename_
auth: # optional; receiver and sensor must use same shared key
enable: _true_|_false_
key: _string_
compressBlockSize: _integer_ # optional; default: 65
inputPacketLen: _integer_ # optional; default: 65535
logFilename: _filename_ # optional
pcapMode: _Allow_|_Deny_|_All_ # optional
capturePorts: _list-of-ports_ # optional
captureInterfacesPorts: _map: interface-name:port_ # optional
ignorePorts: _list-of-ports_ # optional
You can find example configuration files in the /contrib/config/
folder.
Thank you for using PacketStreamer.
Got a question, need some help? Find the Deepfence team on Slack
- https://github.com/deepfence/PacketStreamer/issues: Got a feature request or found a bug? Raise an issue
- productsecurity at deepfence dot io: Found a security issue? Share it in confidence
- Find out more at deepfence.io
For any security-related issues in the PacketStreamer project, contact productsecurity at deepfence dot io.
Please file GitHub issues as needed, and join the Deepfence Community Slack channel.
The Deepfence PacketStreamer project (this repository) is offered under the Apache2 license.
Contributions to Deepfence PacketStreamer project are similarly accepted under the Apache2 license, as per GitHub's inbound=outbound policy.