Skip to main content

NetBox Routing Protocols

A NetBox plugin for modelling static routes, routing policy and BGP configuration alongside the devices and IPAM objects they belong to.

It gives you somewhere to record routing intent — which is the piece NetBox leaves to you — so that config generation, compliance checks and automation can read it back out of the API.

Features

Static routing

  • Static routes bound to a device, VRF, prefix and next hop
  • Explicit default-route modelling (0.0.0.0/0 / ::/0) without needing a placeholder prefix
  • A Static Routes tab on the IPAM Prefix view

Routing policy

  • Prefix lists with ordered, sequenced rules
  • Prefix list rules matching a prefix, any prefix, or the default route, with ge/le length bounds
  • Route maps with ordered rules matching against prefix lists
  • Optional automatic terminating deny 9999 rule on new prefix lists and route maps

BGP

  • BGP routers per device and VRF, with ASN, router ID, AS-path handling and route reflection
  • Peers addressed by IP or as unnumbered interface peers
  • Peer groups, with peers inheriting group attributes
  • Address families (IPv4 unicast, IPv6 unicast, L2VPN EVPN) at router, peer and peer-group level
  • Per-address-family inbound and outbound route-map policy
  • Network statements, aggregates and protocol redistribution

Every model supports the standard NetBox features: tags, custom fields, change logging, journaling, export templates, global search, the REST API and the GraphQL API.

Compatibility

Plugin NetBox Python
1.0.x 4.6.x 3.12+

Installation

Install into your NetBox virtual environment:

source /opt/netbox/venv/bin/activate
pip install netbox-routing-protocols

Add it to PLUGINS in configuration.py:

PLUGINS = [
    'netbox_routing_protocols',
]

Run the migrations:

python manage.py migrate

Add the package to local_requirements.txt so it survives a NetBox upgrade:

echo netbox-routing-protocols >> /opt/netbox/local_requirements.txt

Restart NetBox:

sudo systemctl restart netbox netbox-rq

Configuration

All settings are optional.

PLUGINS_CONFIG = {
    'netbox_routing_protocols': {
        # Create a terminating "deny 9999 / match any" rule whenever a new prefix
        # list or route map is created. Set to False to start them empty.
        'create_default_deny_rule': True,
    },
}

API

REST endpoints are published under /api/plugins/routing-protocols/, and all models are exposed through NetBox's GraphQL API.

curl -H "Authorization: Token $NETBOX_TOKEN" \
     https://netbox.example.com/api/plugins/routing-protocols/bgp-peers/?device=core-sw-01

⚠️ BGP passwords are stored and returned in clear

BGPPeer.password and BGPPeergroup.password hold the BGP MD5 authentication key. The field is treated like any other: it is stored as entered and returned verbatim by the REST API, the GraphQL API, the change log (and therefore webhook payloads), and the UI.

That is deliberate. The key has to reach device configuration, so config generation must be able to read it back — a value automation cannot retrieve would defeat the point of recording it here.

It does mean the value is readable by anyone who can view the object, and by anything holding core.view_objectchange, plus anyone with database or Django shell access.

Store your platform's hashed or encrypted form, not the raw secret. Most network operating systems accept a pre-encrypted key and will render it straight into the configuration:

! Cisco IOS — type 7
neighbor 192.0.2.1 password 7 070C285F4D06
! Arista EOS — type 7
neighbor 192.0.2.1 password 7 <encrypted>
! Juniper — $9$ encrypted
set protocols bgp group EXTERNAL neighbor 192.0.2.1 authentication-key "$9$..."

Storing that form means NetBox never holds the raw secret, and the value can still be rendered into config unchanged.

Be aware of what this does and does not buy you. Cisco/Arista type 7 is obfuscation, not encryption — it is trivially reversible, so it protects against casual exposure (a screenshot, a shared export, an over-broad API token) rather than against an attacker who obtains the value. Juniper $9$ is likewise reversible. If your platform supports a genuinely non-reversible form, prefer it.

Regardless of which form you store, restrict object permissions to match the sensitivity, and treat database backups and webhook destinations as carrying secrets.

Contributing

Issues and pull requests are welcome at https://github.com/jasonyates/netbox-routing-protocols.

Generating migrations

Generate migrations against the oldest supported NetBox release (min_version in __init__.py), not whichever one you happen to have installed. makemigrations records a dependency on the newest migration of every app it references, so a migration generated against a later patch release will fail on earlier ones with:

NodeNotFoundError: Migration netbox_routing_protocols.0001_initial dependencies
reference nonexistent parent node ('dcim', '0237_...')

CI runs the test matrix against both ends of the supported range, so this is caught before release rather than by users.

Licence

Apache-2.0. See LICENSE.

Release files for netbox-routing-protocols 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for netbox-routing-protocols 1.0.0
File Size Uploaded
netbox_routing_protocols-1.0.0.tar.gz 78.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for netbox-routing-protocols 1.0.0
File Interpreter ABI Platform
netbox_routing_protocols-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 175.0 kB

Release files / netbox_routing_protocols-1.0.0.tar.gz

Download URL netbox_routing_protocols-1.0.0.tar.gz
Size 78.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f1aadeecdf96bd6132d80f633f51dbfcc2a3c24e94e46aba4e5d8a916f7a4659
BLAKE2b-256 checksum
How to use checksums
368ed9b42a9d747a8745552e230525a0fe3727ae6770bcacd1d94ef6c1078a47
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.

Transparency log

Release files / netbox_routing_protocols-1.0.0-py3-none-any.whl

Download URL netbox_routing_protocols-1.0.0-py3-none-any.whl
Size 96.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
10b2c9dd7a70aa782fc369e43cf5a62c8bcdf70dfc32226965b46694c1cbb6b8
BLAKE2b-256 checksum
How to use checksums
c281cd6e19a2090a28a5b2fbdb13547511a7ea36135c724232877077de86b83b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.

Transparency log

Release history Release notifications | RSS feed

1.1.0

2 release files

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page