Skip to content

RPKI rov/aspa stages, shared cache, transparent proxy mode#36

Merged
pforemski merged 17 commits into
mainfrom
dev0424
Jun 12, 2026
Merged

RPKI rov/aspa stages, shared cache, transparent proxy mode#36
pforemski merged 17 commits into
mainfrom
dev0424

Conversation

@pforemski

Copy link
Copy Markdown
Contributor

Summary

Three related feature sets (companion PR: bgpfix/bgpfix#22):

Shared RPKI cache in core

The cache (new bgpfix/rpki package) is now maintained by the bgpipe core and shared by stages. Global flags: --rpki (RTR host:port, tls://host:port, URL, or file — default Cloudflare RTR), --rpki-refresh, --rpki-retry, --rpki-insecure. URL/file sources get periodic refresh with conditional GET / mtime + content-hash dedup; RTR reconnects with serial-based incremental updates.

rpki stage split into rov + aspa

  • rov: RFC 6811 origin validation; --invalid withdraw|filter|drop|split|keep, --strict, per-prefix rov/ tags, Prometheus metrics, HTTP status endpoint.
  • aspa: draft-ietf-sidrops-aspa-verification path verification; peer role auto-detected from the RFC 9234 Role capability (or --role), first-hop check with RS exemption (RFC 7947), --peer-tag PEER_AS for multi-peer feeds like ris-live; aspa/status + aspa/invalid-hop tags.

Transparent proxy mode (--transparent) and --ttl

New pkg/util/sockctl composable socket controls replace the old tcpmd5 files: TCP-MD5 (now also OpenBSD), Linux IP_TRANSPARENT, TTL/hop limit (GTSM, RFC 5082). listen --transparent accepts TPROXY-redirected sessions and publishes the captured tuple in the pipe KV; connect --transparent re-originates it, spoofing the source — a fully transparent BGP man-in-the-middle with no router reconfiguration.

Also: scripts/aspa-live*.sh measurement helpers (updated to the new stage syntax), docs synced for all of the above, ASPA downstream validation fix (one uncovered central pair allowed), rpki-client ASPA JSON key support.

go.mod

Pinned to bgpfix pseudo-version v0.19.1-0.20260612100952-76be15db (the #22 branch); bump to a tagged release after that PR merges, before cutting v0.21.0.

Test plan

  • go build ./... && go vet ./... && go test ./... green against the pinned module (no local replace)
  • integration tests in stages/rpki cover live rov+aspa pipelines end-to-end
  • bgpipe -n -- ris-live -- aspa --role provider --peer-tag PEER_AS --invalid keep -- stdout explains cleanly

🤖 Generated with Claude Code

Track failing (CAS, PAS) hop in aspVerify and expose it as the
aspa/invalid-hop tag; warn once per direction when peer ASN is unknown.
Accept rpki-client's `providers` key (emits [0] for AS0) alongside
Routinator's `provider_asids`. Add end-to-end tests covering file load,
cache swap, ROV/ASPA actions, and reload.

Combined with the n-2 valley-free relaxation already on dev0424.
New pkg/util/sockctl: composable socket control funcs (Chain) for
TCP-MD5 (now also on OpenBSD), IP_TRANSPARENT, and TTL/hop limit.

connect/listen get --transparent (Linux TPROXY) for fully transparent
BGP proxying: listen recovers the original tuple and publishes it in
the pipe KV; connect derives its target from L_LOCAL and spoofs the
source from L_REMOTE. --ttl supports GTSM (RFC 5082) and multihop.
The RPKI cache moves to the bgpipe core (bgpfix/rpki package),
created on first UseRpki() and maintained per the global --rpki
flags: RTR (plain or TLS), an HTTP(S) URL, or a local file, with
periodic refresh, conditional GET, and content-hash dedup.

The old rpki stage splits into two composable stages sharing that
cache: rov (RFC 6811 origin validation, per-prefix actions) and
aspa (path verification with RFC 9234 role auto-detection,
--peer-tag for multi-peer feeds like ris-live).

Depend on bgpfix@rpki-cache; replace directive commented out.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes bgpipe’s RPKI validation and transport features by moving RPKI cache management into the core (shared across stages), splitting the old rpki stage into dedicated rov (origin validation) and aspa (path validation) stages, and adding composable socket controls to support transparent proxying and explicit TTL/hop-limit.

Changes:

  • Introduce a core-managed, shared RPKI cache (core/rpki.go) fed from RTR/URL/file via global --rpki* flags.
  • Split validation functionality into new rov and aspa stages with updated metrics/HTTP status endpoints and integration tests.
  • Add pkg/util/sockctl* socket control plumbing (TCP-MD5, Linux transparent proxy mode, TTL) and wire it into listen/connect; update docs and scripts accordingly.

Reviewed changes

Copilot reviewed 55 out of 56 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
stages/rpki/validate.go Removed legacy combined ROV/ASPA validation implementation.
stages/rpki/validate_test.go Removed legacy prefix validation unit tests.
stages/rpki/validate_msg_test.go Removed legacy UPDATE validation unit tests.
stages/rpki/rtr.go Removed stage-local RTR loop (moved to core).
stages/rpki/rpki.go Reduced to package-level docs/constants after stage split.
stages/rpki/rpki_test.go Refactored shared test helpers for new rov/aspa stages.
stages/rpki/rov.go New ROV stage (RFC 6811) backed by the shared core cache.
stages/rpki/rov_test.go New unit tests for ROV behavior/actions/tags.
stages/rpki/next.go Removed stage-local “next” cache implementation (moved to shared cache).
stages/rpki/next_test.go Removed tests for legacy stage-local cache.
stages/rpki/integration_test.go New end-to-end tests covering cache load + stage wiring + actions.
stages/rpki/file.go Removed stage-local file parsing/watching (moved to core/shared cache).
stages/rpki/file_test.go Removed tests for legacy stage-local file parser.
stages/rpki/aspa.go Updated ASPA stage to use shared cache and new peer-role resolution logic.
stages/rpki/aspa_test.go Reworked ASPA tests to match the new stage structure and peer handling.
stages/repo.go Registers new rov and aspa stages; removes rpki stage.
stages/listen.go Adds --transparent/--ttl; wires socket controls via sockctl.
stages/connect.go Adds --transparent/--ttl; supports tuple-derived target/bind for transparent MITM.
scripts/docs-serve Helper to serve docs via mkdocs-material.
scripts/docs-deploy Helper to deploy docs via mkdocs gh-deploy.
scripts/aspa-live.sh New ASPA measurement helper for RIS Live with updated stage syntax.
scripts/aspa-live-stats.sh New helper to run live ASPA with metrics and summarize counts.
pkg/util/tcpmd5_unsupported.go Removed (replaced by sockctl_*).
pkg/util/tcpmd5_linux.go Removed (replaced by sockctl_linux.go).
pkg/util/sockctl.go New socket-control composition utilities + address-family inference.
pkg/util/sockctl_unsupported.go Unsupported-platform implementations for TcpMd5/Transparent/Ttl.
pkg/util/sockctl_test.go Unit tests for Chain and isV6 helpers.
pkg/util/sockctl_openbsd.go OpenBSD socket-control implementation (TCP-MD5 flag + TTL).
pkg/util/sockctl_linux.go Linux socket-control implementation (TCP-MD5 + IP_TRANSPARENT + TTL).
pkg/util/sockctl_linux_test.go Linux-only test ensuring TTL sockopt is applied on a real socket.
mkdocs.yml Adds aspa and rov docs; removes rpki doc from nav.
go.sum Updates bgpfix dependency checksums for pinned pseudo-version.
go.mod Pins bgpfix to a pseudo-version needed by the companion PR branch.
docs/stages/update.md Updates examples/links to use rov instead of rpki.
docs/stages/tag.md Updates references from rpki to rov.
docs/stages/rv-live.md Updates example pipelines to use rov.
docs/stages/rpki.md Removed old combined-stage documentation.
docs/stages/rov.md New ROV stage documentation (incl. shared cache config).
docs/stages/ris-live.md Updates examples to use rov.
docs/stages/metrics.md Updates references to point to rov.
docs/stages/listen.md Documents --transparent and --ttl for listen stage.
docs/stages/limit.md Updates references to point to rov.
docs/stages/index.md Adds aspa, replaces rpki with rov in stage list.
docs/stages/connect.md Documents --transparent and --ttl for connect stage.
docs/stages/aspa.md New ASPA stage documentation.
docs/quickstart.md Updates global flags and supported stage list (aspa, rov, --rpki*).
docs/json-format.md Updates examples/references from rpki tags to rov tags.
docs/intro.md Updates stage list/example pipeline to use rov/aspa.
docs/index.md Updates quick demo to use rov.
docs/filters.md Updates tag examples to refer to rov/status.
docs/examples.md Updates examples to use rov and adds new shared-cache wording.
docs/docker.md Updates docker examples to use global --rpki + rov.
core/rpki.go New shared core RPKI cache manager (RTR/URL/file).
core/rpki_test.go Tests for file/URL/RTR core cache sources.
core/config.go Adds global --rpki* flags.
core/bgpipe.go Starts the shared RPKI cache at pipeline startup (when in use).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/util/sockctl.go
Comment on lines +38 to +51
func isV6(network, address string) bool {
if strings.HasSuffix(network, "6") {
return true
}
if strings.HasSuffix(network, "4") {
return false
}
host := address
if h, _, err := net.SplitHostPort(address); err == nil {
host = h
}
ip, err := netip.ParseAddr(host)
return err == nil && ip.Is6() && !ip.Is4In6()
}
pforemski added 11 commits June 12, 2026 12:27
pure Go covers the rest via go build; android-arm64 runs in Termux
catches the classic 'grep -L on an R-only pipeline' silent no-op
… reference accuracy

- flowspec: the and bit ANDs with the preceding term (RFC 8955), not the next
- json-format: envelope is always 6 elements; document NOTIFY/REFRESH payloads;
  confederation AS_PATH segments are unsupported, not silently flattened
…gure

SVG gets an opaque rounded background (readable on dark themes),
responsive sizing, and font fallbacks
@pforemski pforemski merged commit cb1bc04 into main Jun 12, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants