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:
makepacketstreamer receiver --config [configuration_file]You can use an example configuration file:
packetstreamer receiver --config ./contrib/config/receiver-local.yamlYou 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.yamlWhen 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 reportUse the RELEASE parameter to strip the binary for a production environment:
make RELEASE=1Use the STATIC parameter to statically-link the binary:
make STATIC=1Use 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=1Use the docker-image target to build a container image:
make docker-image
# Alternatively, build a stripped release binary
make docker-image RELEASE=1PacketStreamer can be deployed on Kubernetes using Helm:
kubectl apply -f ./contrib/kubernetes/namespace.yaml
helm install packetstreamer ./contrib/helm/ --namespace packetstreamerBy 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.yamldocker run --rm -it \
--cap-add=NET_ADMIN --net=host \
-v $(pwd)/contrib/config:/etc/packetstreamer \
deepfenceio/deepfence_packetstreamer \
sensor --config /etc/packetstreamer/sensor-local.yamlThe 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 reportThe 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 receivervagrant ssh sensorOn each, enter the source code directory:
cd PacketStreamer
./packetstreamer receiver --config ./contrib/config/receiver-vagrant.yamlcd PacketStreamer
sudo ./packetstreamer --config ./contrib/config/sensor-vagrant.yamlGenerate some live traffic
echo 'GET http://some_ip:80' | vegeta attack -rate 100 -duration 5m | tee results.bin | vegeta reportpacketstreamer 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_ # optionalYou 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.
