Monitor BGP Announcements with BGPalerter on Linux
Deploy BGPalerter v2 on a Linux VPS to monitor your prefixes for hijacks, route leaks, and RPKI invalid states. Configure Slack and email alerts, run as a systemd service.
If you announce your own prefixes via BGP BGP and Bring Your Own IP on a VPS: The Complete Guide, you need to know when something goes wrong. A prefix hijack, a route leak, an RPKI misconfiguration: these can take your network offline or route your traffic through an attacker. BGPalerter watches public route collector data and alerts you in real time.
This tutorial installs BGPalerter v2 on Ubuntu 24.04, configures prefix and ASN monitoring, sets up Slack and email notifications, and runs the whole thing as a systemd service. It assumes you already have BGP running with BIRD2 BIRD2 BGP Configuration on a Linux VPS or FRR FRRouting BGP Configuration on a Linux VPS.
What does BGPalerter monitor and how does it work?
BGPalerter monitors your BGP prefixes in real time using public route collector data from RIPE RIS. It connects via WebSocket to ris-live.ripe.net, which aggregates feeds from 600+ peers worldwide. No integration with your routers is required. It runs on any Linux server with outbound internet access.
BGPalerter ships with these monitors:
| Monitor | What it detects | Default channel |
|---|---|---|
| monitorHijack | Origin AS mismatch, sub-prefix hijacks | hijack |
| monitorVisibility | Prefix withdrawn or seen by too few peers | visibility |
| monitorNewPrefix | Unexpected sub-prefix announced by your AS | newprefix |
| monitorPath | AS path matches a regex pattern (scrubbing, transit change) | path |
| monitorPathNeighbors | Unexpected upstream/downstream AS in path | path |
| monitorAS | Your ASN announces an undeclared prefix | misconfiguration |
| monitorRPKI | Prefix announced with RPKI invalid state | rpki |
| monitorROAS | ROA added, edited, deleted, or expiring | roa |
Each monitor has a thresholdMinPeers parameter. An alert fires only when the anomaly is confirmed by at least that many route collector peers, reducing false positives.
How do I install BGPalerter on Ubuntu 24.04?
Download the latest BGPalerter binary from GitHub and make it executable. No Node.js install required when using the prebuilt binary. The self-contained binary bundles the Node.js runtime, so plan for at least 1 GB of free RAM on the monitoring server.
Create a dedicated user
Run BGPalerter under its own unprivileged account. Never run network monitoring tools as root when there is no reason to.
sudo adduser --system --group --home /opt/bgpalerter --shell /usr/sbin/nologin bgpalerter
Download the binary
cd /opt/bgpalerter
sudo -u bgpalerter curl -Lo /opt/bgpalerter/bgpalerter-linux-x64 https://github.com/nttgin/BGPalerter/releases/latest/download/bgpalerter-linux-x64
sudo chmod +x /opt/bgpalerter/bgpalerter-linux-x64
ls -la /opt/bgpalerter/bgpalerter-linux-x64
The file should be around 140 MB. The binary is self-contained and bundles the Node.js runtime. No runtime dependencies.
Docker alternative
If you prefer containers:
docker run -d --name bgpalerter \
-v /opt/bgpalerter/volume:/opt/bgpalerter/volume \
--restart unless-stopped \
nttgin/bgpalerter:latest run serve -- --d /opt/bgpalerter/volume/
Place your config.yml and prefixes.yml in /opt/bgpalerter/volume/ before starting the container. The rest of this tutorial covers the binary method. The configuration files are identical for both.
How do I configure prefixes.yml to monitor my ASN?
BGPalerter needs to know which prefixes and ASNs belong to you. The generate command queries public routing data and builds prefixes.yml from what your AS currently announces.
sudo -u bgpalerter /opt/bgpalerter/bgpalerter-linux-x64 generate \
-a YOUR_ASN \
-o /opt/bgpalerter/prefixes.yml \
-i -m
Replace YOUR_ASN with your AS number (digits only, no "AS" prefix). The flags:
| Flag | Purpose |
|---|---|
-a |
ASN(s) to monitor. Comma-separated for multiple: -a 64496,64497 |
-o |
Output file path |
-i |
Ignore delegated prefixes (originated by other ASNs) |
-m |
Auto-detect all origin ASNs for your prefixes |
The command produces a file like this:
198.51.100.0/24:
description: Production network
asn: 64496
ignoreMorespecifics: false
ignore: false
2001:db8::/32:
description: IPv6 allocation
asn: 64496
ignoreMorespecifics: false
ignore: false
options:
monitorASns:
64496:
group: default
Key fields
ignoreMorespecifics: Set to true if you intentionally deaggregate (e.g., you announce both /24 and /25s). When false, BGPalerter alerts on any more-specific announcement it did not expect. For most operators, false is the right default. Unexpected more-specifics are a hijack signal.
options.monitorASns: Enables monitorAS for your ASN. BGPalerter alerts if your ASN starts originating a prefix not listed in the file.
group: Controls alert routing. The default group maps to notification channels. You can create separate groups (e.g., noc, engineering) and route them to different Slack channels or email lists.
Edit the generated file to add descriptions, adjust ignoreMorespecifics per prefix, or add prefixes that are not yet announced but should be monitored for unauthorized origination.
How do I configure config.yml?
The auto-configuration wizard creates a default config.yml on first run. For production use, you want explicit control over every parameter.
Create /opt/bgpalerter/config.yml:
connectors:
- file: connectorRIS
name: ris
params:
carefulSubscription: true
url: ws://ris-live.ripe.net/v1/ws/
perMessageDeflate: true
monitors:
- file: monitorHijack
channel: hijack
name: basic-hijack-detection
params:
thresholdMinPeers: 3
- file: monitorVisibility
channel: visibility
name: withdrawal-detection
params:
thresholdMinPeers: 40
notificationIntervalSeconds: 3600
- file: monitorNewPrefix
channel: newprefix
name: newprefix-detection
params:
thresholdMinPeers: 3
- file: monitorAS
channel: misconfiguration
name: asn-monitor
params:
thresholdMinPeers: 3
- file: monitorRPKI
channel: rpki
name: rpki-monitor
params:
thresholdMinPeers: 3
checkUncovered: true
checkDisappearing: true
- file: monitorROAS
channel: roa
name: rpki-diff
params:
enableDiffAlerts: true
enableExpirationAlerts: true
roaExpirationAlertHours: 2
checkOnlyASns: true
- file: monitorPathNeighbors
channel: path
name: path-neighbors
params:
thresholdMinPeers: 3
reports:
- file: reportFile
channels:
- hijack
- newprefix
- visibility
- path
- misconfiguration
- rpki
- roa
params:
persistAlertData: false
alertDataDirectory: alertdata/
notificationIntervalSeconds: 86400
persistStatus: true
alertOnlyOnce: false
fadeOffSeconds: 360
checkFadeOffGroupsSeconds: 30
logging:
directory: logs
logRotatePattern: YYYY-MM-DD
maxRetainedFiles: 30
maxFileSizeMB: 15
compressOnRotation: true
useUTC: true
rest:
host: localhost
port: 8011
rpki:
vrpProvider: rpkiclient
refreshVrpListMinutes: 15
monitoredPrefixesFiles:
- prefixes.yml
checkForUpdatesAtBoot: true
generatePrefixListEveryDays: 0
pidFile: bgpalerter.pid
maxMessagesPerSecond: 6000
multiProcess: false
environment: production
configVersion: 2
Connector notes
connectorRIS streams live BGP updates from RIPE RIS via WebSocket. The carefulSubscription: true setting limits the stream to only your monitored prefixes, reducing bandwidth and CPU.
Your firewall must allow outbound WebSocket connections to ris-live.ripe.net on port 80 (ws://) or 443 (wss://). No inbound rules needed.
The rest section exposes a local HTTP API on port 8011 for health checks and status queries. It binds to localhost by default, so it is not exposed to the network.
Monitor tuning
thresholdMinPeers controls sensitivity. A value of 3 means at least 3 route collector peers must confirm an anomaly before alerting. Lower values catch more events but produce more false positives. For hijack detection, 3 is a good starting point. For visibility, 40 is appropriate since RIPE RIS has 600+ peers.
notificationIntervalSeconds at the monitor level overrides the global setting. For visibility, 3600 (1 hour) prevents alert fatigue during flapping.
How do I monitor RPKI invalid announcements with BGPalerter?
BGPalerter checks the RPKI validity of every BGP announcement it receives for your prefixes. If your prefix appears with an RPKI invalid state, you get an alert. This catches ROA misconfigurations and certain hijack types that RPKI-based filtering would reject.
The monitorRPKI section in config.yml handles this:
checkUncovered: truealerts when your prefix has no ROA at all. You want ROA coverage for every announced prefix RPKI ROA Setup for BGP: Create ROAs, Validate Routes in BIRD2 and FRR.checkDisappearing: truealerts when a ROA that previously covered your prefix disappears.
The separate monitorROAS module watches for ROA changes at the RPKI level: new ROAs created, existing ROAs edited or deleted, and ROAs approaching expiration. The roaExpirationAlertHours: 2 setting gives you a 2-hour heads-up before a ROA expires.
A sample RPKI alert looks like:
The prefix 198.51.100.0/24 (AS64496) is announced with RPKI state Invalid.
Seen by 5 peers. Top 3 AS paths: 64496 174 3356, 64496 6939, 64496 1299
How do I set up email alerts in BGPalerter?
Add a reportEmail block to the reports section of config.yml. BGPalerter uses SMTP directly.
reports:
# ... keep reportFile from above ...
- file: reportEmail
channels:
- hijack
- newprefix
- visibility
- path
- misconfiguration
- rpki
- roa
params:
showPaths: 5
senderEmail: bgpalerter@example.com
smtp:
host: mail.example.com
port: 587
secure: false
ignoreTLS: false
auth:
user: bgpalerter@example.com
pass: your-smtp-password-here
type: login
tls:
rejectUnauthorized: true
notifiedEmails:
default:
- noc@example.com
Replace the SMTP values with your mail server details. The showPaths: 5 setting includes up to 5 AS paths in the alert email so you can see where the anomalous route propagated.
Since config.yml contains the SMTP password in plain text, restrict the file permissions so only the bgpalerter user and root can read it:
sudo chown root:bgpalerter /opt/bgpalerter/config.yml
sudo chmod 640 /opt/bgpalerter/config.yml
The notifiedEmails section maps groups to email addresses. The default group receives all alerts. If you defined custom groups in prefixes.yml, add matching entries:
notifiedEmails:
default:
- noc@example.com
noc:
- oncall@example.com
- sre@example.com
How do I set up Slack notifications in BGPalerter?
Add a reportSlack block to the reports section. You need a Slack incoming webhook URL.
Create the webhook in Slack: go to your workspace settings, find "Incoming Webhooks" under Apps, and create a webhook for the channel where you want alerts.
reports:
# ... keep reportFile and reportEmail ...
- file: reportSlack
channels:
- hijack
- newprefix
- visibility
- path
- misconfiguration
- rpki
- roa
params:
showPaths: 3
colors:
hijack: "#d60b1c"
newprefix: "#fa9548"
visibility: "#fad648"
path: "#42cbf5"
rpki: "#d892f0"
roa: "#d892f0"
hooks:
default: https://hooks.slack.com/services/T00/B00/xxxx
The colors map gives each alert type a distinct color in Slack. Red for hijacks, yellow for visibility loss, purple for RPKI issues.
Replace the webhook URL placeholder with your actual Slack webhook. The config.yml permissions set earlier (640, root:bgpalerter) keep the webhook URL readable only by the service.
How do I run BGPalerter as a systemd service?
Create the systemd unit
sudo tee /etc/systemd/system/bgpalerter.service > /dev/null << 'EOF'
[Unit]
Description=BGPalerter - BGP Monitoring
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=bgpalerter
Group=bgpalerter
WorkingDirectory=/opt/bgpalerter
ExecStart=/opt/bgpalerter/bgpalerter-linux-x64
Restart=on-failure
RestartSec=30s
# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/bgpalerter
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
The ProtectSystem=strict and ProtectHome=true directives restrict filesystem access. BGPalerter only needs to write to its own directory.
Enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now bgpalerter
enable makes the service start on boot. --now starts it immediately.
systemctl status bgpalerter
● bgpalerter.service - BGPalerter - BGP Monitoring
Loaded: loaded (/etc/systemd/system/bgpalerter.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-03-20 10:20:00 UTC; 5s ago
Main PID: 1373 (bgpalerter-linu)
Tasks: 10 (limit: 9443)
Memory: 724.3M
CPU: 4.483s
CGroup: /system.slice/bgpalerter.service
└─1373 /opt/bgpalerter/bgpalerter-linux-x64
The self-contained binary bundles the entire Node.js runtime, so baseline memory is around 500-800 MB regardless of prefix count. Make sure you have at least 1 GB of free RAM on the monitoring server.
Check the logs
journalctl -u bgpalerter -f --no-pager
On startup, BGPalerter loads the config and connects to RIPE RIS. The first lines in the journal look like:
Loaded config: /opt/bgpalerter/config.yml
BGPalerter, version: 2.0.1 environment: production
BGPalerter also writes logs to /opt/bgpalerter/logs/. The logRotatePattern: YYYY-MM-DD setting creates a new log file daily. With maxRetainedFiles: 30 and compressOnRotation: true, you keep a month of compressed logs without manual intervention.
How do I test BGPalerter alerts?
Run BGPalerter with the -t flag to send test alerts through all configured notification channels. This uses a built-in test connector that simulates every alert type without waiting for real BGP events.
sudo -u bgpalerter /opt/bgpalerter/bgpalerter-linux-x64 -t
This sends test messages to your Slack channel and email. Check that alerts arrive with the correct formatting and routing. If you defined multiple groups, each group should receive its mapped alerts.
For ongoing monitoring, watch the journal:
journalctl -u bgpalerter --since "1 hour ago" --no-pager
How does BGPalerter compare to alternatives?
BGPalerter is not the only BGP monitoring option. Here is a quick comparison:
| Tool | Type | Best for |
|---|---|---|
| BGPalerter | Self-hosted, open source | Single AS, prefix monitoring, real-time alerts |
| ARTEMIS | Self-hosted, open source | Large networks, custom detection modules, research |
| Cloudflare Radar | SaaS | Quick lookup, no self-hosting, limited alerting |
| BGPStream | Library/SaaS | Programmatic analysis, historical data research |
| bgp.tools | SaaS | Visual exploration, community data, quick checks |
BGPalerter fits the self-hosted single-AS use case well. It requires no router integration and runs on a small VPS. ARTEMIS is more powerful but significantly more complex to deploy.
For defense in depth, combine BGPalerter with RPKI ROA deployment RPKI ROA Setup for BGP: Create ROAs, Validate Routes in BIRD2 and FRR and proper route filtering BGP Route Filtering: Prefix Lists, AS-Path Filters, Bogon Rejection, and GTSM on your BGP sessions.
Something went wrong?
BGPalerter exits immediately: Check journalctl -u bgpalerter -e. Common causes: malformed YAML in config.yml or prefixes.yml. Validate with python3 -c "import yaml; yaml.safe_load(open('config.yml'))".
No data from RIPE RIS: Your firewall must allow outbound connections to ris-live.ripe.net on port 80 (WebSocket). If you are behind a restrictive proxy, use the wss:// URL on port 443 instead. Update the connector URL in config.yml accordingly.
Alerts not arriving (email): Run with -t to isolate. Check SMTP credentials in config.yml. Verify the sender address is allowed by your mail server (SPF, authentication). Check journalctl -u bgpalerter for SMTP error messages.
Alerts not arriving (Slack): Verify the webhook URL is valid. Slack deactivates webhooks for unused apps. Test the webhook directly: curl -X POST -H 'Content-type: application/json' --data '{"text":"test"}' "https://hooks.slack.com/services/T00/B00/xxxx".
High memory usage: Large prefix lists consume more memory. If you monitor many ASNs, consider increasing swap or splitting into multiple BGPalerter instances with separate prefix files.
Service fails to restart: RestartSec=30s in the unit file adds a 30-second delay between restart attempts. For persistent failures, check the exit code in systemctl status bgpalerter.
Copyright 2026 Virtua.Cloud. All rights reserved. This content is original work by the Virtua.Cloud team. Reproduction, republication, or redistribution without written permission is prohibited.
Ready to try it yourself?
Deploy your own server in seconds. Linux, Windows, or FreeBSD.
See VPS Plans