Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

NetBox

Reads what NetBox associates with the client’s address. Supports every source, including the two that resolve a shared service address.

What NetBox is asked

One lookup always happens:

GET <url>/api/ipam/ip-addresses/?address=<client ip>

Up to four more are made, each gated by a source:

QuerySource
dcim/devices/{id}/ or virtualization/virtual-machines/{id}/device
ipam/ip-addresses/?device_id=N&role=…vip
ipam/fhrp-group-assignments/?interface_type=…&interface_id=…fhrp
ipam/ip-addresses/?fhrpgroup_id=…fhrp

A read-only API token is enough.

Authenticating

NetBox has two generations of API token, and this backend sends whichever it is given: the scheme is derived from the token itself, so there is nothing to configure.

TokenSent asWhere it comes from
nbt_<key>.<secret>Authorization: Bearer nbt_<key>.<secret>v2, the default since NetBox 4.5
anything elseAuthorization: Token <token>the legacy v1 token, not accepted from NetBox 4.7

The nbt_ prefix is NetBox’s own marker for a v2 token, and the whole string — key, dot and secret — is displayed once when the token is created, so paste it verbatim. A value starting nbt_ that carries no . is the key half on its own: that is refused at startup, because NetBox would otherwise answer every lookup with a 403, which looks exactly like a token that has been revoked.

Declaring names

Two places, and either or both can be trusted:

  • dns_name on the IP address object — the ordinary case, one name per address.
  • A custom field (custom_field, by default acme_domains) for the extra names that address may request. Configure it in NetBox as a multi-select or a text field on ipam.ipaddress and — for the device source — on dcim.device and virtualization.virtualmachine. A single string is accepted as well as a list.

With the device source, an address that carries no value of its own falls back to the field on its device or virtual machine, so names can be declared once per machine rather than once per address. It is a fallback and not a union: see Sources.

Shared and service addresses

A VRRP, CARP or keepalived pair answers on an address that belongs to the pair, not to either member — but the client connects from its own member address, so without one of the sources below it is refused a certificate for the service name. Both are unions: the member’s own names and the service address’s names are true at the same time.

Which one an estate needs depends on how it models redundancy in NetBox.

vip — a role on an address of the same device

The classic modelling: the service address is created on one of the members’ interfaces and tagged with a role.

GET <url>/api/ipam/ip-addresses/?device_id=3&role=vip&role=vrrp

vip_roles says which roles count. The role is re-checked on the answer as well as sent as a filter — a filter parameter this server got wrong must never degrade into “every address on the device”, which would widen an allowlist without saying so.

fhrp — membership of an FHRP group

NetBox’s own model for first-hop redundancy: the service address is assigned to an ipam.FHRPGroup, and each member’s interface is recorded as belonging to that group.

client address ─▶ its interface ─▶ fhrp-group-assignments?interface_id=7
                                        └─▶ group ids ─▶ their addresses

The direction of that chain is the membership proof. A group is only ever reached through an assignment naming the client’s own interface. Nothing is ever looked up by group name, by the service address, or by the identifier the client asked for — so there is no query that could reach a group the client is not recorded in, and no way to turn the check into a lookup of “who owns this name?” by choosing a request carefully. An interface in no group contributes nothing and costs one request.

No role filter applies here: an address assigned to an FHRP group is the group’s service address by construction, and applying vip_roles would drop legitimately untagged VIPs.

A client connecting from the service address needs neither source — that address object comes back from the first query with its own names attached.

TLS

Unlike the challenge validators, where the certificate is deliberately not checked because the proof is what matters, NetBox’s certificate is the only thing identifying the service whose answers decide who may have a name certified. The public roots apply, plus any operator-supplied CA. Switching that off is explicit, logged on every start, and meant to be temporary.

Configuration

[ipam]
backend = "netbox"

[ipam.netbox]
url = "https://netbox.internal.example.com"
token = "your_netbox_read_only_token"
custom_field = "acme_domains"
sources = ["dns_name", "custom_field", "device"]

Turning on service addresses:

[ipam.netbox]
sources = ["dns_name", "custom_field", "device", "vip", "fhrp"]
vip_roles = ["vrrp", "carp"]

Reference

url (String) — Default: "" | Env: ACME_PROXY_IPAM__NETBOX__URL

Base URL of the NetBox instance. Any path is kept, so an instance served under a subpath works. Required when ipam.backend is netbox.

token (String) — Default: "" | Env: ACME_PROXY_IPAM__NETBOX__TOKEN

NetBox API token, of either generation — see Authenticating. A secret: prefer the environment variable.

custom_field (String) — Default: "acme_domains" | Env: ACME_PROXY_IPAM__NETBOX__CUSTOM_FIELD

Custom field holding the permitted names, on the address object and on its device or virtual machine. Only read when sources names custom_field or device.

sources (Array) — Default: ["dns_name", "custom_field", "device"] | Env: ACME_PROXY_IPAM__NETBOX__SOURCES

Where a permitted name may come from. All five sources are available here. See Sources.

vip_roles (Array) — Default: ["vip", "vrrp", "hsrp", "glbp", "carp", "anycast"] | Env: ACME_PROXY_IPAM__NETBOX__VIP_ROLES

Which NetBox address roles mark a service address. Read only when sources names vip, so this is which roles rather than whether to look at all.

ca_cert_path (String) — Default: "" | Env: ACME_PROXY_IPAM__NETBOX__CA_CERT_PATH

Extra CA certificates (PEM) to trust on top of the public roots, for a NetBox behind an internal PKI. Ignored when insecure_skip_verify is on.

insecure_skip_verify (Boolean) — Default: false | Env: ACME_PROXY_IPAM__NETBOX__INSECURE_SKIP_VERIFY

Skip verification of NetBox’s TLS certificate entirely. Meant as a temporary way out of an expired NetBox certificate. Startup logs an ipam_netbox_tls_verification_disabled warning for as long as it is set.