Author: Samuel DeLaughter
License: MIT
This repository contains versions of the tools I developed for Denial-of-Service mitigation research during my PhD. It includes scripts for both generating and mitigating volumetric flooding attacks, as well as tools for automating the experimentation process. Automation tools assume the use of a Merge-based testbed like DeterLab, but files in the common
directory are general purpose, and should function across most Linux systems. The next section provides instructions for running experiments in Merge, with documentation for other utilities following.
This code is intended for research purposes only. Please use it responsibly.
These instructions assume you have already materialized an experiment in Merge, connected it to an XDC, and installed the Merge CLI on that XDC.
Anytime you create a new XDC, follow these steps to configure it:
- SSH to your XDC
cd /usr/local
- Run
sudo -E git clone git@github.com:sdelaughter/dos-mitigation.git
to clone this repository. You'll need sudo to write in/usr/local
, and the-E
flag will preserve your environment variables with sudo (including SSH keys). sudo chown -R $USER dos-mitigation
sudo chgrp -R $USER dos-mitigation
cd dos-mitigation
- Run
sudo ./xdc_setup.sh
to install dependencies. You will likely be prompted to enter your timezone.
Anytime you create a new materialization, follow these steps to configure it:
- SSH to your XDC
cd /usr/local/dos-mitigation
cp settings_template settings
- Update
settings
with your own credentials and testbed settings. At minimum you'll need to set the following:MRG_USER, MRG_PROJECT, MRG_EXPERIMENT, MRG_MATERIALIZATION
. If you have any bare metal (non-virtual) nodes in your materialization you must also setbare_metal=true
to ensure routes are properly configured. source settings
mrg config set server $MRG_SERVER
- Run
mrg login $MRG_USER
to login to the Merge testbed. Note that you will typically need to repeat this step each time you connect to the XDC, and at least once per day for long-running connections. - Run
./inventory_gen.sh
to build inventory files listing the devices in your network. - Run
./inventory_update.sh
to copy those inventory files and add extra variables. - Run
./play push_common
to push common files to testbed devices. If you ever add or modify files in thecommon
directory, you'll need to run this playbook again to propagate them to your nodes (for example, if you want to add a new attack type). - Run
./play depends
to install dependencies on testbed devices. This will take a considerable amount of time to run -- it needs to build OpenSSL from source in order to support HTTP3/QUIC.
Follow these steps when you want to run a set of experiments:
- SSH to your XDC
cd /usr/local/dos-mitigation
cp parameters_template.json parameters.json
(this step only needs to be done once, for future experiments, just continue editingparameters.json
as in the following step.)- Update
parameters.json
with the set of variables you want to test in a session of experiments. See the following section for an explanation of this file's formatting. - Run
mrg login [your Merge username]
to make sure you're logged in. - a) If your experiment uses network emulation to adjust loss, latency, or bandwidth on any links, try running
moacmd show
. There's a good chance you will get the following error:
rpc to moactld failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp: lookup moactl on 172.30.0.1:53: no such host"
If so, run: sudo ./moafix.sh
.
- b) If you're not using network emulation,
moacmd show
should give this error instead:
rpc to moactld failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 172.30.0.1:6006: connect: connection refused"
In this case, make sure parameters.json
includes the following three settings to prevent the associated moa commands from running:
"bottleneck_loss": [-1],
"bottleneck_latency": [-1],
"bottleneck_capacity": [-1],
- (Optional) Run
./play ping
to ensure that all devices in your network are up and able to reach the server. You can also run./play debug
to view more detailed information about each device. - Run
python3 ./run.py session_name
to run a set of experiments, wheresession_name
is some descriptive string. Results will be stored in/usr/local/dos-mitigation/logs/session_name
. Except when debugging, it's recommended to run this command viascreen
so that you can close the SSH session without disrupting long-running experiments, and return later to check on the results. So, runscreen python3 ./run.py session_name
to start experiments, then pressCtrl-A-D
to detach the screen and runscreen -r
to reattach it.
For each set of experiment parameters, as described above,run.py
will create a new temporary.settings
file, concatenatingsettings
and thehosts
inventory file (note that some additional settings are added viainventory_update.sh
-- in a future version these will hopefully be moved to the model file and captured automatically at inventory generation). Results for each experiment will be stored in a subdirectory of/usr/local/dos-mitigation/logs/session_name
, named with a timestamp indicating when that experiment began.
The general format of parameters.json
is a dictionary in which keys are parameter names and values are a list of list of corresponding parameter values. All possible combinations will be tested by run.py
, such that this dictionary...
{
"foo": [0, 1],
"bar": ["a", "b"]
}
...will result in four sets of experiments with the following settings:
foo=0, bar="a"
foo=0, bar="b"
foo=1, bar="a"
foo=1, bar="b"
The attack_mitigation_pair
key corresponds to a list of lists, in the form:
'attack_mitigation_pair': [
[attack_A, mitigation_X],
[attack_B, mitigation_Y]
]
Each attack/mitigation pair listed will be treated as a single parameter value to test in combination with the rest, as described above. The attack_mitigation_pair
parameter also supports an optional third value, to specify an alternate attack to be launched when the mitigation is deployed. If only two values are provided, the initial attack value will be used for both mitigated and unmitigated attacks. 2- and 3-value tuples can be freely interspersed, like so:
'attack_mitigation_pair': [
[attack_A, mitigation_X, attack_B],
[attack_B, mitigation_Y],
[attack_C, mitigation_Z, attack_A]
]
The code for our DoS mitigations is primarily split across the common/ebpf
and common/mitigations
directories. The former contains source code in eBPF-compatible C, while the latter contains shell scripts to simplify the process of compiling that source code and attaching the eBPF programs to network devices.
Adds a small proof-of-work to TCP SYN Packets
Adds a padding to TCP SYN Packets
These scripts pose a serious danger if not used with care -- they are to be used for research purposes only, in controlled environemnts. Even then, precautions must be taken to avoid flooding devices outside your control -- if using address-spoofing features, make sure response traffic is dropped rather than delivering it to the rightful address owners. When operating on DeterLab, run.py
will call playbooks\route_config.yml
, which configures devices to route outbound traffic (with public destination IPs) towards a Sink device where it is then dropped. Note that routining this attack backscatter through the network is important for maintaining realism in experimentation, but dropping it before it leaves the testbed is essential.