Osprey 1.3.1
Osprey 1.3.1. Network topology intelligence for OSPF, IS-IS, EIGRP, BGP, MPLS, and EVPN — passive discovery, protocol-accurate modelling, no agents on your routers and no routes injected.
This release turns the BGP evidence Osprey already collects into security findings, decision explanations, and peer-quality answers: a BGP security report with alerting, operator-imported ROA validation, a selection funnel that names the RFC 4271 step behind every winning path, churn classification, a peer scorecard, and a new radial AS-flow lens whose zoom reveals detail instead of magnifying ink.
Highlights since 1.3.0
BGP security
- Security report (Reports → Routing): three deterministic checks over what your BMP sessions were offered — prefixes offered with multiple distinct origins, more-specifics announced under another origin's covering prefix, and paths that already contain your own AS (which the router provably can never select). Findings state presence ("this path was offered on this session"), never acceptance and never "hijack"; each names its observing sessions. When the live feed or the historical recording does not cover the requested scope, the report says so — an empty report under refusal is a coverage statement, not an all-clear.
- Security alerting. The same findings now flow into events, incidents, and alert rules: multiple-origin observed/cleared pairs and own-AS-offered events carry per-prefix identity (so the second affected prefix is not deduplicated away), recoveries resolve the alert from any vantage, and the rail brakes itself with per-prefix debounce and a storm ceiling that never drops a recovery. A new BGP Security group appears in the alert rule manager.
- ROA validation, honestly scoped. Import an authorization set from flat RPKI-style JSON (the DN42 registry export works as-is; AS0 authorizations supported) and every received path is badged valid/invalid/unknown per RFC 6811 at read time — on live views and in the replay, where historical paths validate against the set as of their moment, so updating the registry never rewrites what an old path was. With zero ROAs loaded there are no badges at all, and a coverage summary states what the set actually covers — a session showing no invalids may simply have them filtered upstream.
BGP insight
- The selection funnel. Clicking any observed adjacency now answers "why do paths win here": for the prefixes whose winning path traverses that hop, the RFC 4271 §9.1 step at which the decision actually resolved — LOCAL_PREF, AS-path length, ORIGIN, MED, eBGP-over-iBGP, IGP cost, router-ID tiebreak — shown as winner versus strongest runner-up with the median margin ("±1" next to AS-path length reads as one prepend from flipping). The comparator is the same code the best-path selection runs, so the explanation cannot disagree with the selection; anything the funnel cannot honestly attribute lands in an explicit undetermined bucket.
- Churn shapes. Session churn is classified by what actually changed: selection flips, next-hop re-homes inside the same neighbour, path hunting, cosmetic attribute noise, and genuine announce/withdraw — plus each session's hot prefixes, the small minority that dominates the flapping. The BGP Peers panel shows the dominant shape per peer.
- Peer scorecard. The dependency report's Peer AS tab now answers "is this peer worth it" over a chosen window: flaps, recorded uptime, churn share, and median path lifetime, plus a per-session block with the last table-dump timing and an observability line covering gaps in Osprey's own vantage — without which a monitoring outage reads as an exceptionally stable peer. Everywhere in it, "not measurable" renders as a dash with its reason, never as a fabricated zero.
- Vantage evidence. Per-peer policy-reject counters (the router's own "I refused N of your paths") persist with a sparkline; path half-life is queryable per peer and per origin AS; a blind-spot ledger records when each peer was not observable; best-path edges carry a presence barcode over the timeline window; and a what-if action on every peer row previews the blast radius of losing that peer.
AS-flow radial lens
- A second layout. Next to the columns, a radial lens puts your AS — or any AS you re-root on — at the centre with one ring per AS-path hop and an explicit ≥5-hops outer ring. It is honest about not being a tree: nesting follows each AS's dominant upstream, other observed parents draw as chords, and the view states the off-tree share instead of silently misfiling it. Three ranking axes: origin count, the transit spine (the few ASes carrying most of the feed), and unique originated address space — computed as an interval union, never a sum, so covering aggregates and their more-specifics count once. A ⌕ Find control pins arbitrary ASNs; the AS dossier gained upstream, origination, deaggregation, and transit-reach blocks.
- Zoom builds detail, ink does not grow. Strokes, labels, and badges hold their screen size while positions scale; names appear the moment their slot earns the room, and unnamed origins materialise out of the fold bands as zoom makes space for them — then fold back on the way out. Dense feeds shed decorative overdraw, and opening the dossier no longer resizes the canvas.
- Counting discipline. Merged fold tooltips use exact distinct rollups instead of sums that double-count multi-anchor origins; bubble and edge sizes encode share of the feed, not absolute volume, so a full-table feed draws sanely.
Reliability and accuracy
- BMP prefix counts stay truthful. A flapped peer's prefix count no longer sticks at 0 until the next reconnect, per-address-family counts come from the real per-connection sets, and a flap no longer permanently inflates the RIB gauges.
- BGP next-hop resolution hardened. The peer-session fallback is gated to eBGP with a deterministic order, definitive misses are negative-cached, and cross-AS path stitching's primary peer-to-device step works again for peers whose addresses live outside any IGP area.
- Dependency ranking on real address space. The dependency report's per-AS space columns use the same interval union as the new lens — on a full-table feed the old sum inflated results enough to reorder the top of the list.
Packaging and dependencies
- Dependency refresh, including gopacket 1.7.1 — an upstream security release fixing decoder panics on crafted packets. Osprey's capture paths use the panic-recovering decode API and were not crashable, but a packet-parsing daemon does not stay on a version with known decoder CVEs.
- Third-party attribution is now deterministic. Regenerating the bundled license file could nondeterministically omit a transitively-shipped package; the generator is fixed and regression-tested, and the shipped file is complete.
Install
curl -LO https://github.com/wijnberg-net/osprey/releases/latest/download/osprey_amd64.deb
curl -LO https://github.com/wijnberg-net/osprey/releases/latest/download/SHA256SUMS
sha256sum -c SHA256SUMS
sudo apt install ./osprey_amd64.deb
Debian 12+, Ubuntu 24.04+ (bare metal, Proxmox LXC, or VM). PostgreSQL, NATS, and nginx are pulled in as dependencies; services start under systemd and a self-signed TLS certificate is generated on first install. Open https://your-server/ and log in with the admin account created during setup.
Free evaluation: all features, up to 32 devices, no time limit. Commercial licensing: sales@wijnberg.net.
Full documentation: https://www.wijnberg.net/docs/