Skip to content

Quick Start

Thomas Mangin edited this page Feb 2, 2026 · 11 revisions

Quick Start Guide

Get ExaBGP running in 5 minutes

ℹ️ Version Notice

  • ExaBGP 5.x (LTS - Recommended): Production-ready stable release. Python 3.8+. ACK enabled by default.
  • ExaBGP 6.0.0 (main - Development): Latest features (async reactor, shell completion, enhanced CLI). Python 3.12+ required. See 5.x β†’ 6.0.0 Migration.
  • ExaBGP 4.x (Maintenance): Critical fixes only. Consider migrating to 5.x.
  • Version 3.x: Deprecated. See 3.x β†’ 4.x Migration for upgrade guidance.

New users: Start with ExaBGP 5.x for production stability, or try 6.0.0 for latest features.


Table of Contents


What is ExaBGP?

ExaBGP is a pure BGP protocol implementation that allows you to control BGP route announcements programmatically. It's the BGP swiss army knife of networking.

πŸ”₯ Most Popular Use Case: Health-Check Based Routing

ExaBGP's killer feature is automatic route control based on service health:

  • Your application monitors its own health
  • When healthy β†’ announce route via BGP β†’ receive traffic
  • When failing β†’ withdraw route via BGP β†’ stop receiving traffic
  • No external monitoring needed - the application controls its own routing
  • Automatic failover - routers redirect traffic to healthy instances (5-15 seconds)

Other common use cases:

  • DDoS Mitigation via FlowSpec (pioneered open-source FlowSpec)
  • Anycast Management with automatic site failover
  • Load Balancing using BGP ECMP across healthy instances
  • Traffic Engineering and SDN integration
  • Network Automation with application-driven routing

Important: What ExaBGP Does NOT Do

⚠️ Critical Concept: ExaBGP does NOT manipulate the kernel routing table (RIB/FIB).

ExaBGP is a pure BGP protocol implementation. It speaks BGP to routers, but:

  • ❌ Does NOT install routes in the kernel
  • ❌ Does NOT forward packets
  • ❌ Is NOT a router

What it DOES:

  • βœ… Announces routes to BGP peers (routers install them)
  • βœ… Receives routes from BGP peers (your program processes them)
  • βœ… Provides a simple API (STDIN/STDOUT) for your programs to control BGP

Think of it as: Your application tells ExaBGP "announce this route" β†’ ExaBGP tells the router β†’ Router installs it and forwards traffic.


Installation

Option 1: pip (Recommended)

pip3 install exabgp

Option 2: From Source

git clone https://github.com/Exa-Networks/exabgp.git
cd exabgp
pip3 install -e .

Verify Installation

exabgp --version

You should see version 4.2.x or later.


Your First BGP Session

Let's create a simple configuration that announces a route to a BGP peer.

Step 1: Create Configuration File

Create /etc/exabgp/exabgp.conf:

# Minimal BGP configuration
neighbor 192.168.1.1 {
    router-id 192.168.1.2;
    local-address 192.168.1.2;
    local-as 65001;
    peer-as 65000;

    # Announce a static route
    static {
        route 100.10.0.0/24 next-hop 192.168.1.2;
    }
}

What this does:

  • Peers with router 192.168.1.1 (AS 65000)
  • Our router-id is 192.168.1.2 (AS 65001)
  • Announces 100.10.0.0/24 to the peer
  • The peer (router) will install this route and forward traffic to us

Step 2: Run ExaBGP

exabgp /etc/exabgp/exabgp.conf

You should see:

INFO:     Welcome to ExaBGP
INFO:     Established connection to 192.168.1.1

That's it! Your first BGP session is established and the route is announced.


Your First API Program

The real power of ExaBGP is the API - your programs control route announcements dynamically.

Use Case: High Availability with Health Checks

Announce a service IP only when the service is healthy. If the service fails, withdraw the route automatically.

Step 1: Create Health Check Script

Create /etc/exabgp/healthcheck.py:

#!/usr/bin/env python3
"""
Health check script: Announce route only when service is healthy
"""
import sys
import time
import socket

SERVICE_IP = "100.10.0.100"
SERVICE_PORT = 80
CHECK_INTERVAL = 5


def is_service_healthy():
    """Check if service is listening on port"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(2)
        result = sock.connect_ex((SERVICE_IP, SERVICE_PORT))
        sock.close()
        return result == 0
    except:
        return False


# Wait for ExaBGP to be ready
time.sleep(2)

announced = False

while True:
    if is_service_healthy():
        if not announced:
            # Announce route - service is UP
            sys.stdout.write(f"announce route {SERVICE_IP}/32 next-hop 192.0.2.1\n")
            sys.stdout.flush()
            announced = True
            sys.stderr.write(f"[HEALTHCHECK] Service UP - announced {SERVICE_IP}/32\n")
    else:
        if announced:
            # Withdraw route - service is DOWN
            sys.stdout.write(f"withdraw route {SERVICE_IP}/32\n")
            sys.stdout.flush()
            announced = False
            sys.stderr.write(f"[HEALTHCHECK] Service DOWN - withdrawn {SERVICE_IP}/32\n")

    time.sleep(CHECK_INTERVAL)

Make it executable:

chmod +x /etc/exabgp/healthcheck.py

Step 2: Update Configuration

Update /etc/exabgp/exabgp.conf:

neighbor 192.168.1.1 {
    router-id 192.168.1.2;
    local-address 192.168.1.2;
    local-as 65001;
    peer-as 65000;

    # API process - health check controls announcements
    api {
        processes [healthcheck];
    }
}

process healthcheck {
    run /etc/exabgp/healthcheck.py;
    encoder text;
}

Step 3: Run ExaBGP

exabgp /etc/exabgp/exabgp.conf

What happens:

  1. ExaBGP starts and launches healthcheck.py
  2. Health check script checks if service is listening on port 80
  3. If UP β†’ announces 100.10.0.100/32 to router
  4. If DOWN β†’ withdraws 100.10.0.100/32 from router
  5. Router automatically redirects traffic based on route presence

Result: Automatic high availability! If the service fails, the route is withdrawn and traffic goes elsewhere.

⭐ BETTER: Use Built-in Healthcheck Module (Zero Code Required!)

ExaBGP includes a production-ready healthcheck module - no custom script needed:

process watch-service {
    run python -m exabgp healthcheck \
        --cmd "nc -z 100.10.0.100 80" \
        --ip 100.10.0.100/32 \
        --rise 3 \
        --fall 2;
}

Built-in features:

  • βœ… Rise/fall dampening (avoid flapping)
  • βœ… Automatic IP address management
  • βœ… Syslog integration
  • βœ… Metric-based failover
  • βœ… Execution hooks for alerts
  • βœ… Configuration file support

See: Built-in Healthcheck Module for complete documentation.

Custom scripts (like above) are only needed for complex logic. For 90% of use cases, use the built-in module!


How the API Works

ExaBGP uses a simple STDIN/STDOUT API:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Your Program β”‚ STDOUT ────────→│ ExaBGP   β”‚
β”‚              β”‚                 β”‚          β”‚
β”‚ Python/Bash/ β”‚ STDIN  ←────────│ BGP      β”‚
β”‚ Any Language β”‚                 β”‚ Speaker  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚
                                       β”‚ BGP Protocol
                                       ↓
                                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                 β”‚ Router   β”‚
                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

To announce a route:

print("announce route 100.10.0.0/24 next-hop 192.0.2.1")

To withdraw a route:

print("withdraw route 100.10.0.0/24")

To receive updates from router:

for line in sys.stdin:
    # Process BGP updates from router
    message = json.loads(line)

That's it. No complex libraries. Any language that can read/write STDIN/STDOUT can control BGP.


Common Use Cases

1. DDoS Mitigation (FlowSpec)

Automatically block attack traffic by announcing FlowSpec rules:

# Block SYN flood from 10.0.0.0/8 to port 80
print("announce flow route { "
      "match { source 10.0.0.0/8; destination-port =80; tcp-flags [ syn ]; } "
      "then { discard; } "
      "}")

The router immediately drops matching packets. ExaBGP pioneered open-source FlowSpec (now also in GoBGP, FRRouting, BIRD).

2. Anycast Service Announcement

Multiple servers announce the same IP. Router uses ECMP to distribute load:

# Each server announces the same service IP
print("announce route 100.10.0.100/32 next-hop 192.0.2.1")

If one server fails (route withdrawn), traffic automatically goes to healthy servers.

3. Traffic Engineering

Control traffic paths with BGP communities and metrics:

# Prefer this path (lower MED)
print("announce route 100.10.0.0/24 next-hop 192.0.2.1 med 100")

# Backup path (higher MED)
print("announce route 100.10.0.0/24 next-hop 192.0.2.1 med 200")

Next Steps

πŸ“š Learn More

🎯 Explore Use Cases

πŸ”§ Dive Deeper

🌐 Community


Production Deployments

ExaBGP is battle-tested at scale:

  • Facebook/Meta: Katran L4 load balancer (billions of users)
  • Cloudflare: DDoS mitigation and anycast
  • Charter Communications: ISP routing automation
  • PowerDNS: Anycast DNS high availability

See Users for more production stories.


Quick Reference Card

Basic Commands

# Install
pip3 install exabgp

# Run with config
exabgp /etc/exabgp/exabgp.conf

# Run with debug
env exabgp.log.level=DEBUG exabgp /etc/exabgp/exabgp.conf

# Reload configuration (send SIGUSR1)
kill -USR1 $(pidof exabgp)

# Graceful restart (send SIGTERM)
kill -TERM $(pidof exabgp)

API Commands (print to STDOUT)

# IPv4 Unicast
print("announce route 100.10.0.0/24 next-hop 192.0.2.1")
print("withdraw route 100.10.0.0/24")

# IPv6 Unicast
print("announce route 2001:db8::/32 next-hop 2001:db8::1")

# FlowSpec
print("announce flow route { match { destination 100.10.0.0/24; } then { discard; } }")

# With attributes
print("announce route 100.10.0.0/24 next-hop 192.0.2.1 med 100 local-preference 200")
print("announce route 100.10.0.0/24 next-hop 192.0.2.1 community [65000:100]")

# Flush output (critical!)
sys.stdout.flush()

Troubleshooting

BGP Session Not Establishing

Check:

  1. Router can reach local-address
  2. router-id is set and unique
  3. Firewall allows TCP port 179
  4. AS numbers match router config

Debug:

env exabgp.log.level=DEBUG exabgp /etc/exabgp/exabgp.conf

Routes Not Announced

Check:

  1. Your program prints to STDOUT
  2. You call sys.stdout.flush() after each print
  3. ExaBGP log shows "announced route"
  4. Router's BGP table shows the route

Verify on router:

# Cisco
show ip bgp neighbor 192.168.1.2 received-routes

# Juniper
show route receive-protocol bgp 192.168.1.2

# FRRouting
show ip bgp neighbor 192.168.1.2 received-routes

API Program Not Starting

Check:

  1. Script is executable (chmod +x)
  2. Correct shebang (#!/usr/bin/env python3)
  3. ExaBGP log shows "process started"

Debug:

# Run script manually
/etc/exabgp/healthcheck.py

# Check ExaBGP log
tail -f /var/log/exabgp.log

Key Concepts Recap

βœ… ExaBGP is a BGP protocol speaker, NOT a router βœ… It does NOT install routes in the kernel βœ… Your program controls BGP via simple STDIN/STDOUT API βœ… Routers receive BGP updates and install routes βœ… Traffic flows based on router's routing decisions


Need help? Check the FAQ or ask on Slack.

Ready to learn more? Continue to Installation Guide β†’


πŸ‘» Ghost written by Claude (Anthropic AI)

Clone this wiki locally