Chapter 1: Introduction

Routelock is an intelligent BGP route optimization platform that automatically selects the best upstream carrier for every destination prefix based on real-time performance data, traffic patterns, and cost constraints.

What is Routelock?

If your network has two or more upstream transit providers, the default BGP best-path algorithm picks a single route based on static attributes like AS-path length and MED. It knows nothing about latency, packet loss, jitter, or actual traffic volume. Routelock fills that gap.

Routelock continuously collects NetFlow telemetry, actively probes destination prefixes, monitors BGP sessions via BIRD 2.x, and polls interfaces via SNMP. It feeds all of this into a weighted optimization engine that scores every prefix across every available provider and proposes (or automatically injects) better BGP routes.

🔍

Observe

Collect NetFlow, BGP RIB, SNMP counters, and active probe results in real time.

Analyze

Score every prefix across all providers using a weighted cost function (latency, loss, jitter, traffic, cost).

🛡

Protect

Detect DDoS attacks via baseline deviation, trigger RTBH/FlowSpec/XDP mitigations.

Optimize

Inject better routes into BIRD, shifting traffic to the optimal provider per prefix.

Who is Routelock for?

Architecture Overview

Routelock runs as a single Go binary with modular internal components. It communicates with BIRD 2.x over its Unix socket for BGP control, listens for NetFlow v9/IPFIX on UDP, runs ICMP/TCP/UDP probes, and queries routers via SNMP. All state is stored in TimescaleDB (PostgreSQL with time-series extensions).

+------------------+ | Web Browser | | (Dashboard/API) | +--------+---------+ | HTTPS :443 v +-------------+-------------+ | Routelock | | (Go Binary) | | | | +--------+ +---------+ | | | Web/API| |WebSocket| | | +--------+ +---------+ | | | | +--------+ +---------+ | | |Analysis| |Optimizer| | | +--------+ +---------+ | | | | +-------+ +------+ +----+ | | |NetFlow| |Probes| |SNMP| | | +---+---+ +--+---+ +-+--+ | | | | | | | +---+--------+--------+-+ | | | BGP (BIRD 2.x) | | | +-----------+-----------+ | +-------------|-------------+ | +-------------------+-------------------+ | | | +--------+------+ +--------+------+ +---------+-----+ | Transit A | | Transit B | | IX Peering | | (Full Table) | | (Full Table) | | (Partial) | +----------------+ +----------------+ +---------------+ Data Stores: +------------------+ +------------------+ | TimescaleDB | | BIRD RIB/FIB | | (metrics, flows, | | (BGP routes, | | events, config) | | injected paths) | +------------------+ +------------------+

Terminology Glossary

TermDefinition
ImprovementA proposed or applied route change: shifting a prefix from one provider to a better-scoring one.
ProviderAn upstream BGP neighbor (transit, partial-table, or IX peer) that Routelock can route traffic through.
Weight ScoreA 0-100 composite score combining latency, loss, jitter, throughput, and cost for a given prefix via a given provider.
BIRDThe BIRD Internet Routing Daemon (v2.x), which manages all BGP sessions and the routing table. Routelock controls BIRD to inject optimized routes.
RIBRouting Information Base. The full set of routes learned from BGP peers, stored in BIRD.
FIBForwarding Information Base. The active routes installed in the kernel, actually used for forwarding traffic.
NetFlowCisco telemetry protocol (v9/IPFIX) that exports per-flow traffic statistics from routers.
RTBHRemotely Triggered Black Hole. A DDoS mitigation technique that drops all traffic to a target IP by advertising a route to a null-route next-hop via BGP.
FlowSpecBGP Flow Specification. Allows distributing traffic filtering rules (by source, dest, port, protocol) via BGP to upstream routers.
XDPeXpress Data Path. A Linux kernel technology for high-performance packet filtering at the NIC driver level using eBPF programs.
MRDMulti-Routing Domain. Allows Routelock to manage separate BIRD instances and optimization policies for different network sites or segments.
Commit Control95th percentile traffic management to stay within carrier commit levels and avoid overage charges.
Maintenance WindowA scheduled time range during which Routelock pauses route optimization and optionally pre-withdraws routes from a specific provider.
AS-Path PrependA BGP technique to make a route appear longer, discouraging inbound traffic through that path. Used by Routelock for inbound optimization.

Chapter 2: Installation & Setup

This chapter walks through installing Routelock and its dependencies on a fresh Linux server.

System Requirements

ComponentMinimumRecommended
CPU4 cores8+ cores
RAM8 GB16+ GB
Disk50 GB SSD150+ GB NVMe
OSDebian 12 / Ubuntu 22.04Debian 12
NetworkReachable by routers (NetFlow UDP, BGP TCP)Dedicated management VLAN
Go1.22+1.23+
PostgreSQL1516
TimescaleDB2.14+2.16+
BIRD2.142.15+
Note Routelock manages full BGP tables (1.1M+ active routes). The RAM requirement is driven primarily by BIRD's in-memory RIB. Each full table peer consumes approximately 1–1.5 GB of RAM in BIRD.

Installing Dependencies

1. Go Compiler

bash
wget https://go.dev/dl/go1.23.4.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version

2. PostgreSQL & TimescaleDB

bash
# Install PostgreSQL 16
sudo apt install -y gnupg2 lsb-release
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \
  sudo tee /etc/apt/sources.list.d/pgdg.list
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update && sudo apt install -y postgresql-16

# Install TimescaleDB
echo "deb https://packagecloud.io/timescale/timescaledb/debian/ $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/timescaledb.list
wget -qO- https://packagecloud.io/timescale/timescaledb/gpgkey | sudo apt-key add -
sudo apt update && sudo apt install -y timescaledb-2-postgresql-16

# Tune PostgreSQL for TimescaleDB
sudo timescaledb-tune --yes
sudo systemctl restart postgresql

3. BIRD 2.x

bash
# From official BIRD repository (Debian/Ubuntu)
sudo apt install -y bird2

# Verify
birdc show status
Important Routelock manages BIRD's configuration files directly. Do not manually edit /etc/bird/bird.conf after initial setup. Routelock generates and reloads BIRD configuration through its BGP module.

4. Build Routelock

bash
git clone https://github.com/tzulo/routelock.git
cd routelock
go build -o routelock ./cmd/routelock
sudo cp routelock /usr/local/bin/

Database Setup

1

Create the database and user

sudo -u postgres psql <<'SQL'
CREATE USER routelock WITH PASSWORD 'your-secure-password-here';
CREATE DATABASE routelock OWNER routelock;
\c routelock
CREATE EXTENSION IF NOT EXISTS timescaledb;
SQL
2

Run migrations

Routelock handles schema migrations automatically on first startup. You can also run them manually:

routelock migrate up --config /etc/routelock/routelock.yaml

This creates all required tables, hypertables (for time-series data), continuous aggregates, and retention policies.

3

Verify the schema

sudo -u postgres psql -d routelock -c "\dt"

You should see tables including: providers, bgp_sessions, improvements, netflow_records, probe_results, ddos_events, users, api_keys, config, and more.

Initial Configuration

Create the main configuration file at /etc/routelock/routelock.yaml:

routelock.yaml
# Routelock Configuration
server:
  listen: ":443"
  tls_cert: "/etc/routelock/tls/cert.pem"
  tls_key: "/etc/routelock/tls/key.pem"

database:
  host: "localhost"
  port: 5432
  name: "routelock"
  user: "routelock"
  password: "your-secure-password-here"
  max_connections: 50

# Operating mode: test | human | robot
mode: "test"

netflow:
  listen: ":2055"            # UDP port for NetFlow v9/IPFIX
  workers: 4                 # Parallel decode workers

bgp:
  bird_socket: "/run/bird/bird.ctl"
  scan_interval: "60s"       # How often to read BIRD RIB
  local_as: 65000            # Your AS number

probes:
  enabled: true
  protocol: "icmp"           # icmp, tcp, udp
  interval: "60s"
  timeout: "3s"
  workers: 64
  targets_per_cycle: 5000

snmp:
  enabled: true
  interval: "60s"
  community: "public"

optimization:
  enabled: true
  interval: "300s"           # Run optimizer every 5 minutes
  min_improvement: 15        # Minimum score delta to propose a change
  weights:
    latency: 0.35
    loss: 0.30
    jitter: 0.15
    throughput: 0.10
    cost: 0.10

ddos:
  enabled: true
  baseline_window: "7d"
  detection_threshold: 5.0   # Multiplier over baseline
  severity_levels:
    warning: 3.0
    critical: 5.0
    emergency: 10.0

auth:
  jwt_secret: "generate-a-64-char-random-string"
  session_ttl: "24h"
  bcrypt_cost: 12

logging:
  level: "info"              # debug, info, warn, error
  format: "json"
  file: "/var/log/routelock/routelock.log"
Security Never commit your routelock.yaml to version control. It contains database passwords and JWT secrets. Use environment variable substitution (${DB_PASSWORD}) in production.

First Startup & Bootstrap Admin

1

Create required directories

sudo mkdir -p /etc/routelock/tls /var/log/routelock /var/lib/routelock
2

Generate a self-signed TLS certificate (for initial setup)

openssl req -x509 -newkey rsa:4096 -nodes \
  -keyout /etc/routelock/tls/key.pem \
  -out /etc/routelock/tls/cert.pem \
  -days 365 -subj "/CN=routelock.local"
3

Start Routelock

routelock serve --config /etc/routelock/routelock.yaml

On first startup, Routelock will:

  • Run pending database migrations
  • Generate a bootstrap admin account
  • Print the admin credentials to the log output
INFO  Bootstrap admin created
INFO    Username: admin
INFO    Password: aBc123-XyZ-RandomGenerated
INFO  ** Save this password -- it will not be shown again **
4

Install as a systemd service (recommended)

/etc/systemd/system/routelock.service
[Unit]
Description=Routelock BGP Route Optimization
After=network.target postgresql.service bird.service
Requires=postgresql.service

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/routelock serve --config /etc/routelock/routelock.yaml
Restart=always
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now routelock
5

Log in to the dashboard

Open your browser to https://your-server-ip/ and sign in with the bootstrap admin credentials. Change your password immediately under Settings → Profile.

Chapter 3: Operating Modes

Routelock has three operating modes that control whether route changes are observed, manually approved, or automatically applied. Start in Test mode and graduate to Robot mode only after you trust the system's decisions.

Test Mode

Test Mode

No routes are injected. No traffic is affected.

In Test mode, Routelock performs all data collection and analysis as normal:

However, nothing is applied to BIRD. All improvements are stored with status proposed and are visible on the Improvements page. DDoS mitigations are likewise stored as pending.

What you see in Test mode:

Use Test mode to validate that Routelock is seeing your network correctly and that its optimization proposals make sense before enabling any route injection.

Human Mode

Human Mode

Changes require manual approval before being applied.

Human mode adds an approval workflow. When the optimizer proposes an improvement or the DDoS engine detects an attack:

  1. The change is created with status pending
  2. A real-time notification is pushed to all connected dashboard users
  3. An operator reviews the change on the Improvements or DDoS page
  4. The operator clicks Approve or Reject
  5. If approved, Routelock injects the route into BIRD (or activates the DDoS mitigation)

Approval details shown for each improvement:

PrefixThe destination prefix being optimized (e.g., 203.0.113.0/24)
Current ProviderWhere traffic is currently routed
Proposed ProviderThe recommended better provider
Score DeltaHow much better the new route scores (e.g., +23 points)
LatencyOld vs. new latency (e.g., 45ms → 12ms)
LossOld vs. new packet loss
Traffic VolumeHow much traffic uses this prefix (helps prioritize)
Timeout Pending improvements expire after a configurable TTL (default: 30 minutes). If not approved in time, they are automatically marked expired and re-evaluated on the next optimization cycle.

Robot Mode

Robot Mode

Fully automated. Changes are applied immediately.

In Robot mode, Routelock operates autonomously:

Safety nets in Robot mode:

Switching Modes

Via Configuration File

Edit /etc/routelock/routelock.yaml:

mode: "human"   # test | human | robot

Then reload:

sudo systemctl reload routelock

Via API

curl -X PUT https://routelock.local/api/v1/config/mode \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "human"}'

Via Dashboard

Navigate to Settings → General and select the desired mode from the dropdown. The change takes effect immediately without a restart.

Note Switching from Robot to Human or Test mode does not withdraw already-injected routes. Existing optimizations remain active. Only new proposals will follow the new mode's workflow.

Recommended Progression

PhaseModeDurationWhat to validate
1Test1–2 weeksNetFlow data arriving, BGP sessions up, probe results sensible, proposed improvements look correct
2Human1–4 weeksApprove a few changes manually, verify traffic shifts correctly, confirm latency improvements, check provider commits
3RobotOngoingMonitor dashboard daily, review reports weekly, tune weights and thresholds as needed

Chapter 4: Dashboard & Navigation

The Routelock web interface provides real-time visibility into your network's routing, traffic, and security posture.

Login & Authentication

Navigate to https://your-server/ and you will be presented with the login page. Routelock supports multiple authentication methods:

MethodDescriptionConfiguration
LocalUsername + password stored in Routelock's database (bcrypt hashed)Always available
LDAP/ADAuthenticate against Active Directory or LDAP serverSettings → LDAP
SSO (OAuth2)Sign in with Google or Microsoft identity providersSettings → SSO
2FA (TOTP)Optional second factor using any TOTP app (Google Authenticator, Authy, etc.)Profile → Security

After entering credentials, if 2FA is enabled for the account, you will be prompted for a 6-digit code. Upon successful authentication, a JWT token is issued (stored as an HttpOnly cookie) and you are redirected to the dashboard.

Dashboard Overview

The main dashboard shows a real-time summary of your network:

KPI Cards (Top Row)

CardShows
Total TrafficCurrent aggregate throughput across all providers (Gbps)
Active PrefixesNumber of prefixes currently being optimized
Active ImprovementsNumber of route changes currently injected in BIRD
Avg LatencyWeighted average probe latency across all monitored prefixes
Packet LossWeighted average packet loss percentage
DDoS EventsNumber of currently active DDoS events (with severity indicator)

Provider Summary

Below the KPI cards, the provider summary table shows each upstream provider with:

Traffic Chart

A time-series chart at the bottom shows per-provider traffic over the selected time range (default: last 24 hours). You can toggle providers on/off, change the time range, and switch between bits/s and packets/s.

Sidebar Navigation

The left sidebar provides access to all sections of the application:

SectionPageDescription
OverviewDashboardMain KPI overview and provider summary
Traffic AnalysisTop prefixes, per-provider distribution, flow analysis
OptimizationImprovementsProposed and applied route changes
ProvidersConfigure and monitor upstream BGP providers
BGP SessionsBIRD BGP session status and details
SecurityDDoS EventsDetected attacks, mitigations, history
ScrubberXDP/eBPF scrubber rules and statistics
AlertsAll system and security alerts
AdminUsersUser accounts, roles, permissions
API KeysCreate and manage API keys
SettingsSystem configuration, LDAP, SSO, maintenance windows
ReportsTraffic, performance, cost, and security reports
LogsApplication log viewer with filtering

Real-Time Updates (WebSocket)

Routelock uses a WebSocket connection for live updates. When connected, you will see a small green dot indicator in the top-right corner of the header. Data that updates in real time:

If the WebSocket disconnects (network issue, server restart), the indicator turns red and the client automatically attempts reconnection with exponential backoff. During disconnection, the dashboard falls back to polling every 30 seconds.

Toast Notifications

Important events trigger toast notifications in the bottom-right corner:

ColorTypeExamples
BlueInfoNew improvement proposed, configuration changed
GreenSuccessImprovement applied, DDoS mitigation activated
YellowWarningBGP session flapping, provider near commit limit
RedError/CriticalDDoS detected, BGP session down, system error

Toast notifications auto-dismiss after 8 seconds. Click a notification to navigate to the relevant page. You can configure which notification types you receive in Profile → Notification Preferences.

Chapter 5: Network Optimization

This chapter covers how Routelock selects optimal routes and how you interact with its optimization decisions.

Managing Providers

Navigate to Optimization → Providers to view and manage upstream carriers. Click Add Provider to configure a new BGP neighbor.

Provider Types

TypeDescriptionTypical Use
TransitFull BGP table provider. Receives all ~900K+ IPv4 and ~200K+ IPv6 prefixes.Your primary upstream carriers (e.g., Lumen, Cogent, NTT)
PartialPartial table or default route. Receives a subset of prefixes from an upstream.Backup transits, regional carriers
IXInternet Exchange peering. Routes to specific peers at an IXP.Route servers, bilateral peers at your exchange point

Provider Configuration Fields

FieldDescription
NameHuman-readable name (e.g., "Cogent - Chicago")
ASNRemote AS number
TypeTransit, Partial, or IX
Neighbor IPBGP neighbor address (IPv4 or IPv6)
Local IPYour side of the BGP session
Commit (Mbps)Contracted bandwidth commit level for 95th percentile billing
Cost per MbpsCost factor used in the optimization weight calculation
Weight OverrideOptional: manually bias this provider's score (higher = preferred)
CommunitiesBGP communities to tag injected routes for this provider
SNMP TargetIP and interface index for SNMP traffic polling
EnabledWhether this provider participates in optimization

Understanding Improvements

An improvement is a proposed or applied route change. Routelock's optimization engine runs on a configurable interval (default: every 5 minutes) and evaluates every prefix that has both traffic and probe data across multiple providers.

How the Weight Score Works

For each prefix and each provider, Routelock computes a composite weight score from 0 to 100:

score = (latency_weight  x latency_score)  +
        (loss_weight     x loss_score)     +
        (jitter_weight   x jitter_score)   +
        (throughput_weight x throughput_score) +
        (cost_weight     x cost_score)

Default weights (configurable):
  latency:    0.35
  loss:       0.30
  jitter:     0.15
  throughput: 0.10
  cost:       0.10

Each sub-score is normalized to 0–100 where 100 is best. For example, the latency score is calculated as:

latency_score = max(0, 100 - (measured_latency_ms / target_latency_ms) * 100)

A route change is proposed when:

  1. The best alternative provider scores at least min_improvement points higher than the current provider (default: 15)
  2. The prefix has sufficient traffic to matter (configurable minimum traffic threshold)
  3. The destination has not been recently changed (flap dampening)

Improvement Statuses

StatusMeaning
ProposedGenerated in Test mode. No action will be taken.
PendingGenerated in Human mode. Awaiting operator approval.
AppliedRoute has been injected into BIRD. Traffic is flowing via the new provider.
RejectedOperator rejected this change in Human mode.
ExpiredPending improvement was not approved before the TTL.
WithdrawnPreviously applied route was withdrawn (provider recovered, maintenance, or manual).

Reviewing & Approving Improvements

Navigate to Optimization → Improvements. The table shows all improvements sorted by score delta (biggest improvements first).

Reviewing a pending improvement

Click on any improvement row to expand the detail panel. You will see:

Bulk actions

Select multiple improvements using checkboxes and use the bulk action buttons:

Tip Sort by the Traffic column to prioritize reviewing improvements for your highest-traffic prefixes first. A small latency improvement on a high-traffic prefix may have more impact than a large improvement on a low-traffic one.

Traffic Analysis

The Traffic Analysis page provides deep visibility into your NetFlow data:

Top Prefixes

Shows the top N prefixes by traffic volume with:

Provider Distribution

Pie and stacked-area charts showing how traffic is distributed across providers over time. Filter by:

Flow Details

Search for specific flows by source/destination IP, prefix, AS number, or port. Useful for troubleshooting routing for a specific destination.

BGP Session Monitoring

Navigate to Optimization → BGP Sessions to view the status of all BGP sessions managed by BIRD.

For each session, the page shows:

BGP Session Down When a BGP session goes down, Routelock immediately re-evaluates all prefixes that were using that provider and, in Robot/Human mode, proposes shifting traffic to alternative providers.

Inbound Optimization

Outbound optimization (controlling which provider you send traffic through) is Routelock's primary function. Inbound optimization (influencing how other networks send traffic to you) is an advanced feature that works differently:

Configure inbound optimization under Settings → Inbound Policy. This is an advanced feature and should be used with care, as changes affect how the entire internet routes traffic to your network.

Chapter 6: Security Operations

Routelock includes a comprehensive DDoS detection and mitigation system that works alongside its routing optimization.

DDoS Detection

Routelock detects DDoS attacks by analyzing NetFlow data against learned baselines:

How baselines work

  1. Learning period: Over a configurable window (default: 7 days), Routelock builds per-prefix traffic baselines: average bps, pps, flow count, and their standard deviations.
  2. Continuous comparison: Every NetFlow aggregation cycle (default: 60 seconds), current traffic is compared against the baseline.
  3. Threshold breach: If current traffic exceeds baseline_mean + (threshold_multiplier x baseline_stddev), an event is triggered.

Severity Levels

SeverityDefault MultiplierDescription
Warning3x baselineTraffic anomaly detected. Logged and visible on dashboard. No automatic action.
Critical5x baselineLikely DDoS. In Robot mode, RTBH is triggered. In Human mode, mitigation is proposed.
Emergency10x baselineMassive attack. In Robot mode, both RTBH and FlowSpec are activated. Alerts are sent to all configured channels.

Detection metrics

Reviewing Pending Mitigations

Navigate to Security → DDoS Events. Active and recent events are shown with:

Click on an event to see detailed analysis including:

Approving DDoS Rules

In Human mode, DDoS mitigations require manual approval. The approval dialog shows exactly what will happen:

RTBH (Remotely Triggered Black Hole)

# What Routelock will inject into BIRD:
route 203.0.113.5/32 blackhole {
    bgp_community.add((65535, 666));   # well-known blackhole community
};
Warning RTBH drops ALL traffic to the target IP, including legitimate traffic. Use it only when the target is completely overwhelmed and collateral damage is acceptable.

FlowSpec Rules

# Example FlowSpec rule distributed via BGP:
flow4 {
    dst 203.0.113.5/32;
    proto = 17;              # UDP
    dport = 53;              # DNS
    length >= 512;           # Large DNS responses (amplification)
};
then {
    rate-limit 10000;        # Limit to 10Kbps
};

FlowSpec is more surgical than RTBH: it can filter by protocol, port, packet size, and DSCP, and can rate-limit instead of dropping entirely.

Approval workflow

  1. Review the proposed rules on the DDoS event detail page
  2. Optionally modify parameters (e.g., change rate-limit value, adjust source filter)
  3. Click Approve Mitigation or Reject
  4. If approved, the rules are injected into BIRD and propagated to upstream routers via BGP
  5. Monitor the event timeline to see when traffic drops and the attack subsides

XDP/eBPF Scrubber

For attacks that need local scrubbing (when you want to keep the target online but filter malicious traffic), Routelock includes an XDP/eBPF-based scrubber.

Navigate to Security → Scrubber to manage scrubber rules:

Adding a scrubber rule

FieldDescription
NameDescriptive name for the rule
InterfaceNetwork interface to attach the XDP program to
Source CIDRSource IP range to match (or any)
Dest CIDRDestination IP range to match
ProtocolIP protocol (TCP, UDP, ICMP, or any)
Port RangeDestination port range
ActionDROP (discard), RATE_LIMIT (with pps/bps limit), or REDIRECT (to scrubbing VLAN)
PriorityRule evaluation order (lower = evaluated first)

XDP rules are applied at the NIC driver level, before the kernel networking stack, achieving line-rate filtering performance with minimal CPU overhead. The scrubber page shows real-time per-rule packet/byte counters and drop rates.

Alert Monitoring & Acknowledgment

Navigate to Security → Alerts to view all system and security alerts. Alerts are categorized by severity and source:

Operators can acknowledge alerts to indicate they have been seen and are being handled. Acknowledged alerts are filtered from the default view but remain in the history. Alerts can also be configured to send notifications via:

Chapter 7: Administration

Manage users, authentication, API access, and system configuration.

User Management

Navigate to Admin → Users. Routelock uses role-based access control (RBAC) with three built-in roles:

RolePermissions
AdminFull access. Can manage users, change system configuration, manage API keys, switch operating modes, and perform all operations.
OperatorCan approve/reject improvements and DDoS mitigations, acknowledge alerts, view all data, create maintenance windows. Cannot manage users or change system config.
ViewerRead-only access to the dashboard, improvements, DDoS events, reports, and traffic analysis. Cannot approve, reject, or modify anything.

Creating a user

  1. Click Add User
  2. Enter username, display name, email, and role
  3. Set an initial password (the user will be required to change it on first login)
  4. Optionally enable 2FA requirement for the account
  5. Click Create

Editing and deleting users

Click the edit icon next to any user to change their role, reset their password, or toggle their 2FA requirement. Click the delete icon to deactivate an account. Deactivated accounts are retained for audit logs but can no longer log in.

Important The bootstrap admin account cannot be deleted. There must always be at least one admin account. If you lock yourself out, use the CLI recovery command: routelock reset-admin --config /etc/routelock/routelock.yaml

API Key Management

Navigate to Admin → API Keys to create and manage API keys for programmatic access.

API keys provide an alternative to JWT tokens for automation, scripts, and integrations. Each key has:

API keys are shown only once at creation time. Store them securely. Use them via the X-API-Key header:

curl https://routelock.local/api/v1/providers \
  -H "X-API-Key: rl_live_abc123def456..."

LDAP/AD Configuration

Navigate to Settings → Authentication → LDAP to configure Active Directory or LDAP authentication.

Configuration fields

FieldExampleDescription
Server URLldaps://ad.company.com:636LDAP server address (use ldaps:// for TLS)
Bind DNCN=routelock,OU=Service,DC=company,DC=comService account DN for binding
Bind Password(stored encrypted)Service account password
Base DNOU=Users,DC=company,DC=comSearch base for user lookups
User Filter(sAMAccountName=%s)LDAP filter to find users (%s = username)
Admin GroupCN=NetAdmins,OU=Groups,DC=...LDAP group DN mapped to Admin role
Operator GroupCN=NOC,OU=Groups,DC=...LDAP group DN mapped to Operator role
Viewer GroupCN=NetEng,OU=Groups,DC=...LDAP group DN mapped to Viewer role

Click Test Connection to verify connectivity before saving. LDAP users are automatically provisioned on first login. Their role is determined by group membership.

SSO Setup (OAuth2/OIDC)

Navigate to Settings → Authentication → SSO to configure single sign-on via OAuth2/OpenID Connect.

Google SSO

  1. Create an OAuth2 client in the Google Cloud Console
  2. Set the redirect URI to https://routelock.local/auth/callback/google
  3. Enter the Client ID and Client Secret in Routelock
  4. Configure the allowed domain (e.g., company.com) to restrict which Google accounts can log in
  5. Map Google groups to Routelock roles

Microsoft SSO (Azure AD / Entra ID)

  1. Register an application in Azure AD
  2. Set the redirect URI to https://routelock.local/auth/callback/microsoft
  3. Enter the Tenant ID, Client ID, and Client Secret in Routelock
  4. Configure group-to-role mapping using Azure AD group Object IDs

When SSO is enabled, the login page shows "Sign in with Google" and/or "Sign in with Microsoft" buttons alongside the local login form. Local authentication always remains available as a fallback.

Two-Factor Authentication

Routelock supports TOTP-based two-factor authentication compatible with Google Authenticator, Authy, Microsoft Authenticator, and similar apps.

Enabling 2FA for your account

  1. Navigate to Profile → Security
  2. Click Enable Two-Factor Authentication
  3. Scan the QR code with your authenticator app
  4. Enter the 6-digit code displayed in the app to confirm
  5. Save the backup recovery codes securely (one-time use codes in case you lose access to your authenticator)

Enforcing 2FA

Admins can enforce 2FA for all accounts or specific roles under Settings → Authentication → 2FA Policy:

Configuration Management

Navigate to Settings → General to view and modify runtime configuration. Changes here take effect immediately without restarting Routelock.

Configurable parameters include:

All configuration changes are logged in the audit trail with the user who made the change, the old value, and the new value.

Maintenance Windows

Navigate to Settings → Maintenance Windows to schedule planned maintenance for providers.

Creating a maintenance window

  1. Click Schedule Maintenance
  2. Select the affected provider(s)
  3. Set start and end time (UTC)
  4. Choose the pre-drain period (default: 30 minutes before start). Routelock will begin shifting traffic away from the affected provider this long before the window starts.
  5. Set the behavior:
    • Withdraw All: Remove all optimized routes via this provider
    • Withdraw and Re-optimize: Withdraw routes and re-run the optimizer to find alternatives
    • Drain Only: Do not accept new optimizations for this provider but leave existing routes
  6. Optionally add notes (e.g., "Provider maintenance ticket #12345")

When the maintenance window ends, Routelock automatically includes the provider in the next optimization cycle. Routes will flow back to the provider if it offers the best path.

Recurring Windows You can create recurring maintenance windows (daily, weekly, monthly) for providers that have regular maintenance schedules. Configure these under the "Recurrence" tab when creating a window.

Chapter 8: Advanced Features

Advanced deployment scenarios for large or complex networks.

High Availability

Routelock supports an active-passive HA deployment. Both nodes share the same configuration and database.

Architecture

VIP: 10.10.5.100 | +--------+--------+ | | +----+----+ +----+----+ | Node A | | Node B | | Active | | Standby | | BIRD 2 | | BIRD 2 | +----+----+ +----+----+ | | +--------+---------+ | +------+------+ | TimescaleDB | | (shared) | +--------------+

Setup steps

  1. Shared database: Both nodes connect to the same TimescaleDB instance (or a PostgreSQL HA cluster)
  2. VIP management: Use keepalived or a similar tool to manage a floating VIP between the two nodes
  3. Configure HA in routelock.yaml:
routelock.yaml (HA section)
ha:
  enabled: true
  node_id: "node-a"         # Unique per node
  peer: "10.10.5.102:8443"  # The other node
  heartbeat_interval: "2s"
  failover_timeout: "10s"   # Promote standby after this silence
  vip: "10.10.5.100"
  vip_interface: "eth0"
  1. BIRD on both nodes: Both nodes run BIRD, but only the active node has its BGP sessions configured as enabled. On failover, the new active node reconfigures BIRD to bring up sessions.
  2. Failover behavior:
    • Active node sends heartbeats to standby via HTTPS
    • If standby doesn't receive a heartbeat for failover_timeout, it promotes itself
    • The new active node claims the VIP, enables BGP sessions in BIRD, and resumes optimization
    • When the original node recovers, it demotes itself to standby

Multi-Routing Domains

If you operate multiple sites, each with their own routers and upstream providers, you can manage them all from a single Routelock instance using Multi-Routing Domains (MRD).

Each routing domain has its own:

routelock.yaml (MRD section)
routing_domains:
  - name: "Chicago"
    bird_socket: "/run/bird/bird-chi.ctl"
    netflow_listen: ":2055"
    local_as: 65000

  - name: "Dallas"
    bird_socket: "/run/bird/bird-dal.ctl"
    netflow_listen: ":2056"
    local_as: 65000

  - name: "Ashburn"
    bird_socket: "/run/bird/bird-ash.ctl"
    netflow_listen: ":2057"
    local_as: 65000

The dashboard shows a domain selector in the header. All pages filter data by the selected domain. Reports can be generated per-domain or aggregated across all domains.

IX Peering Optimization

Internet Exchange (IX) peers are handled differently from transit providers:

Configuring IX preference

Provider settings (IX)
{
  "name": "DE-CIX Route Server",
  "type": "ix",
  "prefer_over_transit": true,
  "prefer_threshold": 10,     // Accept up to 10 points worse score vs transit
  "cost_factor": 0.0          // IX peering is usually settlement-free
}

Commit Control (95th Percentile)

Most transit providers bill based on the 95th percentile of traffic. Routelock tracks each provider's traffic against their commit level and can steer traffic to avoid overages.

How it works

  1. Routelock samples per-provider traffic every 5 minutes (via SNMP)
  2. It calculates the rolling 95th percentile for the current billing cycle (typically monthly)
  3. When a provider approaches its commit level (configurable threshold, default: 85%), the optimizer applies a cost penalty that discourages routing more traffic to that provider
  4. If a provider exceeds its commit, the penalty increases sharply, actively shifting traffic to cheaper or under-utilized providers

View commit utilization on the Dashboard (provider summary) or the Reports → Cost report.

Reports

Navigate to Admin → Reports to generate on-demand or scheduled reports.

ReportContents
OverviewExecutive summary: total traffic, improvements made, performance delta, DDoS events for the period
TrafficPer-provider traffic volume over time, peak vs. average, protocol distribution
PerformanceLatency, loss, and jitter improvements. Before-vs-after comparisons for optimized prefixes.
CostPer-provider 95th percentile, commit utilization, estimated cost savings from optimization
SecurityDDoS events summary, attack types, mitigation actions taken, time-to-mitigate

Reports can be exported as PDF or CSV. Schedule recurring reports (daily, weekly, monthly) to be emailed to specified recipients.

Chapter 9: API Reference Quick Start

Routelock exposes a RESTful JSON API at /api/v1/ for all operations available in the dashboard.

Authentication

Two authentication methods are supported:

1. Bearer Token (JWT)

Obtain a token by authenticating:

curl -X POST https://routelock.local/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-password"}'

# Response:
{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "expires_at": "2026-03-10T12:00:00Z",
  "user": {
    "id": 1,
    "username": "admin",
    "role": "admin"
  }
}

Use the token in subsequent requests:

curl https://routelock.local/api/v1/providers \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

2. API Key

curl https://routelock.local/api/v1/providers \
  -H "X-API-Key: rl_live_abc123..."

Common API Patterns

OperationMethodPattern
List resourcesGET/api/v1/{resource}?page=1&per_page=50
Get single resourceGET/api/v1/{resource}/{id}
Create resourcePOST/api/v1/{resource}
Update resourcePUT/api/v1/{resource}/{id}
Delete resourceDELETE/api/v1/{resource}/{id}

All list endpoints support pagination (page, per_page), sorting (sort=field&order=asc|desc), and filtering (filter[field]=value).

Response format

{
  "data": [ ... ],           // Array for lists, object for single
  "meta": {
    "page": 1,
    "per_page": 50,
    "total": 1247,
    "total_pages": 25
  }
}

Error format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid provider type",
    "details": {
      "field": "type",
      "allowed": ["transit", "partial", "ix"]
    }
  }
}

Example API Requests

List all providers

curl https://routelock.local/api/v1/providers \
  -H "Authorization: Bearer $TOKEN"

Create a provider

curl -X POST https://routelock.local/api/v1/providers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Cogent Chicago",
    "type": "transit",
    "asn": 174,
    "neighbor_ip": "198.51.100.1",
    "local_ip": "198.51.100.2",
    "commit_mbps": 10000,
    "enabled": true
  }'

List pending improvements

curl "https://routelock.local/api/v1/improvements?filter[status]=pending&sort=score_delta&order=desc" \
  -H "Authorization: Bearer $TOKEN"

Approve an improvement

curl -X PUT https://routelock.local/api/v1/improvements/42/approve \
  -H "Authorization: Bearer $TOKEN"

Get current DDoS events

curl "https://routelock.local/api/v1/ddos/events?filter[status]=active" \
  -H "Authorization: Bearer $TOKEN"

Switch operating mode

curl -X PUT https://routelock.local/api/v1/config/mode \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "robot"}'

Get system status

curl https://routelock.local/api/v1/status \
  -H "Authorization: Bearer $TOKEN"

# Response:
{
  "data": {
    "version": "1.0.0",
    "mode": "human",
    "uptime": "14d 6h 32m",
    "bgp_sessions": {"total": 5, "established": 5},
    "active_improvements": 847,
    "active_ddos_events": 0,
    "netflow": {"flows_per_sec": 12450},
    "probes": {"targets": 5000, "last_cycle": "2026-03-09T10:30:00Z"},
    "ha": {"role": "active", "peer_status": "connected"}
  }
}

WebSocket Connection

Connect to the real-time event stream:

// JavaScript example
const ws = new WebSocket('wss://routelock.local/api/v1/ws');

// Authenticate after connecting
ws.onopen = () => {
  ws.send(JSON.stringify({
    type: 'auth',
    token: 'eyJhbGciOiJIUzI1NiIs...'
  }));
};

// Subscribe to event channels
ws.onopen = () => {
  // After auth...
  ws.send(JSON.stringify({
    type: 'subscribe',
    channels: ['improvements', 'ddos', 'bgp', 'alerts', 'metrics']
  }));
};

// Receive events
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log(msg);
  // {
  //   "channel": "improvements",
  //   "event": "new",
  //   "data": {
  //     "id": 1234,
  //     "prefix": "203.0.113.0/24",
  //     "status": "pending",
  //     "score_delta": 27,
  //     ...
  //   }
  // }
};

WebSocket event types by channel

ChannelEvents
improvementsnew, approved, rejected, applied, withdrawn, expired
ddosdetected, mitigating, resolved
bgpsession_up, session_down, session_flap
alertsnew, acknowledged, resolved
metricsupdate (every 5 seconds with KPI data)

Chapter 10: Troubleshooting

Common issues and their solutions.

Common Startup Issues

Routelock fails to start: "database connection refused"

ERROR  Failed to connect to database: dial tcp 127.0.0.1:5432: connect: connection refused

Cause: PostgreSQL is not running or not listening on the configured port.

Fix:

# Check PostgreSQL status
sudo systemctl status postgresql

# If not running, start it
sudo systemctl start postgresql

# Verify it's listening
sudo ss -tlnp | grep 5432

Routelock fails to start: "TimescaleDB extension not found"

ERROR  Migration failed: extension "timescaledb" is not available

Cause: TimescaleDB is not installed, or shared_preload_libraries is not configured.

Fix:

# Verify TimescaleDB is in shared_preload_libraries
sudo grep shared_preload_libraries /etc/postgresql/16/main/postgresql.conf
# Should show: shared_preload_libraries = 'timescaledb'

# If missing, run the tuning script and restart
sudo timescaledb-tune --yes
sudo systemctl restart postgresql

Routelock fails to start: "bind: address already in use"

Cause: Another process is using port 443 (or the configured port).

Fix:

# Find what's using the port
sudo ss -tlnp | grep :443

# Stop the conflicting service, or change Routelock's listen port in routelock.yaml

Routelock fails to start: "BIRD socket not found"

ERROR  Cannot connect to BIRD socket: /run/bird/bird.ctl: no such file or directory

Cause: BIRD is not running or the socket path is wrong.

Fix:

# Check BIRD status
sudo systemctl status bird

# Verify socket exists
ls -la /run/bird/bird.ctl

# If BIRD is running but socket path differs, update routelock.yaml:
# bgp.bird_socket: "/var/run/bird/bird.ctl"

BGP Not Connecting

BGP session stuck in "Active" or "Connect" state

Common causes:

Diagnostic steps:

# Check BIRD's view of the session
sudo birdc show protocols all <provider_name>

# Check for TCP connectivity to the neighbor
sudo tcpdump -i eth0 port 179 -n

# Verify firewall rules
sudo iptables -L -n | grep 179

# Check BIRD logs
sudo journalctl -u bird --since "1 hour ago" | grep BGP

BGP session established but no prefixes received

Common causes:

# Check received routes
sudo birdc show route protocol <provider_name> count

# Check import filter rejections
sudo birdc show route protocol <provider_name> filtered count

NetFlow Not Receiving Data

No flows appearing in the dashboard

Diagnostic steps:

# 1. Verify Routelock is listening on the NetFlow port
sudo ss -ulnp | grep 2055

# 2. Check if packets are arriving
sudo tcpdump -i eth0 udp port 2055 -c 10

# 3. If no packets, check the router configuration:
#    - Verify the NetFlow exporter destination IP and port
#    - Ensure the router can reach Routelock's IP
#    - Check for firewall rules blocking UDP 2055

# 4. If packets arrive but flows don't appear, check Routelock logs:
sudo journalctl -u routelock | grep -i netflow

Common router-side issues

Probe Failures

High probe failure rate

Common causes:

# Test manual probe to verify connectivity
ping -c 5 8.8.8.8
traceroute 8.8.8.8

# Check probe logs
sudo journalctl -u routelock | grep -i probe

DDoS False Positives

Legitimate traffic flagged as DDoS

Common causes:

Tuning:

# Increase detection threshold (API)
curl -X PUT https://routelock.local/api/v1/config \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ddos": {
      "detection_threshold": 7.0,
      "severity_levels": {
        "warning": 5.0,
        "critical": 7.0,
        "emergency": 15.0
      }
    }
  }'

Adding a DDoS whitelist entry

Navigate to Settings → DDoS → Whitelist and add prefixes that should be excluded from detection (e.g., CDN prefixes, known bursty traffic sources).

Database Performance

Slow queries or high database CPU

Diagnostic steps:

# Check active queries
sudo -u postgres psql -d routelock -c "SELECT pid, now() - pg_stat_activity.query_start AS duration, query
FROM pg_stat_activity WHERE state = 'active' ORDER BY duration DESC LIMIT 10;"

# Check table sizes
sudo -u postgres psql -d routelock -c "SELECT hypertable_name, pg_size_pretty(hypertable_size(format('%I.%I', hypertable_schema, hypertable_name)::regclass))
FROM timescaledb_information.hypertables;"

# Check retention policies are working
sudo -u postgres psql -d routelock -c "SELECT * FROM timescaledb_information.jobs WHERE proc_name = 'policy_retention';"

Common fixes:

Log Analysis

Routelock outputs structured JSON logs. Key fields:

FieldDescription
levelDEBUG, INFO, WARN, ERROR
tsTimestamp (RFC 3339)
moduleSource module (netflow, bgp, probe, optimizer, ddos, api, web, store)
msgHuman-readable message
errError details (if applicable)

Useful log queries

# View errors in the last hour
sudo journalctl -u routelock --since "1 hour ago" | jq 'select(.level == "ERROR")'

# Filter by module
sudo journalctl -u routelock --since "1 hour ago" | jq 'select(.module == "bgp")'

# Watch optimization decisions in real time
sudo journalctl -u routelock -f | jq 'select(.module == "optimizer")'

# Find DDoS-related events
sudo journalctl -u routelock --since "24 hours ago" | jq 'select(.module == "ddos")'

The dashboard also provides a built-in log viewer at Admin → Logs with filtering by level, module, and time range.

Debug Mode To temporarily enable debug logging without restarting, use the API:
curl -X PUT https://routelock.local/api/v1/config/logging \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"level": "debug"}'
Remember to set it back to info when done, as debug logging is verbose and increases disk usage.

Routelock User Guide v1.0 — Last updated March 2026

Back to Dashboard · API Documentation