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?
- Network engineers managing multi-homed networks with 2+ transit providers
- NOC operators who need real-time visibility into routing decisions and DDoS events
- Network architects designing peering strategies, IX participation, and commit management
- ISPs and hosting providers with full BGP tables (1M+ prefixes) and high traffic volumes
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).
Terminology Glossary
| Term | Definition |
|---|---|
Improvement | A proposed or applied route change: shifting a prefix from one provider to a better-scoring one. |
Provider | An upstream BGP neighbor (transit, partial-table, or IX peer) that Routelock can route traffic through. |
Weight Score | A 0-100 composite score combining latency, loss, jitter, throughput, and cost for a given prefix via a given provider. |
BIRD | The BIRD Internet Routing Daemon (v2.x), which manages all BGP sessions and the routing table. Routelock controls BIRD to inject optimized routes. |
RIB | Routing Information Base. The full set of routes learned from BGP peers, stored in BIRD. |
FIB | Forwarding Information Base. The active routes installed in the kernel, actually used for forwarding traffic. |
NetFlow | Cisco telemetry protocol (v9/IPFIX) that exports per-flow traffic statistics from routers. |
RTBH | Remotely 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. |
FlowSpec | BGP Flow Specification. Allows distributing traffic filtering rules (by source, dest, port, protocol) via BGP to upstream routers. |
XDP | eXpress Data Path. A Linux kernel technology for high-performance packet filtering at the NIC driver level using eBPF programs. |
MRD | Multi-Routing Domain. Allows Routelock to manage separate BIRD instances and optimization policies for different network sites or segments. |
Commit Control | 95th percentile traffic management to stay within carrier commit levels and avoid overage charges. |
Maintenance Window | A scheduled time range during which Routelock pauses route optimization and optionally pre-withdraws routes from a specific provider. |
AS-Path Prepend | A 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
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 4 cores | 8+ cores |
| RAM | 8 GB | 16+ GB |
| Disk | 50 GB SSD | 150+ GB NVMe |
| OS | Debian 12 / Ubuntu 22.04 | Debian 12 |
| Network | Reachable by routers (NetFlow UDP, BGP TCP) | Dedicated management VLAN |
| Go | 1.22+ | 1.23+ |
| PostgreSQL | 15 | 16 |
| TimescaleDB | 2.14+ | 2.16+ |
| BIRD | 2.14 | 2.15+ |
Installing Dependencies
1. Go Compiler
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
# 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
# From official BIRD repository (Debian/Ubuntu)
sudo apt install -y bird2
# Verify
birdc show status
/etc/bird/bird.conf after initial setup. Routelock generates and reloads BIRD configuration through its BGP module.
4. Build Routelock
git clone https://github.com/tzulo/routelock.git
cd routelock
go build -o routelock ./cmd/routelock
sudo cp routelock /usr/local/bin/
Database Setup
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
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.
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 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"
routelock.yaml to version control. It contains database passwords and JWT secrets. Use environment variable substitution (${DB_PASSWORD}) in production.
First Startup & Bootstrap Admin
Create required directories
sudo mkdir -p /etc/routelock/tls /var/log/routelock /var/lib/routelock
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"
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 **
Install as a systemd service (recommended)
[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
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
No routes are injected. No traffic is affected.
In Test mode, Routelock performs all data collection and analysis as normal:
- Collects NetFlow data and builds per-prefix traffic profiles
- Probes destination prefixes across all providers
- Runs the optimization engine and generates proposed improvements
- Detects DDoS events and generates proposed mitigations
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:
- Dashboard: All KPI cards update normally (traffic rates, provider distribution, probe results). The mode badge shows TEST.
- Improvements page: Proposed route changes appear with their weight scores, showing current provider vs. recommended provider and the expected improvement delta.
- DDoS page: Detected events appear with severity and proposed mitigation type, but no action is taken.
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
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:
- The change is created with status
pending - A real-time notification is pushed to all connected dashboard users
- An operator reviews the change on the Improvements or DDoS page
- The operator clicks Approve or Reject
- If approved, Routelock injects the route into BIRD (or activates the DDoS mitigation)
Approval details shown for each improvement:
| Prefix | The destination prefix being optimized (e.g., 203.0.113.0/24) |
| Current Provider | Where traffic is currently routed |
| Proposed Provider | The recommended better provider |
| Score Delta | How much better the new route scores (e.g., +23 points) |
| Latency | Old vs. new latency (e.g., 45ms → 12ms) |
| Loss | Old vs. new packet loss |
| Traffic Volume | How much traffic uses this prefix (helps prioritize) |
expired and re-evaluated on the next optimization cycle.
Robot Mode
Fully automated. Changes are applied immediately.
In Robot mode, Routelock operates autonomously:
- Optimization improvements are applied to BIRD as soon as they are generated
- DDoS mitigations are activated immediately upon detection
- Route withdrawals happen automatically when a provider recovers or maintenance windows end
Safety nets in Robot mode:
- Minimum improvement threshold: Only changes exceeding the configured score delta (default: 15 points) are applied
- Rate limiting: Maximum number of route changes per minute (configurable, default: 50)
- Flap detection: If a prefix bounces between providers more than 3 times in 10 minutes, it is locked to its current provider for 1 hour
- Provider health checks: If a provider's BGP session goes down, all routes are immediately re-evaluated
- Maintenance windows: Automatic route withdrawal before scheduled maintenance
- Rollback: If bulk route injection causes provider traffic to spike beyond its commit level, changes are automatically rolled back
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.
Recommended Progression
| Phase | Mode | Duration | What to validate |
|---|---|---|---|
| 1 | Test | 1–2 weeks | NetFlow data arriving, BGP sessions up, probe results sensible, proposed improvements look correct |
| 2 | Human | 1–4 weeks | Approve a few changes manually, verify traffic shifts correctly, confirm latency improvements, check provider commits |
| 3 | Robot | Ongoing | Monitor 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:
| Method | Description | Configuration |
|---|---|---|
| Local | Username + password stored in Routelock's database (bcrypt hashed) | Always available |
| LDAP/AD | Authenticate against Active Directory or LDAP server | Settings → LDAP |
| SSO (OAuth2) | Sign in with Google or Microsoft identity providers | Settings → 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)
| Card | Shows |
|---|---|
| Total Traffic | Current aggregate throughput across all providers (Gbps) |
| Active Prefixes | Number of prefixes currently being optimized |
| Active Improvements | Number of route changes currently injected in BIRD |
| Avg Latency | Weighted average probe latency across all monitored prefixes |
| Packet Loss | Weighted average packet loss percentage |
| DDoS Events | Number of currently active DDoS events (with severity indicator) |
Provider Summary
Below the KPI cards, the provider summary table shows each upstream provider with:
- BGP session status (green dot = Established, red = Down)
- Current traffic in/out (Gbps)
- Number of received/advertised prefixes
- Average latency and loss for prefixes using that provider
- Commit utilization (percentage of 95th percentile commit used)
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:
| Section | Page | Description |
|---|---|---|
| Overview | Dashboard | Main KPI overview and provider summary |
| Traffic Analysis | Top prefixes, per-provider distribution, flow analysis | |
| Optimization | Improvements | Proposed and applied route changes |
| Providers | Configure and monitor upstream BGP providers | |
| BGP Sessions | BIRD BGP session status and details | |
| Security | DDoS Events | Detected attacks, mitigations, history |
| Scrubber | XDP/eBPF scrubber rules and statistics | |
| Alerts | All system and security alerts | |
| Admin | Users | User accounts, roles, permissions |
| API Keys | Create and manage API keys | |
| Settings | System configuration, LDAP, SSO, maintenance windows | |
| Reports | Traffic, performance, cost, and security reports | |
| Logs | Application 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:
- KPI card values refresh every 5 seconds
- Traffic charts update with new data points
- New improvements and DDoS events appear instantly
- BGP session state changes are reflected immediately
- Provider status transitions are shown 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:
| Color | Type | Examples |
|---|---|---|
| Blue | Info | New improvement proposed, configuration changed |
| Green | Success | Improvement applied, DDoS mitigation activated |
| Yellow | Warning | BGP session flapping, provider near commit limit |
| Red | Error/Critical | DDoS 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
| Type | Description | Typical Use |
|---|---|---|
| Transit | Full BGP table provider. Receives all ~900K+ IPv4 and ~200K+ IPv6 prefixes. | Your primary upstream carriers (e.g., Lumen, Cogent, NTT) |
| Partial | Partial table or default route. Receives a subset of prefixes from an upstream. | Backup transits, regional carriers |
| IX | Internet Exchange peering. Routes to specific peers at an IXP. | Route servers, bilateral peers at your exchange point |
Provider Configuration Fields
| Field | Description |
|---|---|
Name | Human-readable name (e.g., "Cogent - Chicago") |
ASN | Remote AS number |
Type | Transit, Partial, or IX |
Neighbor IP | BGP neighbor address (IPv4 or IPv6) |
Local IP | Your side of the BGP session |
Commit (Mbps) | Contracted bandwidth commit level for 95th percentile billing |
Cost per Mbps | Cost factor used in the optimization weight calculation |
Weight Override | Optional: manually bias this provider's score (higher = preferred) |
Communities | BGP communities to tag injected routes for this provider |
SNMP Target | IP and interface index for SNMP traffic polling |
Enabled | Whether 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:
- The best alternative provider scores at least
min_improvementpoints higher than the current provider (default: 15) - The prefix has sufficient traffic to matter (configurable minimum traffic threshold)
- The destination has not been recently changed (flap dampening)
Improvement Statuses
| Status | Meaning |
|---|---|
| Proposed | Generated in Test mode. No action will be taken. |
| Pending | Generated in Human mode. Awaiting operator approval. |
| Applied | Route has been injected into BIRD. Traffic is flowing via the new provider. |
| Rejected | Operator rejected this change in Human mode. |
| Expired | Pending improvement was not approved before the TTL. |
| Withdrawn | Previously 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:
- Prefix details: CIDR, origin AS, traffic volume (bps/pps)
- Current route: Provider name, AS path, latency, loss, jitter, score
- Proposed route: Provider name, AS path, latency, loss, jitter, score
- Score comparison: Side-by-side bar chart showing old vs. new score breakdown
- Historical probes: Time-series chart of latency/loss for both providers over the last 24 hours
Bulk actions
Select multiple improvements using checkboxes and use the bulk action buttons:
- Approve Selected: Apply all selected improvements at once
- Reject Selected: Reject all selected improvements
- Approve All Pending: Apply every pending improvement (use with caution)
Traffic Analysis
The Traffic Analysis page provides deep visibility into your NetFlow data:
Top Prefixes
Shows the top N prefixes by traffic volume with:
- Current provider and whether it is the optimal provider
- Bits/s and packets/s
- Country and AS name (via BGP origin lookup)
- Optimization status (optimized, suboptimal, pending)
Provider Distribution
Pie and stacked-area charts showing how traffic is distributed across providers over time. Filter by:
- Time range (1h, 6h, 24h, 7d, 30d, custom)
- Direction (inbound, outbound, or both)
- Address family (IPv4, IPv6, or both)
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:
- State: Established, Connect, Active, OpenSent, OpenConfirm, Idle
- Uptime: How long the session has been established
- Prefixes received / exported: Number of routes learned and advertised
- Last error: If the session is down, the reason (Hold Timer Expired, Notification, Cease, etc.)
- Update stats: Messages sent/received, updates, withdrawals
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:
- AS-Path Prepending: Routelock can automatically add prepends to routes advertised via specific providers, making those paths less attractive to external networks and shifting inbound traffic to your preferred provider.
- Selective Announcements: Advertise specific prefixes only through preferred providers.
- Community-based Steering: Use provider-specific BGP communities (e.g., no-export, local-pref communities) to influence inbound routing decisions.
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
- Learning period: Over a configurable window (default: 7 days), Routelock builds per-prefix traffic baselines: average bps, pps, flow count, and their standard deviations.
- Continuous comparison: Every NetFlow aggregation cycle (default: 60 seconds), current traffic is compared against the baseline.
- Threshold breach: If current traffic exceeds
baseline_mean + (threshold_multiplier x baseline_stddev), an event is triggered.
Severity Levels
| Severity | Default Multiplier | Description |
|---|---|---|
| Warning | 3x baseline | Traffic anomaly detected. Logged and visible on dashboard. No automatic action. |
| Critical | 5x baseline | Likely DDoS. In Robot mode, RTBH is triggered. In Human mode, mitigation is proposed. |
| Emergency | 10x baseline | Massive attack. In Robot mode, both RTBH and FlowSpec are activated. Alerts are sent to all configured channels. |
Detection metrics
- Volume (bps): Total bits per second to the target prefix
- Rate (pps): Total packets per second (high pps with small packets = amplification attack)
- Flow count: Number of unique source-destination pairs (high count = distributed attack)
- Protocol distribution: Sudden shift in protocol mix (e.g., 90% UDP when baseline is 20% = UDP flood)
Reviewing Pending Mitigations
Navigate to Security → DDoS Events. Active and recent events are shown with:
- Target prefix/IP
- Attack type (volumetric, protocol, application)
- Severity level
- Current traffic vs. baseline
- Proposed mitigation type (RTBH, FlowSpec, XDP scrubbing)
- Status (detecting, pending, mitigating, resolved)
Click on an event to see detailed analysis including:
- Top source IPs and ASNs contributing to the attack
- Protocol and port breakdown
- Traffic time-series chart (showing baseline, threshold, and actual traffic)
- Proposed mitigation rules with their exact parameters
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
};
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
- Review the proposed rules on the DDoS event detail page
- Optionally modify parameters (e.g., change rate-limit value, adjust source filter)
- Click Approve Mitigation or Reject
- If approved, the rules are injected into BIRD and propagated to upstream routers via BGP
- 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
| Field | Description |
|---|---|
Name | Descriptive name for the rule |
Interface | Network interface to attach the XDP program to |
Source CIDR | Source IP range to match (or any) |
Dest CIDR | Destination IP range to match |
Protocol | IP protocol (TCP, UDP, ICMP, or any) |
Port Range | Destination port range |
Action | DROP (discard), RATE_LIMIT (with pps/bps limit), or REDIRECT (to scrubbing VLAN) |
Priority | Rule 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:
- DDoS alerts: Generated when attacks are detected, mitigated, or resolved
- BGP alerts: Session down, session flapping, unusual route withdrawals
- System alerts: High CPU/memory, disk full, process crash
- Optimization alerts: Provider near commit, route flapping, bulk rollback
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:
- Email (SMTP)
- Slack webhook
- PagerDuty integration
- Generic webhook (custom URL)
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:
| Role | Permissions |
|---|---|
| Admin | Full access. Can manage users, change system configuration, manage API keys, switch operating modes, and perform all operations. |
| Operator | Can approve/reject improvements and DDoS mitigations, acknowledge alerts, view all data, create maintenance windows. Cannot manage users or change system config. |
| Viewer | Read-only access to the dashboard, improvements, DDoS events, reports, and traffic analysis. Cannot approve, reject, or modify anything. |
Creating a user
- Click Add User
- Enter username, display name, email, and role
- Set an initial password (the user will be required to change it on first login)
- Optionally enable 2FA requirement for the account
- 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.
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:
- Name: Descriptive label (e.g., "Monitoring Script", "CI/CD Pipeline")
- Role: Inherited permissions (admin, operator, or viewer)
- Expiry: Optional expiration date
- Allowed IPs: Optional whitelist of source IPs that can use the key
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
| Field | Example | Description |
|---|---|---|
Server URL | ldaps://ad.company.com:636 | LDAP server address (use ldaps:// for TLS) |
Bind DN | CN=routelock,OU=Service,DC=company,DC=com | Service account DN for binding |
Bind Password | (stored encrypted) | Service account password |
Base DN | OU=Users,DC=company,DC=com | Search base for user lookups |
User Filter | (sAMAccountName=%s) | LDAP filter to find users (%s = username) |
Admin Group | CN=NetAdmins,OU=Groups,DC=... | LDAP group DN mapped to Admin role |
Operator Group | CN=NOC,OU=Groups,DC=... | LDAP group DN mapped to Operator role |
Viewer Group | CN=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
- Create an OAuth2 client in the Google Cloud Console
- Set the redirect URI to
https://routelock.local/auth/callback/google - Enter the Client ID and Client Secret in Routelock
- Configure the allowed domain (e.g.,
company.com) to restrict which Google accounts can log in - Map Google groups to Routelock roles
Microsoft SSO (Azure AD / Entra ID)
- Register an application in Azure AD
- Set the redirect URI to
https://routelock.local/auth/callback/microsoft - Enter the Tenant ID, Client ID, and Client Secret in Routelock
- 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
- Navigate to Profile → Security
- Click Enable Two-Factor Authentication
- Scan the QR code with your authenticator app
- Enter the 6-digit code displayed in the app to confirm
- 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:
- Optional: Users choose whether to enable 2FA
- Required for Admins: Admin accounts must have 2FA enabled
- Required for All: All accounts must have 2FA enabled. Users without 2FA are forced to set it up on next login.
Configuration Management
Navigate to Settings → General to view and modify runtime configuration. Changes here take effect immediately without restarting Routelock.
Configurable parameters include:
- Operating mode (Test / Human / Robot)
- Optimization weights (latency, loss, jitter, throughput, cost)
- Minimum improvement threshold
- Probe settings (interval, timeout, protocol, concurrency)
- DDoS thresholds (severity multipliers, baseline window)
- NetFlow aggregation interval
- SNMP polling interval
- Notification channels (email, Slack, PagerDuty, webhook)
- Data retention periods (how long to keep flow records, probe results, etc.)
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
- Click Schedule Maintenance
- Select the affected provider(s)
- Set start and end time (UTC)
- 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.
- 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
- 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.
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
Setup steps
- Shared database: Both nodes connect to the same TimescaleDB instance (or a PostgreSQL HA cluster)
- VIP management: Use keepalived or a similar tool to manage a floating VIP between the two nodes
- Configure HA in routelock.yaml:
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"
- 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. - 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:
- BIRD instance (separate socket and configuration)
- Providers and BGP sessions
- Optimization policy and weights
- NetFlow listener (different port per domain)
- Probe targets and results
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:
- Partial tables: IX peers typically provide only their own routes and customer routes, not the full table
- DSCP probing: Routelock uses DSCP-marked probes to test IX paths, since IX peers may not provide the same reachability as transit
- Prefer-over-transit: When an IX peer provides comparable performance to transit, Routelock can prefer the IX path to reduce transit costs. Configure the preference strength under each IX provider's settings.
- Route server vs. bilateral: Routelock can track routes from IX route servers separately from bilateral peers at the same IX
Configuring IX preference
{
"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
- Routelock samples per-provider traffic every 5 minutes (via SNMP)
- It calculates the rolling 95th percentile for the current billing cycle (typically monthly)
- 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
- 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.
| Report | Contents |
|---|---|
| Overview | Executive summary: total traffic, improvements made, performance delta, DDoS events for the period |
| Traffic | Per-provider traffic volume over time, peak vs. average, protocol distribution |
| Performance | Latency, loss, and jitter improvements. Before-vs-after comparisons for optimized prefixes. |
| Cost | Per-provider 95th percentile, commit utilization, estimated cost savings from optimization |
| Security | DDoS 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
| Operation | Method | Pattern |
|---|---|---|
| List resources | GET | /api/v1/{resource}?page=1&per_page=50 |
| Get single resource | GET | /api/v1/{resource}/{id} |
| Create resource | POST | /api/v1/{resource} |
| Update resource | PUT | /api/v1/{resource}/{id} |
| Delete resource | DELETE | /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
| Channel | Events |
|---|---|
improvements | new, approved, rejected, applied, withdrawn, expired |
ddos | detected, mitigating, resolved |
bgp | session_up, session_down, session_flap |
alerts | new, acknowledged, resolved |
metrics | update (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:
- Firewall: TCP port 179 is blocked between Routelock's server and the router
- IP mismatch: The neighbor IP in Routelock doesn't match the router's BGP configuration
- ASN mismatch: Local or remote AS numbers don't match
- MD5 password: If the router requires TCP-MD5 authentication, ensure it's configured in BIRD
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:
- Import filter is rejecting all routes (check BIRD filter configuration)
- Upstream has not configured their side to advertise routes
- Address family mismatch (IPv4 session trying to receive IPv6, or vice versa)
# 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
- Wrong version: Routelock expects NetFlow v9 or IPFIX (v10). If the router is sending v5, upgrade the export configuration.
- Sampling too aggressive: If the router samples 1-in-10000 flows, very few prefixes will have data. Recommended: 1-in-1000 or 1-in-2000.
- No active flows: Ensure
ip flow monitor(or equivalent) is applied to the correct interfaces.
Probe Failures
High probe failure rate
Common causes:
- ICMP blocked: Many networks filter ICMP. Switch to TCP probes (port 80 or 443) in the probe configuration.
- Source IP not routable: Probes are sent from the server's IP. If your server is behind NAT, probes may fail because responses can't return. Ensure the server has a routable IP or use a probe source interface with one.
- Too many concurrent probes: If the system is overloaded, reduce
probes.workersorprobes.targets_per_cyclein configuration.
# 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:
- Baseline too short: If the baseline window is too short (e.g., 1 day), it may not capture normal traffic patterns like weekend peaks or monthly billing cycles. Increase
ddos.baseline_windowto 7–14 days. - Threshold too low: Increase the detection multiplier. A multiplier of 3x is aggressive; 5x is recommended for most networks.
- New customer traffic: A new customer onboarding large traffic volumes will exceed baselines. Add their prefixes to the DDoS whitelist temporarily.
- CDN or content spikes: Game releases, streaming events, etc. Schedule maintenance windows or whitelist known CDN prefixes.
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:
- Reduce retention: If disk is filling up, reduce the retention period for high-volume tables like
netflow_records(default: 30 days) andprobe_results(default: 90 days) - Add compression: Enable TimescaleDB compression on older chunks:
SELECT add_compression_policy('netflow_records', INTERVAL '7 days'); SELECT add_compression_policy('probe_results', INTERVAL '14 days'); - Tune PostgreSQL: Run
timescaledb-tuneagain if you've changed the server's RAM - Vacuum: Ensure autovacuum is running. If not, run manually:
VACUUM ANALYZE netflow_records; VACUUM ANALYZE probe_results;
Log Analysis
Routelock outputs structured JSON logs. Key fields:
| Field | Description |
|---|---|
level | DEBUG, INFO, WARN, ERROR |
ts | Timestamp (RFC 3339) |
module | Source module (netflow, bgp, probe, optimizer, ddos, api, web, store) |
msg | Human-readable message |
err | Error 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.
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