| 1 | <!--startmeta |
| 2 | custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/integrations/bio-rd_-_ripe_ris.md" |
| 3 | meta_yaml: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/metadata.yaml" |
| 4 | sidebar_label: "bio-rd / RIPE RIS" |
| 5 | learn_status: "Published" |
| 6 | learn_rel_path: "Network Flows/Enrichment Methods" |
| 7 | keywords: ['bioris', 'bio-rd', 'ripe ris', 'bgp', 'grpc', 'route information service', 'as path', 'bgp communities'] |
| 8 | message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE FLOWS' metadata.yaml FILE" |
| 9 | endmeta--> |
| 10 | |
| 11 | <!-- markdownlint-disable-file --> |
| 12 | |
| 13 | # bio-rd / RIPE RIS |
| 14 | |
| 15 | |
| 16 | <img src="https://netdata.cloud/img/network-wired.svg" width="150"/> |
| 17 | |
| 18 | |
| 19 | Plugin: netflow-plugin |
| 20 | Module: bioris |
| 21 | |
| 22 | <img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" /> |
| 23 | |
| 24 | ## Overview |
| 25 | |
| 26 | Enrich network flows with BGP routing context received from a bio-rd-compatible |
| 27 | `RoutingInformationService` gRPC endpoint. [bio-rd](https://github.com/bio-routing/bio-rd) |
| 28 | is a Go-based BGP/BMP daemon that you run yourself. Its `ris` daemon receives BMP |
| 29 | sessions from routers or collectors and exposes the resulting RIB through gRPC. |
| 30 | Netdata is a **client** of that gRPC interface only. |
| 31 | |
| 32 | Netdata does **not** connect directly to RIPE NCC RIS Live, RIPEstat, RIS MRT dumps, |
| 33 | or RIPE route collector sessions. RIPE RIS public access is WebSocket JSON, HTTP API, |
| 34 | and MRT dump based. To use a RIPE-derived external view, run a bridge or service that |
| 35 | imports that data into a bio-rd-compatible `RoutingInformationService`, then point |
| 36 | Netdata at that service. |
| 37 | |
| 38 | Pick this when bio-rd is already part of your routing toolbox, or when you want Netdata |
| 39 | to consume a routing view that is already exposed through the bio-rd RIS gRPC API. If |
| 40 | your routers can speak BMP straight to Netdata, the `bmp` integration is simpler. |
| 41 | |
| 42 | BioRIS populates the same flow-record fields as BMP -- both feed a single shared |
| 43 | in-memory routing trie. See the BMP integration card for the side-by-side comparison |
| 44 | and combined-deployment notes. |
| 45 | |
| 46 | |
| 47 | The plugin connects as a gRPC client to one or more user-provided bio-rd `ris` |
| 48 | endpoints (`grpc_addr`) and runs three RPCs against each one: |
| 49 | |
| 50 | 1. `GetRouters` -- discover which routers/VRFs the bio-rd instance is exposing. |
| 51 | 2. `DumpRIB` -- pull a baseline RIB for each (router, AFI/SAFI) tuple. This is the |
| 52 | expensive call -- full IPv4+IPv6 feeds run to millions of prefixes. |
| 53 | 3. `ObserveRIB` -- subscribe to incremental updates so the trie tracks live changes. |
| 54 | |
| 55 | Per refresh cycle (default 30 minutes), the plugin re-runs `GetRouters` + |
| 56 | `DumpRIB`, then keeps `ObserveRIB` streams open between cycles. Routers that |
| 57 | disappear between refreshes have their routes purged. |
| 58 | |
| 59 | Multiple `ris_instances` are **additive**, not failover -- routes from every |
| 60 | configured endpoint merge into the same trie. The trie is also shared with the |
| 61 | `bmp` integration, so if both are enabled their routes coexist and lookups pick |
| 62 | the best match across both sources. |
| 63 | |
| 64 | Connection is plain gRPC over HTTP/2 by default; set `grpc_secure: true` to use |
| 65 | TLS with the system CA bundle. There is no client-cert / mTLS and no application |
| 66 | auth -- restrict access at the network layer. |
| 67 | |
| 68 | **Fields populated** (same set as BMP): |
| 69 | |
| 70 | | Field | Side | Source | |
| 71 | |---|---|---| |
| 72 | | `SRC_AS` / `DST_AS` | both | When the `routing` provider in the `asn_providers` chain matches | |
| 73 | | `SRC_MASK` / `DST_MASK` | both | Prefix length of the longest-match BGP route | |
| 74 | | `NEXT_HOP` | dest only | BGP next-hop attribute from the destination route | |
| 75 | | `DST_AS_PATH` | dest only | Full AS path, CSV of ASNs | |
| 76 | | `DST_COMMUNITIES` | dest only | Standard BGP communities (CSV of u32) | |
| 77 | | `DST_LARGE_COMMUNITIES` | dest only | RFC 8092 large communities | |
| 78 | |
| 79 | Source-side AS path and communities are **not** surfaced; BGP path attributes are |
| 80 | most meaningful for the destination of the traffic. AS *names* (`SRC_AS_NAME`, |
| 81 | `DST_AS_NAME`) come from the GeoIP/ASN MMDB, not from BGP -- BioRIS gives you |
| 82 | accurate AS *numbers* and path/community attributes; the names come from the ASN |
| 83 | database integration. |
| 84 | |
| 85 | **Storage tier:** `DST_AS_PATH`, `DST_COMMUNITIES`, and `DST_LARGE_COMMUNITIES` |
| 86 | are written only into the raw journal tier. The 1-minute / 5-minute / 1-hour |
| 87 | rollup tiers do not carry them. Queries that need AS path or community data |
| 88 | must run against a window that the raw retention still covers. |
| 89 | |
| 90 | |
| 91 | This integration is only supported on the following platforms: |
| 92 | |
| 93 | - Linux |
| 94 | |
| 95 | This integration runs as a single instance per Netdata Agent. |
| 96 | |
| 97 | |
| 98 | ### Default Behavior |
| 99 | |
| 100 | #### Auto-Detection |
| 101 | |
| 102 | Disabled by default. Set enrichment.routing_dynamic.bioris.enabled to true and provide at least one ris_instances entry. |
| 103 | |
| 104 | #### Limits |
| 105 | |
| 106 | Memory scales with the number of RIS instances, peers, routing tables, prefixes, AS paths, and communities. Full-table feeds can consume hundreds of MB per peer. |
| 107 | |
| 108 | #### Performance Impact |
| 109 | |
| 110 | Disabled until BioRIS is configured. Once active, Netdata maintains an |
| 111 | in-memory routing trie for the received RIB and updates. Plan capacity from |
| 112 | the number of peers and tables you import, and watch the agent's RSS. |
| 113 | |
| 114 | |
| 115 | ## Setup |
| 116 | |
| 117 | |
| 118 | ### Prerequisites |
| 119 | |
| 120 | #### A running bio-rd 'ris' daemon |
| 121 | |
| 122 | bio-rd is a separate project. The plugin only consumes its gRPC interface; it |
| 123 | does not bundle bio-rd. You install and operate it yourself: |
| 124 | |
| 125 | ```bash |
| 126 | # Install Go (>=1.20), then: |
| 127 | git clone https://github.com/bio-routing/bio-rd.git |
| 128 | cd bio-rd/cmd/ris |
| 129 | go build -o /usr/local/bin/ris . |
| 130 | ``` |
| 131 | |
| 132 | Configure `ris` with one or more BMP sources using bio-rd's `bmp_addr` / |
| 133 | `bmp_servers` configuration. Refer to the bio-rd documentation for the BMP setup |
| 134 | -- this is bio-rd's configuration, not Netdata's. |
| 135 | |
| 136 | Do not set Netdata's `grpc_addr` to a RIPE RIS Live URL, RIPEstat API URL, MRT dump |
| 137 | URL, or route collector session address. Those endpoints are not the |
| 138 | `RoutingInformationService` gRPC API that Netdata consumes. |
| 139 | |
| 140 | Run the daemon with a gRPC port: |
| 141 | `/usr/local/bin/ris --grpc_port 50051 --config.file /etc/bio-rd.yml` |
| 142 | |
| 143 | |
| 144 | #### Network reachability + no auth |
| 145 | |
| 146 | The gRPC connection is plain HTTP/2 by default, or TLS with the system CA |
| 147 | bundle when `grpc_secure: true`. There is no client-cert / mTLS and no application |
| 148 | authentication -- restrict access at the firewall, or run bio-rd on the same |
| 149 | host as the agent and bind it to localhost. |
| 150 | |
| 151 | |
| 152 | |
| 153 | ### Configuration |
| 154 | |
| 155 | #### Options |
| 156 | |
| 157 | BioRIS options live under `enrichment.routing_dynamic.bioris` in |
| 158 | `netflow.yaml`. |
| 159 | |
| 160 | |
| 161 | <details open><summary>Config options</summary> |
| 162 | |
| 163 | |
| 164 | |
| 165 | | Option | Description | Default | Required | |
| 166 | |:-----|:------------|:--------|:---------:| |
| 167 | | enabled | Master switch. | false | no | |
| 168 | | timeout | Connect + per-RPC timeout for `GetRouters` and `ObserveRIB` setup. Default is aggressive; raise to 2-5s when reaching a remote bio-rd over the public internet. | 200ms | no | |
| 169 | | refresh | Cadence at which the plugin re-runs `GetRouters` + `DumpRIB` for every router. Floored to 10s. | 30m | no | |
| 170 | | refresh_timeout | Per-DumpRIB request timeout and per-message stream timeout for the baseline RIB pull. | 10s | no | |
| 171 | | ris_instances | List of bio-rd endpoints. Each entry: `grpc_addr` (`host:port` or full `http(s)://` URI), `grpc_secure` (TLS with system CAs when true), `vrf` (string VRF name to filter on), `vrf_id` (numeric VRF ID, alternative to `vrf`). Multiple instances are additive (not failover) -- routes from every instance merge into the same trie. | [] | yes | |
| 172 | |
| 173 | |
| 174 | </details> |
| 175 | |
| 176 | |
| 177 | |
| 178 | #### via File |
| 179 | |
| 180 | The configuration file name for this integration is `netflow.yaml`. |
| 181 | |
| 182 | |
| 183 | You can edit the configuration file using the [`edit-config`](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#edit-configuration-files) script from the |
| 184 | Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#locate-your-config-directory). |
| 185 | |
| 186 | ```bash |
| 187 | cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata |
| 188 | sudo ./edit-config netflow.yaml |
| 189 | ``` |
| 190 | |
| 191 | ##### Examples |
| 192 | |
| 193 | ###### Local bio-rd |
| 194 | |
| 195 | bio-rd running on the same host, plain gRPC. |
| 196 | |
| 197 | ```yaml |
| 198 | enrichment: |
| 199 | routing_dynamic: |
| 200 | bioris: |
| 201 | enabled: true |
| 202 | timeout: 2s |
| 203 | refresh: 30m |
| 204 | refresh_timeout: 30s |
| 205 | ris_instances: |
| 206 | - grpc_addr: "127.0.0.1:50051" |
| 207 | grpc_secure: false |
| 208 | |
| 209 | ``` |
| 210 | ###### Remote bio-rd over TLS |
| 211 | |
| 212 | Across a network, system CA bundle. No client cert / mTLS. |
| 213 | |
| 214 | <details open><summary>Config</summary> |
| 215 | |
| 216 | ```yaml |
| 217 | enrichment: |
| 218 | routing_dynamic: |
| 219 | bioris: |
| 220 | enabled: true |
| 221 | timeout: 5s |
| 222 | ris_instances: |
| 223 | - grpc_addr: "ris.example.internal:50051" |
| 224 | grpc_secure: true |
| 225 | vrf: "global" |
| 226 | |
| 227 | ``` |
| 228 | </details> |
| 229 | |
| 230 | ###### Prefer BGP over the exporter's AS view |
| 231 | |
| 232 | With the default provider chain, an exporter-supplied AS number wins over |
| 233 | BGP. If your bio-rd feed is more accurate than what the exporter is |
| 234 | stamping into flow records, reorder the chains so `routing` is consulted |
| 235 | first. |
| 236 | |
| 237 | |
| 238 | <details open><summary>Config</summary> |
| 239 | |
| 240 | ```yaml |
| 241 | enrichment: |
| 242 | asn_providers: [routing, flow, geoip] |
| 243 | net_providers: [routing, flow] |
| 244 | routing_dynamic: |
| 245 | bioris: |
| 246 | enabled: true |
| 247 | ris_instances: |
| 248 | - grpc_addr: "127.0.0.1:50051" |
| 249 | |
| 250 | ``` |
| 251 | </details> |
| 252 | |
| 253 | ###### Combined with BMP into a single trie |
| 254 | |
| 255 | Run BMP from internal routers and BioRIS from a separate bio-rd-compatible RIS |
| 256 | service, for example one populated from an external routing view. Both populate |
| 257 | the same shared trie -- lookups pick the best-matching route across both sources |
| 258 | at query time. |
| 259 | |
| 260 | |
| 261 | <details open><summary>Config</summary> |
| 262 | |
| 263 | ```yaml |
| 264 | enrichment: |
| 265 | routing_dynamic: |
| 266 | bmp: |
| 267 | enabled: true |
| 268 | listen: "0.0.0.0:10179" |
| 269 | bioris: |
| 270 | enabled: true |
| 271 | ris_instances: |
| 272 | - grpc_addr: "127.0.0.1:50051" |
| 273 | |
| 274 | ``` |
| 275 | </details> |
| 276 | |
| 277 | |
| 278 | |
| 279 | ### Default 200ms timeout too aggressive |
| 280 | |
| 281 | `timeout` covers the gRPC connect plus the `GetRouters` and `ObserveRIB` |
| 282 | setup RPCs. Over the public internet to a remote bio-rd, 200ms is often not |
| 283 | enough. If you see "deadline exceeded" errors in the journal, raise to 2-5s. |
| 284 | `refresh_timeout` is separate and bounds the long-running `DumpRIB` and per- |
| 285 | message stream reads (default 10s). |
| 286 | |
| 287 | |
| 288 | ### Initial dump takes minutes for full feeds |
| 289 | |
| 290 | A full IPv4+IPv6 RIB from a full-table bio-rd source can contain millions of |
| 291 | prefixes. The first `DumpRIB` after enabling (or after a plugin restart) takes |
| 292 | time -- BGP attribution is incomplete until it finishes. Subsequent |
| 293 | `ObserveRIB` streams are incremental. |
| 294 | |
| 295 | |
| 296 | ### Plugin restart wipes the trie |
| 297 | |
| 298 | The trie is in-memory only -- restarting the netflow plugin loses every |
| 299 | learned BGP route. Convergence over BioRIS depends on the upstream feed; a |
| 300 | full DumpRIB from a full-table bio-rd source can take minutes. Schedule |
| 301 | restarts off-peak if BGP attribution matters for your workflow. |
| 302 | |
| 303 | |
| 304 | ### Pointing grpc_addr at RIPE RIS does not work |
| 305 | |
| 306 | `grpc_addr` must point to a bio-rd-compatible `RoutingInformationService` |
| 307 | endpoint. RIPE RIS Live, RIPEstat, RIS MRT dumps, and route collector BGP |
| 308 | sessions use different protocols, so they cannot be used directly as |
| 309 | `ris_instances[].grpc_addr`. Put a converter or bio-rd-compatible service in |
| 310 | front of RIPE-derived data if you need that external view. |
| 311 | |
| 312 | |
| 313 | ### Memory growth without bound |
| 314 | |
| 315 | The trie has no time-based eviction. Routes are removed only when the |
| 316 | upstream BGP source withdraws them, when a router disappears from |
| 317 | `GetRouters` between refreshes, or on plugin shutdown. A full feed is |
| 318 | several hundred MB of RSS per peer, permanently. |
| 319 | |
| 320 | |
| 321 | ### AS path / communities missing on older queries |
| 322 | |
| 323 | `DST_AS_PATH`, `DST_COMMUNITIES`, and `DST_LARGE_COMMUNITIES` only exist in |
| 324 | the raw journal tier. The 1m / 5m / 1h rollup tiers do not carry them. Queries that span beyond the raw |
| 325 | retention horizon will not return BGP path data. |
| 326 | |
| 327 | |
| 328 | ### AS path inconsistent with the exporter's view |
| 329 | |
| 330 | Different vantage points see different BGP paths. If your flow exporter and |
| 331 | the BGP source bio-rd is peering with are different boxes with different |
| 332 | routing tables, expect divergence. This is normal in BGP, not a bug. |
| 333 | |
| 334 | |
| 335 | ### Validate BioRIS enrichment after enabling |
| 336 | |
| 337 | BioRIS-derived enrichment depends on the bio-rd version, upstream BGP source, |
| 338 | route visibility, and refresh cadence. Validate against your bio-rd setup |
| 339 | before relying on this for capacity or security decisions. |
| 340 | |
| 341 | |
| 342 |