No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2025-11-12 22:26:40 -05:00
.gitea/workflows publish release 2025-11-12 22:26:40 -05:00
.gitignore More better 2025-11-12 20:47:44 -05:00
.goreleaser.yml publish release 2025-11-12 22:26:40 -05:00
cli.go Better 2025-11-12 21:30:35 -05:00
cli_test.go added tests 2025-11-12 22:10:08 -05:00
config.go docker bridge added 2025-11-12 21:52:10 -05:00
config_test.go added tests 2025-11-12 22:10:08 -05:00
go.mod retidy 2025-11-12 21:31:31 -05:00
go.sum retidy 2025-11-12 21:31:31 -05:00
main.go docker bridge added 2025-11-12 21:52:10 -05:00
main_test.go added tests 2025-11-12 22:10:08 -05:00
network.go docker bridge added 2025-11-12 21:52:10 -05:00
network_test.go added tests 2025-11-12 22:10:08 -05:00
README.md docker bridge added 2025-11-12 21:52:10 -05:00
tui.go Better 2025-11-12 21:30:35 -05:00
tui_test.go added tests 2025-11-12 22:10:08 -05:00

badNet - Network Impairment Simulator

A powerful network simulation tool for testing applications under adverse network conditions using Linux network namespaces and traffic control.


Project Overview

badNet is a network impairment simulation tool designed for testing and validating application behavior under various real-world network conditions. By leveraging Linux network namespaces and the Traffic Control (tc) subsystem with Network Emulation (netem), badNet creates isolated virtual network environments where you can simulate delays, packet loss, corruption, and other network anomalies.


System Architecture

High-Level Architecture

┌─────────────────────────────────────────────────────────────┐
│                        Host System                          │
│  ┌────────────────────────────────────────────────────────┐ │
│  │                   badNet Application                   │ │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │ │
│  │  │  TUI/CLI     │  │  Config      │  │  tc/netem    │  │ │
│  │  │  Interface   │  │  Manager     │  │  Controller  │  │ │
│  │  └──────────────┘  └──────────────┘  └──────────────┘  │ │
│  └────────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌─────────────────────┐          ┌─────────────────────┐   │
│  │  Client Namespace   │          │  Server Namespace   │   │
│  │  (client-ns)        │          │  (server-ns)        │   │
│  │                     │          │                     │   │
│  │  ┌──────────────┐   │  veth    │   ┌──────────────┐  │   │
│  │  │ veth-client  │◄──┼──────────┼──►│ veth-server  │  │   │
│  │  │ 10.99.0.1/24 │   │   pair   │   │ 10.99.0.2/24 │  │   │
│  │  └──────────────┘   │          │   └──────────────┘  │   │
│  │        ▲            │          │         ▲           │   │
│  │        │ tc netem   │          │         │ tc netem  │   │
│  │ (delay, loss, etc.) │          │ (delay, loss, etc.) │   │
│  └─────────────────────┘          └─────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

Technical Components

Network Namespaces: Linux kernel feature providing network stack isolation, including separate:

  • Network interfaces
  • Routing tables
  • Firewall rules
  • Network statistics

Virtual Ethernet (veth) Pairs: Simulated ethernet cables connecting the namespaces, acting as bidirectional pipes for network traffic.

Traffic Control (tc) + Network Emulation (netem): Linux kernel modules that apply quality-of-service rules to network interfaces, enabling precise control over packet behavior.

Data Flow

  1. Application starts and validates CAP_NET_ADMIN capability
  2. Configuration loaded from config.toml (or defaults generated)
  3. User selects operation via TUI or CLI
  4. Setup creates namespaces, veth pairs, assigns IPs, applies tc rules
  5. Network traffic flows through veth pair with applied impairments
  6. Teardown removes namespaces (automatically cleaning all resources)

Installation Guide

Prerequisites

⚠️ IMPORTANT: This tool requires Linux and specific kernel features. It will NOT work on macOS or Windows (even with WSL due to namespace limitations).

  • Operating System: Linux (kernel 2.6.24+ for network namespaces, 2.6.23+ for netem)
  • Go: Version 1.21 or higher
  • Root Access: Required for network namespace operations (sudo or CAP_NET_ADMIN capability)
  • Linux Utilities: ip and tc commands (from iproute2 package)

System Dependencies

Install required packages:

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install iproute2

# RHEL/CentOS/Fedora
sudo dnf install iproute

# Arch Linux
sudo pacman -S iproute2

Building from Source

# Clone the repository
git clone https://gitlab.star.army.mil/emsco/utils/badnet.git
cd badnet

# Download dependencies
go mod download

# Build the binary
go build -o badnet main.go

# Optional: Install system-wide
sudo cp badnet /usr/local/bin/

Granting Capabilities (Alternative to sudo)

For production environments, grant specific capabilities instead of requiring full root:

# Grant CAP_NET_ADMIN to the binary
sudo setcap cap_net_admin+ep ./badnet

# Verify capabilities
getcap ./badnet
# Output: ./badnet = cap_net_admin+ep

💡 Note: With capabilities set, you can run badNet without sudo while still maintaining security.


🚀 Usage Instructions

badNet offers two operational modes: an interactive Terminal User Interface (TUI) and command-line interface (CLI) for scripting.

Interactive TUI Mode

Launch the TUI by running badNet without arguments:

sudo ./badnet

TUI Controls:

  • ↑/↓ Arrow Keys: Navigate menu options
  • Enter: Select option
  • q or Ctrl+C: Quit (automatic cleanup)

Menu Options:

  1. Setup Network: Creates namespaces and applies network impairments
  2. Teardown Network: Removes all network configurations
  3. Quit: Exit application (auto-teardown if network is active)

CLI Mode

For automation and scripting:

Check Network Status

sudo ./badnet status

Example Output:

Network is ACTIVE
# or
Network is DOWN

Setup Network

sudo ./badnet up

Example Output:

Network setup completed successfully

Teardown Network

sudo ./badnet down

Example Output:

Network torn down successfully

Execute Commands in Namespaces

sudo ./badnet exec <client|server> <command> [args...]

Parameters:

  • <client|server>: Target namespace (client for client-ns, server for server-ns)
  • <command>: Command to execute in the namespace
  • [args...]: Optional arguments for the command

Example Usage:

# Ping from client to server
sudo ./badnet exec client ping -c 4 10.99.0.2

# Start HTTP server in server namespace
sudo ./badnet exec server python3 -m http.server 8080

# Run custom script in client namespace
sudo ./badnet exec client ./my_test_script.sh

Example Output:

# sudo ./badnet exec client ping -c 2 10.99.0.2
PING 10.99.0.2 (10.99.0.2) 56(84) bytes of data.
64 bytes from 10.99.0.2: icmp_seq=1 ttl=64 time=125 ms
64 bytes from 10.99.0.2: icmp_seq=2 ttl=64 time=98 ms

--- 10.99.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 98.123/111.567/125.012/13.444 ms

Testing the Network

Once the network is set up, you can test it by running commands in the namespaces:

Ping Test

# From client namespace to server
sudo ip netns exec client-ns ping -c 4 10.99.0.2

# From server namespace to client
sudo ip netns exec server-ns ping -c 4 10.99.0.1

Example Output with Impairments:

PING 10.99.0.2 (10.99.0.2) 56(84) bytes of data.
64 bytes from 10.99.0.2: icmp_seq=1 ttl=64 time=245 ms
64 bytes from 10.99.0.2: icmp_seq=2 ttl=64 time=132 ms
64 bytes from 10.99.0.2: icmp_seq=4 ttl=64 time=187 ms
(packet 3 lost due to 10% loss configuration)

Run Server in Namespace

# Start a simple HTTP server in server namespace
sudo ip netns exec server-ns python3 -m http.server 8080

Connect from Client Namespace

# Make HTTP request from client namespace
sudo ip netns exec client-ns curl http://10.99.0.2:8080

Docker Network Integration

badNet now supports integration with Docker networks by creating a bridge interface that can be used as a Docker network driver. This allows Docker containers to connect to the impaired network.

Setup Docker Network

After setting up badNet, create a Docker network using the bridge:

# Create Docker network using badNet bridge
sudo docker network create --driver bridge --opt com.docker.network.bridge.name=badnet-br badnet-network

# Or if you want to use a custom bridge name, update config.toml and recreate
sudo docker network create --driver bridge --opt com.docker.network.bridge.name=your-bridge-name your-network-name

Run Containers with Network Impairments

# Run a client container connected to the impaired network
sudo docker run --network badnet-network --name client-app -it ubuntu bash

# Run a server container connected to the impaired network
sudo docker run --network badnet-network --name server-app -p 8080:8080 -it ubuntu bash

# Inside containers, they will experience the network impairments configured in badNet

Example: Testing with Docker

# Setup badNet network
sudo ./badnet up

# Create Docker network
sudo docker network create --driver bridge --opt com.docker.network.bridge.name=badnet-br badnet-network

# Run server container
sudo docker run --network badnet-network --name server -d nginx

# Run client container and test connectivity
sudo docker run --network badnet-network --name client -it alpine sh -c "apk add curl && curl http://server"

# The curl command will experience the network impairments (delay, loss, etc.)

Using Docker Compose

You can also use Docker Compose to define services that connect to the impaired network:

# docker-compose.yml
version: '3.8'
services:
  server:
    image: nginx:alpine
    networks:
      - badnet
    ports:
      - "8080:80"

  client:
    image: alpine:latest
    networks:
      - badnet
    command: sh -c "apk add curl && sleep 5 && curl http://server"
    depends_on:
      - server

networks:
  badnet:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: badnet-br

Usage with Docker Compose:

# Setup badNet network first
sudo ./badnet up

# Run the services
sudo docker-compose up

# Or run in background
sudo docker-compose up -d

# View logs to see the impaired network effects
sudo docker-compose logs client

Cleanup Docker Network

# Stop and remove containers
sudo docker stop client server
sudo docker rm client server

# Or if using compose
sudo docker-compose down

# Remove Docker network
sudo docker network rm badnet-network

# Teardown badNet network
sudo ./badnet down

Automation Example

#!/bin/bash
# automated_test.sh

echo "Setting up impaired network..."
sudo ./badnet up

echo "Running application tests..."
# Your test commands here
sudo ip netns exec client-ns ./run_tests.sh

echo "Cleaning up..."
sudo ./badnet down

⚙️ Configuration Options

badNet uses TOML format for configuration. On first run, a default config.toml is automatically created.

Configuration File Location

The configuration file must be named config.toml and placed in the same directory as the badNet executable.

Complete Configuration Reference

# Network Namespace Names
client_ns = "client-ns"    # Name for client namespace
server_ns = "server-ns"    # Name for server namespace

# Virtual Ethernet Interface Names
client_veth = "veth-client"  # Client-side interface name
server_veth = "veth-server"  # Server-side interface name

# IP Address Configuration (CIDR notation)
client_ip = "10.99.0.1/24"   # Client IP and subnet
server_ip = "10.99.0.2/24"   # Server IP and subnet

# Bridge Configuration
bridge_name = "badnet-br"    # Bridge name for Docker network integration

# Network Impairment Configuration - Client Side
[netem_client]
delay = "100ms"              # Base latency (e.g., "50ms", "1s")
jitter = "20ms"              # Variance in delay (distribution)
loss = "10%"                 # Random packet loss percentage
loss_correlation = "25%"      # Correlation between packet losses
duplicate = "1%"             # Packet duplication rate
corrupt = "0.5%"             # Packet corruption rate
reorder = "5%"               # Packet reordering probability
reorder_correlation = "50%"   # Correlation in reordering

# Network Impairment Configuration - Server Side
[netem_server]
delay = "100ms"
jitter = "20ms"
loss = "10%"
loss_correlation = "25%"
duplicate = "1%"
corrupt = "0.5%"
reorder = "5%"
reorder_correlation = "50%"

Configuration Parameters Explained

Network Impairment Parameters

Parameter Type Description Example Values
delay Duration Base network latency "10ms", "100ms", "1s"
jitter Duration Variation in delay (normal distribution) "5ms", "20ms"
loss Percentage Random packet drop rate "0%", "5%", "25%"
loss_correlation Percentage Likelihood of consecutive losses "0%", "25%", "75%"
duplicate Percentage Packet duplication rate "0%", "1%", "5%"
corrupt Percentage Packet corruption rate "0%", "0.1%", "1%"
reorder Percentage Packet reordering probability "0%", "5%", "25%"
reorder_correlation Percentage Correlation in reorder events "0%", "50%", "100%"

Bridge Configuration

Parameter Type Description Example Values
bridge_name String Bridge interface name for Docker network integration "badnet-br", "docker-br"