BGPv4 Adversarial Test Framework based on RFC 4271
Project description
BGP Adversarial Test Framework
A comprehensive adversarial testing framework for BGP v1 to v4 implementations based on RFC specifications.
Intended Use
This tool is designed as an RFC compliance testing utility for researchers and network engineers evaluating BGP implementation conformance. While it includes tests for security-related protocol behaviors, it is primarily intended to assist in compliance verification and protocol analysis rather than security auditing or penetration testing activities.
Caveat: This is an RFC compliance testing tool. It may assist security researchers in evaluating BGP implementations, but security assessment is not its primary purpose, and it is not intended for use in penetration testing activities.
Overview
This framework provides automated testing capabilities to identify vulnerabilities and protocol violations in BGPv4 implementations. It includes tests for:
- Message header validation (RFC 4271 Section 4.1, 6.1)
- OPEN message handling (RFC 4271 Section 4.2, 6.2)
- UPDATE message processing (RFC 4271 Section 4.3, 6.3)
- Path attribute validation (RFC 4271 Section 5)
- Finite State Machine behavior (RFC 4271 Section 8)
- Timing and Keepalive behavior (RFC 4271 Section 4.4, 10)
- Route aggregation (RFC 4271 Section 9.2.2)
- Decision process (RFC 4271 Section 9.1)
- Security considerations (RFC 4271 Section 6, RFC 4272)
Features
- Comprehensive Test Coverage: Tests based on RFC 4271 and RFC 4272 requirements
- Security Vulnerability Testing: Tests for BGP security attacks from RFC 4272
- Configurable Testing: YAML configuration for complex test scenarios
- Multiple Output Formats: JSON and YAML report generation
- Detailed Reporting: Pass/fail status with expected vs actual behavior
- Selective Test Execution: Run specific tests or categories
Installation
pip install -e .
Testing Setup
This framework requires a BGP peer to test against. Below are options for setting up a test environment.
Option 1: Containerlab (Recommended)
Containerlab provides a quick way to deploy containerized BGP routers:
# Install containerlab
curl -L https://containerlab.dev/install/ | bash
# Create topology file (topology.yml)
cat > topology.yml << 'EOF'
name: bgp_test
topology:
kinds:
linux:
image: frrouting/frr:latest
nodes:
router1:
kind: linux
image: frrouting/frr:latest
bgp:
as: 65001
neighbors:
- name: router2
as: 65002
router2:
kind: linux
image: frrouting/frr:latest
bgp:
as: 65002
neighbors:
- name: router1
as: 65001
links:
- endpoints: ["router1:eth1", "router2:eth1"]
EOF
# Deploy the lab
containerlab deploy -t topology.yml
# Get router IP
containerlab inspect -t topology.yml
# Test the framework
bgp-test --target <router_ip> --as-number 65001
# Destroy the lab when done
containerlab destroy -t topology.yml
Option 2: Docker Containers
# Run FRR container
docker run -d --name bgp-peer frrouting/frr:latest
# Enter the container and configure BGP
docker exec -it bgp-peer vtysh -c "configure terminal"
docker exec -it bgp-peer vtysh -c "router bgp 65001"
docker exec -it bgp-peer vtysh -c "neighbor 192.168.1.1 remote-as 65001"
docker exec -it bgp-peer vtysh -c "end"
docker exec -it bgp-peer vtysh -c "write memory"
# Get container IP
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' bgp-peer
# Test
bgp-test --target <container_ip> --as-number 65001
Option 3: System Packages (Linux)
# Install FRR or BIRD
sudo apt install frr # Debian/Ubuntu
sudo apt install bird # Alternative
# Configure FRR
sudo vtysh -c "configure terminal"
sudo vtysh -c "router bgp 65001"
sudo vtysh -c "neighbor 192.168.1.1 remote-as 65001"
sudo vtysh -c "end"
sudo vtysh -c "write memory"
# Test
bgp-test --target 127.0.0.1 --as-number 65001
Option 4: Virtual Machines
Download and install:
- FRR: https://frrouting.org/
- BIRD: https://bird.network.cz/
- Cisco CSR1000V: Commercial option
- Juniper vSRX: Commercial option
Quick Test Without a BGP Peer
Use the programmatic API to validate message generation:
from bgp_test_framework.api import BGPMessageBuilder, BGPParser
# Test message building
msg = BGPMessageBuilder.create_open(my_as=65001)
parsed = BGPParser.parse_header(msg)
print(f"Message type: {parsed['type']}")
# Test compliance scoring
from bgp_test_framework.api import BGPTestHarness, BGPTestConfig
config = BGPTestConfig(target_host="192.168.1.1", source_as=65001)
harness = BGPTestHarness(config)
tests = harness.get_all_tests("message_header")
print(f"Available tests: {len(tests)}")
Quick Start
Basic Usage
bgp-test --target 192.168.1.1 --as-number 65001
With Configuration File
bgp-test --config config.yaml
Run Specific Tests
bgp-test --target 192.168.1.1 --test-ids MH-001 MH-002 MH-003
Run Test Categories
bgp-test --target 192.168.1.1 --categories message_header open_message
Programmatic API
The framework provides a Python API for programmatic testing:
from bgp_test_framework.api import run_bgp_tests, BGPTestHarness, BGPTestConfig
# Quick start - run all tests
result = run_bgp_tests("192.168.1.1", 65001)
print(f"Compliance Score: {result['compliance_score']}%")
print(f"Grade: {result['compliance_grade']}")
# Run specific categories
result = run_bgp_tests(
"192.168.1.1",
65001,
categories=["message_header", "open_message"]
)
# Use the test harness for more control
config = BGPTestConfig(
target_host="192.168.1.1",
source_as=65001,
hold_time=180
)
harness = BGPTestHarness(config)
tests = harness.get_all_tests("message_header")
results = harness.run_category("message_header")
report = harness.get_compliance_report(results)
Message Builder API
Build BGP messages programmatically:
from bgp_test_framework.api import BGPMessageBuilder
# Build messages
open_msg = BGPMessageBuilder.create_open(my_as=65001, hold_time=180)
keepalive = BGPMessageBuilder.create_keepalive()
notification = BGPMessageBuilder.create_notification(1, 1)
route_refresh = BGPMessageBuilder.create_route_refresh(afi=1, safi=1)
# Build path attributes
origin = BGPMessageBuilder.create_origin_attribute("IGP")
as_path = BGPMessageBuilder.create_as_path_attribute([65001, 65002])
next_hop = BGPMessageBuilder.create_next_hop_attribute("192.168.1.1")
# Build multiprotocol attributes
mp_reach = BGPMessageBuilder.create_mp_reach(2, 1, b"\xc0\xa8\x01\x01", nlri)
originator_id = BGPMessageBuilder.create_originator_id(0x0A000001)
cluster_list = BGPMessageBuilder.create_cluster_list([1, 2, 3])
Command Line Options
| Option | Description |
|---|---|
--target, -t |
Target BGP peer IP address (required) |
--port, -p |
BGP port (default: 179) |
--as-number, -a |
Source AS number (default: 65001) |
--source-ip |
Source IP address |
--bgp-id |
BGP Identifier |
--hold-time |
Hold time in seconds (default: 180) |
--timeout |
Connection timeout (default: 5.0) |
--categories |
Test categories to run |
--test-ids |
Specific test IDs to run |
--config, -c |
YAML configuration file |
--output, -o |
Output file for results |
--format |
Output format (json/yaml) |
--verbose, -v |
Verbose output |
--debug, -d |
Debug output |
Test Categories
message_header
Tests for BGP message header validation per RFC 4271 Section 4.1 and 6.1:
- MH-001: Invalid Marker
- MH-003: Message Length Too Short
- MH-004: Message Length Too Large
- MH-006: Invalid Message Type
- MH-009: OPEN Message Length Too Short
- MH-010: UPDATE Message Length Too Short
- MH-011: KEEPALIVE Message Wrong Length
- MH-012: NOTIFICATION Message Length Too Short
graceful_restart
Tests for Graceful Restart per RFC 4724:
- GR-001: Graceful Restart Capability
- GR-002: Graceful Restart Timer
- GR-003: End-of-RIB Marker
- GR-004: Graceful Restart State
- GR-005: Graceful Restart AFI/SAFI
enhanced_route_refresh
Tests for Enhanced Route Refresh per RFC 7313:
- ERR-001: Enhanced Route Refresh Capability
- ERR-002: Outbound Route Refresh
- ERR-003: Inbound Route Refresh
- ERR-004: Route Refresh with ORF Prefix
- ERR-005: Route Refresh AFI/SAFI
extended_messages
Tests for Extended Message support per RFC 7606:
- EXT-001: Extended Message Capability
- EXT-002: Extended Message Size
- EXT-003: Message Length Overflow
- EXT-004: Extended Message Type
- EXT-005: Extended Keepalive
orf_filtering
Tests for Outbound Route Filtering per RFC 5291:
- ORF-001: ORF Capability
- ORF-002: ORF Send Receive
- ORF-003: ORF Prefix Filter
- ORF-004: ORF Route Refresh
- ORF-005: ORF Multiple Entries
dynamic_capability
Tests for Dynamic Capability per RFC 6724:
- DC-001: Dynamic Capability Advertisement
- DC-002: Capability Refresh
- DC-003: Unknown Capability
- DC-004: Capability Length Error
- DC-005: Multiple Capabilities
open_message
Tests for OPEN message handling per RFC 4271 Section 4.2 and 6.2:
- OP-001: Unsupported BGP Version
- OP-005: Hold Time One (MUST reject)
- OP-008: Invalid BGP Identifier - All Zeros
- OP-011: Unknown Optional Parameter
update_message
Tests for UPDATE message processing per RFC 4271 Section 4.3 and 6.3:
- UP-001: Missing ORIGIN Attribute
- UP-002: Missing AS_PATH Attribute
- UP-003: Missing NEXT_HOP Attribute
- UP-004: Invalid ORIGIN Value
- UP-005: Malformed AS_PATH
- UP-011: Attribute Length Mismatch
- UP-012: Duplicate Attribute
attribute
Tests for path attribute validation per RFC 4271 Section 5:
- ATTR-001: AS_PATH Loop Detection
- ATTR-005: LOCAL_PREF on EBGP
- ATTR-007: AGGREGATOR Invalid Length
fsm
Tests for Finite State Machine behavior per RFC 4271 Section 8:
- FSM-001: UPDATE in Idle State
- FSM-002: UPDATE in Connect State
- FSM-005: KEEPALIVE in Idle State
timing
Tests for timing behavior per RFC 4271 Section 10:
- TIM-001: Hold Timer Expiry
- TIM-002: KEEPALIVE Rate Limit
- TIM-003: Zero Hold Time No KEEPALIVE
security
Tests for security considerations per RFC 4271 Section 6:
- SEC-001: Connection Collision Detection
- SEC-002: BGP Identifier Collision
- SEC-006: TCP RST Injection
- SEC-008: AS_PATH Shortening Attack
- SEC-009: False Route Origination
- SEC-010: NEXT_HOP Manipulation
- SEC-011: ORIGIN Attribute Manipulation
- SEC-012: LOCAL_PREF Manipulation
- SEC-014: Route Withdrawal Replay
- SEC-016: ATOMIC_AGGREGATE Manipulation
- SEC-019: Invalid AS_PATH Leftmost AS
route_aggregation
Tests for route aggregation per RFC 4271 Section 9.2.2:
- AGG-001: AS_SET Sorting
- AGG-002: Aggregation Without AS_SET
- AGG-005: ATOMIC_AGGREGATE Restriction
- AGG-006: Complex AS_PATH Aggregation
decision_process
Tests for BGP decision process per RFC 4271 Section 9.1:
- DEC-001: Route Selection - Highest LOCAL_PREF
- DEC-002: Route Selection - Shortest AS_PATH
- DEC-003: Route Selection - ORIGIN Priority
- DEC-008: Route Resolvability
- DEC-010: AS_PATH with Own AS Loop
confederation
Tests for AS confederations per RFC 3065:
- CONFED-001: AS_CONFED_SEQUENCE Path Attribute
- CONFED-002: AS_CONFED_SET Path Attribute
- CONFED-003: Confederation Identifier Loop Detection
- CONFED-004: Member-AS Loop Detection
keepalive_message
Tests for KEEPALIVE message handling per RFC 4271 Section 4.4:
- KA-001: KEEPALIVE in Wrong State
- KA-002: KEEPALIVE Wrong Length
- KA-004: KEEPALIVE in Connect State
- KA-005: KEEPALIVE in OpenSent State
notification_message
Tests for NOTIFICATION message handling per RFC 4271 Section 4.5 and 6.4:
- NOT-001: NOTIFICATION in Idle State
- NOT-002: NOTIFICATION Message Too Short
- NOT-005: Cease Notification
version_negotiation
Tests for BGP version negotiation per RFC 4271 Section 7:
- VN-001: BGP Version 1
- VN-002: BGP Version 2
- VN-003: BGP Version 3
- VN-004: BGP Version 0
- VN-005: BGP Version 5 (Future)
connection_collision
Tests for BGP connection collision detection per RFC 4271 Section 6.8:
- COL-001: Simultaneous Connection Open
- COL-002: Same BGP Identifier
- COL-003: Higher BGP Identifier Wins
Configuration File
Example YAML configuration:
# Target configuration
target: "192.168.1.1"
port: 179
source_as: 65001
source_ip: "10.0.0.1"
bgp_id: "10.0.0.1"
hold_time: 180
timeout: 5.0
# Test selection
test_categories:
- message_header
- open_message
- update_message
test_ids:
- MH-001
- OP-001
# Test behavior
delay_between_tests: 0.5
retry_count: 1
# Output
output: "results.json"
format: "json"
verbose: true
debug: false
Output Format
JSON Output
{
"summary": {
"total": 50,
"passed": 45,
"failed": 5,
"pass_rate": "90.0%",
"target": "192.168.1.1:179",
"source_as": 65001,
"by_category": {
"message_header": {"total": 14, "passed": 14, "failed": 0},
"open_message": {"total": 15, "passed": 13, "failed": 2}
}
},
"results": [
{
"test_id": "MH-001",
"test_name": "Invalid Marker",
"category": "message_header",
"passed": true,
"expected_behavior": "Send OPEN with invalid marker",
"actual_behavior": "NOTIFICATION received: code=1, subcode=1"
}
]
}
Testing Considerations
Legal and Ethical Use
This framework is intended for:
- Security research and vulnerability assessment
- Protocol compliance testing
- Network device validation
- Educational purposes
WARNING: Only test systems you own or have explicit permission to test. Unauthorized testing may be illegal.
Test Prerequisites
- Network connectivity to target BGP peer
- Target BGP speaker must be reachable on TCP port 179
- No firewall blocking the connection
Development
Running Tests
# Unit tests
pytest tests/unit/
# Functional tests
pytest tests/functional/
# All tests
pytest tests/
Project Structure
bgp_test_framework/
├── src/bgp_test_framework/
│ ├── __init__.py
│ ├── constants.py # RFC 4271/4272 constants
│ ├── messages.py # BGP message parsing/building
│ ├── tests.py # Test case definitions (210+ tests)
│ ├── runner.py # Test execution engine
│ ├── api.py # Programmatic API
│ └── cli.py # CLI entry point
├── tests/
│ ├── unit/ # Unit tests
│ └── functional/ # Functional tests
├── examples/ # Example setups
│ ├── containerlab/ # Containerlab topology
│ ├── docker/ # Docker Compose setup
│ └── test_example.py # Python API example
├── RFCs/ # RFC specification documents
│ ├── rfc1105.txt # RFC 1105 (BGP v1, obsolete)
│ ├── rfc1163.txt # RFC 1163 (BGP-2, obsolete)
│ ├── rfc1267.txt # RFC 1267 (BGP-3, obsolete)
│ ├── rfc1771.txt # RFC 1771 (BGP-4, obsolete)
│ ├── rfc2918.txt # RFC 2918 (Route Refresh)
│ ├── rfc3065.txt # RFC 3065 (AS Confederations)
│ ├── rfc4271.txt # RFC 4271 (BGP-4)
│ └── rfc4272.txt # RFC 4272 (BGP Security)
├── config.yaml # Example configuration
├── pyproject.toml # Project configuration
└── README.md
References
- RFC 4271 - A Border Gateway Protocol 4 (BGP-4)
- RFC 4272 - BGP Security Vulnerabilities Analysis
- RFC 2918 - Route Refresh Capability for BGP-4
- RFC 3065 - Autonomous System Confederations for BGP
- RFC 4724 - Graceful Restart Mechanism for BGP
- RFC 7313 - Enhanced Route Refresh Capability for BGP-4
- RFC 4760 - Multiprotocol Extensions for BGP-4
- RFC 4456 - Route Reflection
- RFC 4893 - BGP Support for Four-Octet AS Number Space
- RFC 1105 - BGP (obsolete)
- RFC 1163 - BGP-2 (obsolete)
- RFC 1267 - BGP-3 (obsolete)
- RFC 1771 - BGP-4 (obsolete)
License
MIT License - See LICENSE file for details.
Contributing
Contributions are welcome. Please submit issues and pull requests on the project repository.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bgp_test_framework-0.1.0.2.tar.gz.
File metadata
- Download URL: bgp_test_framework-0.1.0.2.tar.gz
- Upload date:
- Size: 195.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54476dbdfe1f3c81624ec7485072b8f0e411597f2a83dde900d8f7fef082fea5
|
|
| MD5 |
719f841a5b54712653a3802715675cd8
|
|
| BLAKE2b-256 |
effbaf7e49434ee26fd070bbef5d7b5574703b4e5e71f3447be77ba3b3003c08
|
Provenance
The following attestation bundles were made for bgp_test_framework-0.1.0.2.tar.gz:
Publisher:
pypi-publish.yml on daedalus/bgp-test-framework
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bgp_test_framework-0.1.0.2.tar.gz -
Subject digest:
54476dbdfe1f3c81624ec7485072b8f0e411597f2a83dde900d8f7fef082fea5 - Sigstore transparency entry: 1154830920
- Sigstore integration time:
-
Permalink:
daedalus/bgp-test-framework@75e212c462621e15fd7bdc9fe814faee51dca3ec -
Branch / Tag:
refs/tags/v0.1.0.2 - Owner: https://github.com/daedalus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@75e212c462621e15fd7bdc9fe814faee51dca3ec -
Trigger Event:
release
-
Statement type:
File details
Details for the file bgp_test_framework-0.1.0.2-py3-none-any.whl.
File metadata
- Download URL: bgp_test_framework-0.1.0.2-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
225429f3792be52d126b38edc3cb925fdb9887fcab98d3b0c08a95155a17cb58
|
|
| MD5 |
6f177a06a752b93be23bb152fc0f73cd
|
|
| BLAKE2b-256 |
432be896de2c9fe0b2ed798bf39e0c70bab4627306d3e8e619e402187a792f41
|
Provenance
The following attestation bundles were made for bgp_test_framework-0.1.0.2-py3-none-any.whl:
Publisher:
pypi-publish.yml on daedalus/bgp-test-framework
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bgp_test_framework-0.1.0.2-py3-none-any.whl -
Subject digest:
225429f3792be52d126b38edc3cb925fdb9887fcab98d3b0c08a95155a17cb58 - Sigstore transparency entry: 1154830929
- Sigstore integration time:
-
Permalink:
daedalus/bgp-test-framework@75e212c462621e15fd7bdc9fe814faee51dca3ec -
Branch / Tag:
refs/tags/v0.1.0.2 - Owner: https://github.com/daedalus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@75e212c462621e15fd7bdc9fe814faee51dca3ec -
Trigger Event:
release
-
Statement type: