Synchronize OPNsense to netbox.
  • Python 94.3%
  • HTML 4.6%
  • Nix 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Oluf Lorenzen 211d6bd36d
Cover the device_names block in the feature-order test
The registry test pins the exact set of blocks, so the new block has to be
listed there too.
2026-10-03 21:07:56 +02:00
docs Make credential references self-describing with env:/file: prefixes 2026-09-29 14:28:10 +02:00
LICENSES from-copier 2026-09-26 13:23:39 +02:00
netbox_sync_opnsense Cover the device_names block in the feature-order test 2026-10-03 21:07:56 +02:00
nix Add sync engine, all feature blocks, and Nix packaging 2026-09-27 20:19:36 +02:00
tests Fix job-log messages losing their values 2026-09-29 11:31:53 +02:00
.copier-answers.yml from-copier 2026-09-26 13:23:39 +02:00
.editorconfig from-copier 2026-09-26 13:23:39 +02:00
.gitignore Add plugin foundation and OPNsense API client 2026-09-27 09:59:05 +02:00
CHANGELOG.md Read DNS host overrides so device names can be FQDNs 2026-10-03 21:07:17 +02:00
COMPATIBILITY.md Add sync engine, all feature blocks, and Nix packaging 2026-09-27 20:19:36 +02:00
flake.lock Add sync engine, all feature blocks, and Nix packaging 2026-09-27 20:19:36 +02:00
flake.nix Add sync engine, all feature blocks, and Nix packaging 2026-09-27 20:19:36 +02:00
Makefile from-copier 2026-09-26 13:23:39 +02:00
mise.toml Add reconciliation: mark-missing and opt-in grace-gated removal 2026-09-28 12:02:04 +02:00
pyproject.toml Use a global sync schedule 2026-09-30 00:35:12 +02:00
README.md Narrow the content-type claim to what the appliance actually does 2026-09-29 17:59:07 +02:00
REUSE.toml Add UI and REST API 2026-09-29 10:30:46 +02:00
uv.lock add netbox as dev dependency for typing etc. 2026-09-29 14:57:53 +02:00

Netbox sync OPNsense

Netbox plugin to synchronize data from an OPNsense firewall.

➡️ Quick Links: Repository · Issues

🌱 Status

Netbox plugin to synchronize data from an OPNsense firewall. is pretty new and still under development.

📚 Documentation

There's no documentation yet, you'll have to read the source for now. Sorry!

🔐 Credentials

Credentials are referenced, never stored. An endpoint row holds the location of a key and a secret; the value is read at sync time and never written to the database, so a database dump cannot leak a firewall API secret.

A reference is self-describing — its prefix is its type, and a reference without a known prefix is an error rather than a guess:

Reference Meaning
env:OPNSENSE_FW1_KEY Read environment variable OPNSENSE_FW1_KEY from the NetBox process.
file:/run/secrets/opnsense-fw1-key Read that file (must be an absolute path).

A single trailing newline is stripped from file contents, because echo and most secret stores add one. An empty value is an error, not an empty credential.

A reference is checked in two places, because the two questions have different owners. Its shape — a known prefix, an absolute path, an environment variable name without spaces — is validated when the endpoint is saved, and a malformed reference is rejected against the form field. Whether it resolves (the variable is set, the file is readable) depends on the host the plugin runs on, so that is checked by the Test connection action, which resolves both references and then performs one read-only API round trip. Keeping resolution out of the save path means an endpoint stays editable on a deployment that only exposes the secret to the worker process.

Provisioning the secrets — environment variables from the service manager, or a root-only file — remains the deployment's job. See docs/nix.md for the NixOS module.

🔌 Connection troubleshooting

A sync failure names what actually went wrong, so the message is worth reading before changing any setting.

TLSV1_ALERT_INTERNAL_ERROR on the handshake — check the port first. The appliance answered the TLS handshake with an alert and never presented a certificate. Nothing that speaks the OPNsense API is listening on that port; something else is answering. The OPNsense web UI defaults to 8443, so a base_url of https://firewall (port 443) is the common mistake — 443 is frequently taken by a reverse proxy.

This failure is not affected by the verify TLS certificate switch. Disabling verification only skips the checks performed after a certificate is received, so when a handshake is interrupted before that point there is nothing for the setting to relax. If the failure text mentions the combination, the port is wrong, not the verification setting.

... returned 'text/html' instead of JSON — usually a false alarm, fixed in this release. OPNsense's API speaks JSON, but the response label does not always say so: some endpoints deliver a JSON body under text/html. The response is now parsed and judged on its body, which is the only thing that can be judged. If you still see this message, the body genuinely was not JSON — most often a login page, which means the API key or secret was rejected rather than lacking a privilege.

CERTIFICATE_VERIFY_FAILED — that one is about verification. The handshake completed and the certificate was rejected. Prefer pointing CA bundle path at the issuing CA over turning verification off: the CA bundle is used as-is, while disabling verification also accepts an intercepted connection. Note that connecting by IP address requires the certificate to carry that IP in its subject alternative names, which many appliance certificates do not — use a hostname the certificate is valid for.

🗃️ Installation

Simply install the netbox-sync-opnsense package from PyPI via your preferred package manager.

For example, to add it as a dependency to your uv-managed project, use this:

uv add netbox-sync-opnsense

🧑‍💻 Development

Preparation

We're using uv to manage this project and its dependencies. After cloning the repository using Git, a simple uv sync should get everything you need.

git clone https://git.h.oluflorenzen.de/finkregh/netbox-sync-opnsense.git netbox-sync-opnsense
cd netbox-sync-opnsense
uv sync

direnv

We recommend using direnv to add installed dependencies to your $PATH, so that you don't need to prepend uv run to every command. For example, after installing direnv, you can use direnv edit in this repository's directory and add the following line:

PATH_add .venv/bin

The rest of this readme assumes that you have .venv/bin in your $PATH.

EditorConfig

Make sure your editor or IDE supports the EditorConfig standard, so that your code adheres to the project's preferred indentation, line lengths, etc.

Makefile

There is a Makefile that contains frequently used commands to speed up development, but it's optional to use. The following targets exist:

  • fmt: Use Ruff to format and lint the code.
  • qa: Use mypy for static type analysis.
  • reuse: Use reuse lint to make sure every file contains licensing information.
  • test: Use pytest for automated testing and code coverage.
  • noqa: Add noqa statements to ignore everything Ruff complains about. Only use this after fixing everything that needs fixing.

make all, or simply make, will run fmt, qa, reuse, and test. You should do this before every commit and fix all issues that are reported.

📃 License

This project is licensed under the terms of the MIT License.

The project also conforms to the REUSE Specification, version 3.3. You can use the reuse tool to interpret the machine-readable licensing information.