{"id":45154883,"url":"https://github.com/lance0/prefixd","last_synced_at":"2026-04-01T17:41:48.264Z","repository":{"id":335879124,"uuid":"1135772163","full_name":"lance0/prefixd","owner":"lance0","description":"BGP FlowSpec policy daemon for automated DDoS mitigation","archived":false,"fork":false,"pushed_at":"2026-03-20T01:10:18.000Z","size":2193,"stargazers_count":72,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-20T06:16:29.807Z","etag":null,"topics":["bgp","ddos","ddos-mitigation","fastnetmon","flowspec","gobgp","netops","network-automation","rust"],"latest_commit_sha":null,"homepage":"https://prefixd.io","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lance0.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"ko_fi":"lance0"}},"created_at":"2026-01-16T15:13:44.000Z","updated_at":"2026-03-20T01:10:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lance0/prefixd","commit_stats":null,"previous_names":["lance0/prefixd"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/lance0/prefixd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lance0%2Fprefixd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lance0%2Fprefixd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lance0%2Fprefixd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lance0%2Fprefixd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lance0","download_url":"https://codeload.github.com/lance0/prefixd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lance0%2Fprefixd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bgp","ddos","ddos-mitigation","fastnetmon","flowspec","gobgp","netops","network-automation","rust"],"created_at":"2026-02-20T04:02:38.376Z","updated_at":"2026-04-01T17:41:48.252Z","avatar_url":"https://github.com/lance0.png","language":"Rust","funding_links":["https://ko-fi.com/lance0"],"categories":[],"sub_categories":[],"readme":"# prefixd\n\n[![Build](https://github.com/lance0/prefixd/actions/workflows/ci.yml/badge.svg)](https://github.com/lance0/prefixd/actions/workflows/ci.yml)\n[![Rust](https://img.shields.io/badge/rust-1.85+-orange.svg)](https://www.rust-lang.org)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n**prefixd** is a BGP FlowSpec policy daemon for automated DDoS mitigation. It receives attack signals from detectors, applies policy-driven playbooks, and announces FlowSpec rules to routers via GoBGP.\n\n![Dashboard Overview](docs/images/dashboard-overview.png)\n\n---\n\n## Why prefixd?\n\nYou have detectors (FastNetMon, Kentik, Prometheus alerts) that know when you're under attack. You have routers (Juniper, Arista, Cisco) that can filter traffic at line rate with FlowSpec. But there's a gap:\n\n| Problem | Without prefixd | With prefixd |\n|---------|-----------------|--------------|\n| **Detector → Router** | Manual CLI or fragile scripts | Automated policy engine |\n| **Response time** | Minutes (operator intervention) | Seconds (API-driven) |\n| **Safety** | Easy to fat-finger, no guardrails | Quotas, safelist, /32-only, TTLs |\n| **Visibility** | Scattered logs, no audit trail | Dashboard, metrics, audit log |\n| **Expiry** | Forget to remove rules | Auto-expire via TTL |\n\n**Key idea:** Detectors signal intent, prefixd decides policy. No detector ever speaks BGP directly.\n\n```\nDetector ──► prefixd ──► GoBGP ──► Routers\n                │\n                ├── Policy Engine (playbooks)\n                ├── Guardrails (quotas, safelist)\n                └── Reconciliation (auto-expire)\n```\n\n---\n\n## Quick Start\n\n### 1. Clone and configure\n\n```bash\ngit clone https://github.com/lance0/prefixd.git\ncd prefixd\n```\n\n### 2. Start the stack\n\n```bash\ndocker compose up -d\n```\n\nThis starts 7 services:\n\n| Service | Purpose | Ports |\n|---------|---------|-------|\n| **nginx** | Reverse proxy (single entrypoint) | 80 |\n| **prefixd** | Policy daemon | internal |\n| **dashboard** | Web UI | internal |\n| **gobgp** | BGP route server | 179 (BGP) |\n| **postgres** | State storage | 5432 |\n| **prometheus** | Metrics storage | 9091 |\n| **grafana** | Monitoring dashboards | 3001 |\n\n### 3. Verify it's running\n\n```bash\n# Check all services are healthy\ndocker compose ps\n\n# Test the API\ncurl http://localhost/v1/health\n# {\"status\":\"ok\",\"version\":\"0.14.0\",\"auth_mode\":\"none\"}\n```\n\n### 4. Create an admin account\n\n```bash\ndocker compose exec prefixd prefixdctl operators create \\\n  --username admin --role admin\n# Enter password when prompted\n```\n\n### 5. Open the dashboard\n\n```bash\nopen http://localhost\n```\n\nLogin with the admin credentials you just created.\n\n### Troubleshooting\n\n```bash\n# View prefixd logs\ndocker compose logs prefixd\n\n# View GoBGP logs\ndocker compose logs gobgp\n\n# Restart everything\ndocker compose restart\n```\n\n**Common issues:**\n- Port 80 in use → Stop local web server or change nginx port in docker-compose.yml\n- Port 5432 in use → Stop local PostgreSQL or change port in docker-compose.yml\n- Port 179 in use → Another BGP daemon is running\n- \"connection refused\" → Wait a few seconds for services to start\n\n---\n\n## Next Steps\n\nOnce you have prefixd running locally:\n\n### 1. Configure your inventory\n\nEdit `configs/inventory.yaml` to map your IP space to customers:\n\n```yaml\ncustomers:\n  - customer_id: acme\n    name: \"ACME Corp\"\n    prefixes:\n      - \"203.0.113.0/24\"\n    services:\n      - service_id: dns\n        assets:\n          - ip: \"203.0.113.10\"\n        allowed_ports:\n          udp: [53]\n```\n\n### 2. Define playbooks\n\nEdit `configs/playbooks.yaml` to set response policies:\n\n```yaml\nplaybooks:\n  - name: udp_flood\n    match:\n      vector: udp_flood\n    steps:\n      - action: police\n        rate_bps: 10000000    # 10 Mbps\n        ttl_seconds: 120\n      - action: discard       # Escalate if attack persists\n        ttl_seconds: 300\n```\n\n### 3. Connect a detector\n\nPoint your detector at prefixd's API. Three integration paths:\n\n**Generic events API** (any detector):\n```bash\ncurl -X POST http://localhost/v1/events \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer $PREFIXD_API_TOKEN\" \\\n  -d '{\n    \"timestamp\": \"'\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"'\",\n    \"source\": \"fastnetmon\",\n    \"victim_ip\": \"203.0.113.10\",\n    \"vector\": \"udp_flood\",\n    \"bps\": 5000000000\n  }'\n```\n\n**Native adapters** (zero-config signal translation):\n- **Alertmanager** → `POST /v1/signals/alertmanager` — maps labels/annotations to events\n- **FastNetMon** → `POST /v1/signals/fastnetmon` — accepts native JSON payload\n\nWith [multi-signal correlation](docs/configuration.md#correlation) enabled, events from multiple detectors targeting the same IP are grouped and corroborated before triggering mitigation.\n\nSee [FastNetMon Integration](docs/detectors/fastnetmon.md) for a complete setup guide.\n\n### 4. Peer with your routers\n\nConfigure GoBGP neighbors in `configs/gobgp.conf` and set up FlowSpec import policies on your routers. See [Router Setup](docs/deployment.md#router-configuration).\n\n---\n\n## Features\n\n| Category | What it does |\n|----------|--------------|\n| **Signal Ingestion** | HTTP API + native Alertmanager and FastNetMon webhook adapters |\n| **Multi-Signal Correlation** | Time-windowed grouping of events from multiple detectors with source weighting and corroboration |\n| **Policy Engine** | YAML playbooks define per-vector responses with escalation |\n| **Guardrails** | Quotas, safelist, /32-only enforcement, mandatory TTLs |\n| **BGP FlowSpec** | Announces via GoBGP (traffic-rate, discard actions) |\n| **Reconciliation** | Auto-expires mitigations, repairs RIB drift every 30s |\n| **Dashboard** | Real-time web UI with WebSocket updates and toast notifications |\n| **Manual Mitigation** | \"Mitigate Now\" form for operator-initiated events |\n| **Authentication** | Three roles (admin, operator, viewer) with mode-aware auth (`none`, `bearer`, `credentials`, `mtls`) |\n| **Observability** | Prometheus metrics, Grafana dashboards, structured logs, audit trail |\n| **CLI** | `prefixdctl` for status, mitigations, safelist, config reload |\n\n---\n\n## How It Works\n\n1. **Detector sends event** → `POST /v1/events`, `/v1/signals/alertmanager`, or `/v1/signals/fastnetmon`\n2. **Inventory lookup** → Find customer/service owning the IP\n3. **Signal correlation** → Group related signals by (victim_ip, vector), check corroboration\n4. **Playbook match** → Determine action (police/discard) based on vector\n5. **Guardrails check** → Validate quotas, safelist, prefix length\n6. **FlowSpec announce** → Send rule to GoBGP via gRPC\n7. **Router enforcement** → Traffic filtered at line rate\n8. **Auto-expiry** → Rule withdrawn when TTL expires\n\n**Fail-open design:** If prefixd dies, mitigations auto-expire. No permanent rules, no stuck state.\n\n---\n\n## Documentation\n\n| Topic | Link |\n|-------|------|\n| Full deployment guide | [docs/deployment.md](docs/deployment.md) |\n| Configuration reference | [docs/configuration.md](docs/configuration.md) |\n| API reference | [docs/api.md](docs/api.md) |\n| CLI reference | [docs/cli.md](docs/cli.md) |\n| Router setup | [docs/deployment.md#router-configuration](docs/deployment.md#router-configuration) |\n| Grafana dashboards | [docs/grafana.md](docs/grafana.md) |\n| Architecture | [docs/architecture.md](docs/architecture.md) |\n\n---\n\n## Supported Routers\n\nFlowSpec (RFC 5575, RFC 8955) is supported by:\n\n| Vendor | Platform | Notes |\n|--------|----------|-------|\n| Juniper | MX, PTX, SRX | Full FlowSpec support |\n| Arista | 7xxx | EOS 4.20+ |\n| Cisco | IOS-XR | ASR 9000, NCS |\n| Nokia | SR OS | 19.x+ |\n\n---\n\n## Requirements\n\n- **Docker** (recommended) or Rust 1.85+ for building from source\n- **PostgreSQL 14+** for state storage\n- **GoBGP** is included in Docker Compose\n\n---\n\n## Upgrading\n\nDatabase migrations run automatically on startup. See **[docs/upgrading.md](docs/upgrading.md)** for version-specific notes.\n\n\u003e **v0.12.0 breaking change:** Offset-based pagination (`?offset=N`) has been removed from all list endpoints. Use cursor-based pagination instead (`?cursor=\u003copaque\u003e\u0026limit=N`). If you have scripts or integrations using `--offset` or `?offset=`, they must be updated. See [ADR 016](docs/adr/016-cursor-pagination.md) for rationale and [upgrading.md](docs/upgrading.md) for migration examples.\n\n---\n\n## Project Status\n\nCurrent version: **v0.14.0**\n\n- Core functionality stable and tested\n- Real-time dashboard with WebSocket updates, toast notifications, and mitigation detail views\n- Full operator workflow: manual mitigation, withdraw, safelist management, config browsing\n- API may change before v1.0\n- See [ROADMAP.md](ROADMAP.md) for planned features\n\n---\n\n## Community\n\n- **Issues:** [GitHub Issues](https://github.com/lance0/prefixd/issues)\n- **Contributing:** [CONTRIBUTING.md](CONTRIBUTING.md)\n- **Architecture Decision Records:** [docs/adr/](docs/adr/) (19 ADRs)\n\n---\n\n## License\n\nMIT - See [LICENSE](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flance0%2Fprefixd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flance0%2Fprefixd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flance0%2Fprefixd/lists"}