Skip to content

Repository files navigation

bgp-rogue

CI

A containerised BGP prefix hijack detector. It streams historical BGP route announcements via pybgpstream and flags any origin AS that is not in your authorised list — a strong signal of a route hijack.

Demo


Background

BGP (Border Gateway Protocol) is the routing protocol that connects autonomous systems (ASes) on the internet. Because BGP has no built-in origin validation, a rogue AS can announce a prefix it does not own and attract traffic meant for the legitimate owner — a BGP hijack. This tool replays archived BGP update data from a RouteViews/RIPE RIS collector and reports every announcement where the origin AS was not the expected one.


Architecture

pybgpstream (CAIDA BGPStream API)
        │
        ▼
RouteViews collector (rrc00)
        │  BGP UPDATE messages (archived)
        ▼
 pybgpstream-print.py
        │
        ├─ for each UPDATE: extract origin AS from AS path
        │
        └─ origin AS ∉ authorized list?
                └─ YES → print "*** Potential Hijack ***"

The script chunks the review window into --interval-minute slices and processes each slice sequentially, printing progress as it goes. Only the rrc00 collector is used by default; this can be changed in the source.


Prerequisites

No local Python environment is required — all dependencies are bundled in the image.


Setup

docker build -t bgprogue .

Usage

docker run bgprogue \
  --prefix    <PREFIX> \
  --authorized-as <ASN> \
  --start     "YYYY-MM-DD HH:MM:SS" \
  --stop      "YYYY-MM-DD HH:MM:SS" \
  [--interval <MINUTES>]
Flag Required Description
--prefix Yes IP prefix to monitor. Repeatable for multiple prefixes.
--authorized-as Yes AS number authorised to announce the prefix. Repeatable.
--start Yes Start of the review window (YYYY-MM-DD HH:MM:SS).
--stop Yes End of the review window (YYYY-MM-DD HH:MM:SS).
--interval No Chunk size in minutes (default: 180).
--collector No BGP collector to query (repeatable, default: rrc00). See collector list.

Example — BGPStream event #251745

185.70.40.0/24 (owned by AS62371) was hijacked by AS1221 on 29 Sep 2020.

docker run bgprogue \
  --prefix 185.70.40.0/24 \
  --authorized-as 62371 \
  --start "2020-09-29 16:00:00" \
  --stop  "2020-09-29 18:59:59"

Expected output when a hijack is detected:

currently reviewing from 2020-09-29 16:00:00 UTC to 2020-09-29 19:00:00 UTC
Got Stream
Expected Announcement found: 185.70.40.0/24 - 1299 3356 1221 - 1221
*** Potential Hijack ***
 prefix 185.70.40.0/24 by as 1221

Discord Alerting

Set the DISCORD_WEBHOOK_URL environment variable to receive a message in a Discord channel whenever a potential hijack is detected:

docker run -e DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/YOUR/WEBHOOK bgprogue \
  --prefix 185.70.40.0/24 --authorized-as 62371 \
  --start "2020-09-29 16:00:00" --stop "2020-09-29 18:59:59"

See DEPLOYMENT.md for Docker Compose setup and webhook creation instructions.


Development

The project uses Ruff and Black for linting and formatting, enforced via pre-commit hooks (including Gitleaks for secret scanning).

python3 -m venv .venv && source .venv/bin/activate
pip install pre-commit
pre-commit install

Roadmap

# Status Description
1 ✅ Done Secret scan — confirmed no credentials in working tree or git history
2 ✅ Done Refactor: replace hardcoded event parameters with CLI arguments (argparse)
3 ✅ Done Tooling: Ruff, Black, Gitleaks pre-commit hooks, pyproject.toml
4 ✅ Done Documentation: professional README with architecture, usage, and roadmap
5 ✅ Done Pin Docker base image to a digest for reproducible builds
6 ✅ Done GitHub Actions CI workflow (lint + Docker build)
7 #1 Add unit tests for hijack detection logic
8 ✅ Done Support configurable collectors via --collector flag
#4 ✅ Done Discord webhook alerting on hijack detection (set DISCORD_WEBHOOK_URL)
#5 ✅ Done Containerised deployment guide (DEPLOYMENT.md)
#6 ✅ Done detect-secrets baseline and pre-commit hook
9 🔲 Planned ASN-to-org name enrichment — resolve origin AS to operator name via bgpview.io API for human-readable hijack alerts


Note: Claude was used to help uplift this older project for public release. Things should work, but in some cases I haven't been able to check end-to-end. PRs and fixes are very welcome.

License

GPL-3.0 License © incendiary

About

Containerised BGP prefix hijack detector using pybgpstream — flags route announcements from unexpected origin ASes

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages