The goal of this project is to implement a distributed network intrusion detection system using random forests. The classification is done in the data plane of programmable switches, utilizing resources that would otherwise be wasted. These free resources are scarce, therefore distinct parts of the ML model are uploaded to different switches. Switches belong to different administrative domains, so the model must be distributed in a secure manner. For this reason federated learning is used: each domain trains/refines its own model and the results are combined by a centralized coordinator, which then distributes the updated model to the various domains. The switches within each domain work together to classify packets: they use different slices of the same ML model. Different network slices execute the inference separately; they only work together to build a better model.
The project is currently Work In Progress. Its federated learning capabilities are not yet implemented, the coordinator component is currently no-op.
docker: development environment for prototyping. Contains the required dependencies and tools for development, but doesn't support eBPF or Tofino switches. Can be used a remote Python interpreter.net_runner: responsible for compiling the P4 source code and starting a simulated network via Mininetswitch: P4 source code. Configurable constants can be found in a dedicated file.lib_common: shared library between various Python scripts. Contains constants based on the P4 source code.controller,oracle,coordinator: Python implementations of the various components. Please refer to the plan overview diagram at the top of this document for more information.centralized: an alternative controller that executes inference within the Python script as opposed to in-network.trainer: capable of creating a pre-trained model from data previously collected by other components.pcap_extractor: extracts flow features and flow data from PCAP files, which can then be used for training a model.training_data: contains the training data. This data might have to be manually downloaded, please refer to the README.md in the directory.work: working directory, contains automatically generated files.Makefile: main entry point for this project.tofino-topology.json: topology definition used when Tofino switches are used.grafana-dashboard.json: Grafana dashboard definition for visualizing the results of the simulation in real time.- Requires InfluxDB 3 with a
natwork-t52database and the admin token to be set in theStatsDatabaseConfigclass.
- Requires InfluxDB 3 with a
- Ensure you have the dependencies listed in docker/Dockerfile.
- Using a docker container is not recommended: some networking and BPF-related features are not expected to work.
- Training data might have to be manually downloaded, please read the relevant README.
- If Tofino switches are used, the Tofino SDE must be installed and configured.
When editing the P4 source code, make sure to keep lib_common/data.py up-to-date.
The Makefile can be used to manage the various components of the project. The file also contains configuration options, which can be modified based on what kind of simulation is desired.
Common commands:
make clean: deletes generated files (e.g. compiled P4 source code), except caches.make clean-all: deletes all generated files, including caches.
To enable debug logging for any command, append DEBUG=1 to the command line.
Example: make mininet-compile DEBUG=1
Commands:
make mininet-compile: compiles the P4 source code and nothing else. Other commands also include this step. No recompilation is triggered if no changes are detected in the P4 source directory.make mininet-cli: starts a simulated network with a CLI, also starting the various project components.make mininet-eval: rather then starting a CLI, it runs an evaluation that replays a PCAP file.
Unlike with the mininet-eval command, the individual components must be started manually when using Tofino.
On top of that, the PCAP files might need to be modified to avoid MTU issues. Example of truncation, including filtering for a specific attack type by only including a specific range of packets:
editcap -F pcap friday.pcap - 1-5700000 | tcpreplay-edit --mtu=1300 --mtu-trunc --no-flow-stats --fixhdrlen --topspeed -w ddos_and_portscan.pcap -Commands:
make tofino-oracle: starts the oracle componentmake tofino-coordinator: starts the controller componentmake tofino-controller: starts the controller componentmake tofino-tcpreplay: starts packet replaying
This controller runs the inference in Python, not in the data plane of the switches.
It can be used with both eBPF and Tofino switches, just set CENTRALIZED=1 when running the commands.
Prior to starting the centralized controller, a pre-trained model must be created: make centralized-train.
This uses data exported by the regular controller component.
- Model encoding sometimes takes a very long time (e.g. even around 30 seconds): the NIKSS-CTL API is very slow.
- A flow started out as benign might become an attacker later. Currently, neither our dataset, nor our implementation supports this scenario.
There are some ideas that are worth noting, but are not yet planned for implementation.
- Direction-specific features: e.g. separate feature_count for client-to-server and server-to-client directions.
- Aggregate features: port or IP subnet-based features (e.g. average PPS per port).
- They should probably be exponential weighted moving averages to keep them relevant for long runtimes.
- Port-based features require changes to the simulation environment: the ingress IFs from PCAPs must be extracted.
- Start from a model trained on something, then replay a PCAP file that contains a different attack
- Trick to use multiple CICIDS days at once: replace the 1st byte in the IP addresses with the day's ordinal
- Calculate F1 score or accuracy based on correctly classified packets, not flows:
- This way the score would reflect how soon the flows get classified
- The oracle should use a random forest model instead of knowing the true labels of the dataset
- Convert an entire random forest into a single decision tree and encode that into a single match-action table
- There is literature on this random forest flattening, look into whether it causes the size of the trees to explode
- We don't need to save the exact certainty values either in this case: all we need to know is whether the certainty is above or below the threshold
- Resetting flow data (on flow timeout) could be explicitly synchronizes across switches
- The switch that adds the inference header determines whether the flow should be timed out
- It sets a flag in the inference header that indicating its decision
Random forest:
- pForest: In-Network Inference with Random Forests
- RF encoding method: 1 table per depth per tree
- IIsy: Practical In-Network Classification
- Source code
- RF encoding method: one table per feature + one table per tree
- Planter: Seeding Trees Within Switches
- Source code
- RF encoding method: one table per feature + one table per tree
- Supporting Large Random Forests in the Pipelines of a Hardware Switch to Classify Packets at 100 Gbps Line Rate
- RF encoding method: one table per tree
- SwitchTree: In-network Computing and Traffic Analyses with Random Forests
- Source code
- RF encoding method: one table per depth per tree
Distributed computing & in-network computing:
- DINC: Toward Distributed In-Network Computing
- Flightplan: Dataplane Disaggregation and Placement for P4 Programs
- SRA: Switch Resource Aggregation for Application Offloading in Programmable Networks
Federated learning: