Code Monkey home page Code Monkey logo

coredns-netbox-plugin's Introduction

coredns-netbox-plugin

This plugin gets an A record from NetBox1. It uses the REST API of netbox to ask for a an IP address of a hostname:

curl https://netbox.example.org/api/ipam/ip-addresses/?dns_name=example-vm-host

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "family": {
                "value": 4,
                "label": "IPv4"
            },
            "address": "192.168.1.101/25",
            "interface": {
                "id": 452,
                "url": "https://netbox.example.org/api/virtualization/interfaces/452/",
                "virtual_machine": {
                    "url": "https://netbox.example.org/api/virtualization/virtual-machines/10/",
                },
            },
        }
    ]
}

Enabling

To activate the netbox plugin you need to compile CoreDNS with the plugin added to plugin.cfg

netbox:github.com/oz123/coredns-netbox-plugin

Ordering in plugin.cfg

The ordering of plugins in the plugin.cfg file is important to ensure you get the behaviour you expect when using multiple plugins in a Corefile server block.

For example, in order to utilise the native cache plugin, ensure that you add the netbox plugin after cache:cache but before any plugins you want to be able to fall-through to (eg file:file or forward:forward).

Syntax

netbox [ZONES...] {
  token TOKEN
  url URL
  tls CERT KEY CACERT
  fallthrough [ZONES...]
}
  • ZONES zones that the netbox should be authoritative for.

  • token TOKEN sets the API token used to authenticate against NetBox (REQUIRED).

  • url URL defines the URL netbox should query. This URL must be specified in full as SCHEME://HOST/api/ipam/ip-addresses (REQUIRED).

  • tls is followed by:

    • no arguments, if the server certificate is signed by a system-installed CA and no client cert is needed (this is the default if HTTPS is used).
    • a single argument that is the CA PEM file, if the server cert is not signed by a system CA and no client cert is needed.
    • two arguments - path to cert PEM file, the path to private key PEM file - if the server certificate is signed by a system-installed CA and a client certificate is needed.
    • three arguments - path to cert PEM file, path to client private key PEM file, path to CA PEM file - if the server certificate is not signed by a system-installed CA and client certificate is needed.

    These options set certificate verification method for the NetBox server if HTTPS is used to access the API.

  • ttl DURATION defines the TTL of records returned from netbox. Default is 1h (3600s).

  • timeout DURATION defines the HTTP timeout for API requests against NetBox. Default is 5s.

  • fallthrough If a zone matches but no record can be generated, pass request to the next plugin. If [ZONES…] is omitted, then fallthrough happens for all zones for which the plugin is authoritative. If specific zones are listed then only queries for those zones will be subject to fallthrough.

The config parameters token, url and localCacheDuration are required.

Examples

Send all requests to NetBox:

. {
    netbox {
        token SuperSecretNetBoxAPIToken
        url https://netbox.example.org/api/ipam/ip-addresses
    }
}

Send requests within example.org to NetBox and fall-through to the file plugin in order to respond to unsupported record types (ie SOA, NS etc):

. {
    netbox example.org {
        token SuperSecretNetBoxAPIToken
        url https://netbox.example.org/api/ipam/ip-addresses
        fallthrough
    }
    file db.example.org
}

Handle all requests with netbox and fall-through to the forward plugin for requests within example.org with caching via the cache plugin:

. {
    netbox {
        token SuperSecretNetBoxAPIToken
        url https://netbox.example.org/api/ipam/ip-addresses
        fallthrough example.org
    }
    forward . 1.1.1.1 1.0.0.1
    cache
}

Changelog

0.2 - Cleanup add IPv6 support

  • Refactor query.go
  • Add tests for IPv6
  • Enable IPv6 in query.go

0.1 - Initial Naive release

  • Got it somehow working
  • Gather feedback

Developing locally

You can test the plugin functionallity with CoreDNS by adding the following to go.mod in the source code directory of coredns.

replace github.com/oz123/coredns-netbox-plugin => <path-to-you-local-copy>/coredns-netbox-plugin

Testing against a remote instance of netbox is possible with SSH port forwarding:

Host YourHost
   Hostname 10.0.0.91
   ProxyJump YourJumpHost
   LocalForward 18443 192.168.1.128:8443

Credits

This plugin is heavily based on the code of the redis-plugin for CoreDNS.

coredns-netbox-plugin's People

Contributors

andrewheberle avatar dependabot[bot] avatar hvanderheide avatar kotso avatar oz123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

coredns-netbox-plugin's Issues

plugin/netbox: no next plugin found with fallthrough

Hi there 👋. I'm trying to setup this plugin.

The expected behavior is:

  • Look into Netbox
  • If not found look into the file
  • All other requests into the corporate DNS

Current result:

  • Dig to a value placed in netbox: OK
  • Dig to a value placed into the file: NOK
  • Dig a corporate entry: OK

Config

Plugin.cfg order: netbox --> file --> forward

Corefile:

si.gre.hpecorp.net:53 {
    netbox si.gre.hpecorp.net {
        token secret
        url http://cmsgtest3.gre.hpecorp.net:8000/api/ipam/ip-addresses
        localCacheDuration 300s
        fallthrough 
        timeout 3s
    }
    file /config/db.si.gre.hpecorp.net
    log
    errors
}

.:53 {
    forward . 16.110.135.51 16.110.135.52
    log
    errors
}

db.si.gre.hpecorp.net file

$ORIGIN si.gre.hpecorp.net.
$TTL 1h               ; default expiration time of all resource records without their own TTL value

; =============================== Resource Records ==============================

@	3600 IN	SOA ns1.si.gre.hpecorp.net. admin.si.gre.hpecorp.net. (
				1           ; serial
				7200        ; refresh (2 hours)
				3600        ; retry (1 hour)
				1209600     ; expire (2 weeks)
				3600        ; minimum (1 hour)
				)

	3600 IN NS ns1.si.gre.hpecorp.net.
	3600 IN NS ns2.si.gre.hpecorp.net.

nico IN A 192.168.28.201

Log

[INFO] Started netbox plugin version 0.1.1-dev
.:53
si.gre.hpecorp.net.:53
CoreDNS-1.9.1
linux/amd64, go1.17.8, 
[INFO] Recored not found in{"count":0,"next":null,"previous":null,"results":[]}
[INFO] 172.17.0.1:44278 - 64076 "A IN nico.si.gre.hpecorp.net. udp 64 false 4096" - - 0 1.570978228s
[ERROR] plugin/errors: 2 nico.si.gre.hpecorp.net. A: plugin/netbox: no next plugin found

If I remove the netbox config from the Corefile and keep only the file config I can validate that the "nico" entry is ok.

And BTW it would be nice to read first the file and then ask Netbox. I haven't been able to setup this.

Bug with NXDOMAIN PR

The most recent PR looks to have introduced a bug where a valid response from NetBox returns the proper address in addition to NXDOMAIN. I'm very new to Go so I wanted to post it here as I continue to look into it. Thx

I have the following defined in my NetBox:

devkea.homelab.bjzy.me 192.168.50.2
devcoredns.homelab.bjzy.me 192.168.50.60
devnetbox.homelab.bjzy.me 192.168.50.7

When querying nonexistent names, everything is expected:

❯ nslookup something.homelab.bjzy.me 192.168.50.60
Server:		192.168.50.60
Address:	192.168.50.60#53

** server can't find something.homelab.bjzy.me: NXDOMAIN

❯ nslookup else.homelab.bjzy.me 192.168.50.60
Server:		192.168.50.60
Address:	192.168.50.60#53

** server can't find else.homelab.bjzy.me: NXDOMAIN

But when query a valid name, it returns proper IP in addition to NXDOMAIN:

❯ nslookup devkea.homelab.bjzy.me 192.168.50.60
Server:		192.168.50.60
Address:	192.168.50.60#53

Name:	devkea.homelab.bjzy.me
Address: 192.168.50.2
** server can't find devkea.homelab.bjzy.me: NXDOMAIN

❯ nslookup devcoredns.homelab.bjzy.me 192.168.50.60
Server:		192.168.50.60
Address:	192.168.50.60#53

Name:	devcoredns.homelab.bjzy.me
Address: 192.168.50.60
** server can't find devcoredns.homelab.bjzy.me: NXDOMAIN

❯ nslookup devnetbox.homelab.bjzy.me 192.168.50.60
Server:		192.168.50.60
Address:	192.168.50.60#53

Name:	devnetbox.homelab.bjzy.me
Address: 192.168.50.7
** server can't find devnetbox.homelab.bjzy.me: NXDOMAIN

Corefile:

#/etc/coredns/Corefile
homelab.bjzy.me {
    netbox {
        token ba5b0d53c7968ebbe15a47d9ab891b512f50e46a
        url https://devnetbox.homelab.bjzy.me/api/ipam/ip-addresses
    }
    whoami
    health
    prometheus 0.0.0.0:9153
    log
    errors
}

Cannot build the plugin

Building in FreeBSD 12.2 jail with go 1.15.6 as plugin of CoreDNS 1.8.0:

...
# github.com/oz123/coredns-netbox-plugin
../coredns-netbox-plugin/setup.go:28:31: cannot use setup (type func(*"github.com/caddyserver/caddy".Controller) error) as type "github.com/coredns/caddy".SetupFunc
in argument to plugin.Register
../coredns-netbox-plugin/setup.go:43:20: undefined: metrics.MustRegister
../coredns-netbox-plugin/setup.go:48:21: cannot use c (type *"github.com/caddyserver/caddy".Controller) as type *"github.com/coredns/caddy".Controller in argument to
 dnsserver.GetConfig
*** Error code 2

PTR record if asked for an IP

Would be cool if the plugin could also do the reverse record and check if the for a requested IP (something like this: 1.178.168.192.in-addr.arpa) a hostname is defined (PTR record / reverse DNS).

Support for netbox-dns plugin

I'm using the netbox-dns-plugin, which extends NetBox with complete DNS zone management functionality. This adds additional features like zones and other record types. It'd be great if I could query this information from coredns with your plugin.

I had a look at the plugin code and have some ideas how to implement this. I'd add a boolean argument in setup.go, which toggles if the native API or the DNS plugin API is used.

case "zoneplugin":
	if !c.NextArg() {
		return nil, c.ArgErr()
	}
	zoneplugin, err := strconv.ParseBool(c.Val())
	if err != nil {
		return n, c.Errf("could not parse 'zoneplugin': %s", err)
	}
	n.ZonePlugin = zoneplugin

Then I'd convert func query() to a wrapper function which calls either the existing query() (renamed to e.g. queryNative()) function or a new function queryZonePlugin().

func (n *Netbox) query(host string, family int) ([]net.IP, error) {
	if n.ZonePlugin {
		return n.queryZonePlugin(host, family)
	}
	return n.queryNative(host, family)
}

I'd be happy to try and implement that functionality into your plugin, if you find this useful.

tag release please!

Hi, when building this plugin for coredns i got an error due to this commit : d43c0e5

coredns pull the latest stable version rather than master.

Can you please tag a stable release?

Or perhaps there's a way to tell CoreDNS to build coredns-netbox-plugin from master branch?

Thanks!

Please, release a new version

The commit f7cca1e is really important, it prevents failure of CoreDNS service on Netbox error. Please, release a new version with this commit integrated.

CoreDNS server crashes

CoreDNS server with the plugin loaded crashes if the Netbox server is not available:

[FATAL] HTTP Error Get "http://10.111.1.130:8080/api/ipam/ip-addresses/?dns_name=aniva.reseaucloud.local": dial tcp 10.111.1.130:8080: connect: connection refused
consul.reseaucloud.local.:53
reseaucloud.local.:53
.:53
CoreDNS-1.8.0
freebsd/amd64, go1.15.6,

Zone reseaucloud.local. is configured to be resolved using Netbox plugin.

Please, fix the problem.

Fix fall through behaviour

The "fall-through when a record doesn't exist" should not be a default/implicit behavior. See how this kind of behavior is implemented in other plugins (e.g. hosts plugin).

Unable to "parse netbox config" issue?

I'm trying to connect coredns with my netbox configuration and am running into this issue:

plugin/netbox: Could not parse netbox config

My Corefile looks like this:

.lan {
        netbox {
          url https://[my.domain]/api/ipam/ip-addresses
          token 7[...]3
        }

        cache 10
        log
        errors
}

I tested that API address in Postman w/ the proper credentials and it was able to get information, so I don't think its a permission issue. Anything else I can check?

Trouble with fallthrough

Hey there, I'm having some trouble getting the fallthrough to actually fallthrough. With "test1.example.com" in the local zonefile and "test2.example.com" in netbox I'm getting the following behavior:

Giventhe Corefile:

#    netbox {
#        token MyTokenHere
#        url http://10.20.30.40/api/ipam/ip-addresses
#        fallthrough
#    }

    file /etc/coredns/example.com
}

Queries to test1.example.com resolve and test2.example.com fail. Given the Corefile:

    netbox {
        token MyTokenHere
        url http://10.20.30.40/api/ipam/ip-addresses
        fallthrough
    }

#    file /etc/coredns/example.com
}

Queries to test1.example.com fail and test2.example.com resolve. Given the Corefile:

    netbox {
        token MyTokenHere
        url http://10.20.30.40/api/ipam/ip-addresses
        fallthrough
    }

    file /etc/coredns/example.com
}

Queriest to test1.example.com still fail and test2.example.com resolve. I'm not quite sure why fallthrough isn't letting the file's answer resolve. One thing I thought is maybe I have the plugin position wrong but it's before "file:file":

metadata:metadata
geoip:geoip
cancel:cancel
tls:tls
timeouts:timeouts
reload:reload
nsid:nsid
bufsize:bufsize
bind:bind
debug:debug
trace:trace
ready:ready
health:health
pprof:pprof
prometheus:metrics
errors:errors
log:log
dnstap:dnstap
local:local
dns64:dns64
acl:acl
any:any
chaos:chaos
loadbalance:loadbalance
tsig:tsig
cache:cache
netbox:github.com/oz123/coredns-netbox-plugin
rewrite:rewrite
header:header
dnssec:dnssec
autopath:autopath
minimal:minimal
template:template
transfer:transfer
hosts:hosts
route53:route53
azure:azure
clouddns:clouddns
k8s_external:k8s_external
kubernetes:kubernetes
file:file
auto:auto
secondary:secondary
etcd:etcd
loop:loop
forward:forward
grpc:grpc
erratic:erratic
whoami:whoami
on:github.com/coredns/caddy/onevent
sign:sign
view:view

And even trying it at the very end of the list or very beginning of the list isn't changing the behavior.

Query fails if no AAAA record is available in netbox

Hi,

I am using the latest version from master branch.
When a device has an IPv4 and IPv6 DNS name assigned in netbox, everything works fine. The name can be resolved, the answer contains both records.

However, if a device only has an IPv4 assigned, we are running into the following issue:

bash-5.1# ping device.blabla.local
ping: device.blabla.local: Name does not resolve
bash-5.1# nslookup   device.blabla.local
Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	device.blabla.local
Address: 172.29.14.1
** server can't find device.blabla.local: NXDOMAIN

When I check the logs, I can see the following info:

[INFO] 172.29.90.1:1770 - 29865 "A IN device.blabla.local. udp 47 false 512" NOERROR qr,aa,rd 92 0.048924982s
[INFO] 172.29.90.1:55350 - 33929 "AAAA IN device.blabla.local. udp 47 false 512" NXDOMAIN qr,aa,rd 47 0.044846348s
[INFO] 172.29.90.1:4305 - 63751 "A IN device.blabla.local. udp 47 false 512" NOERROR qr,aa,rd 92 0.000204359s

I guess the problem is that NXDOMAIN is returned for AAAA, even if a record for A was found.

module name incorrect -- plugin won't build

Attempting to build on a Mac w/ go1.15. It appears to me that the module name for the plugin should be github.com/oz123/coredns-netbox-plugin rather than just coredns-netbox-plugin. It's causing import errors:

TDavis-MACBOOK-6:coredns tdavis$ go generate
TDavis-MACBOOK-6:coredns tdavis$ go build
go: finding module for package github.com/oz123/coredns-netbox-plugin
go: found github.com/oz123/coredns-netbox-plugin in github.com/oz123/coredns-netbox-plugin v0.0.1
go: github.com/coredns/coredns imports
	github.com/coredns/coredns/core/plugin imports
	github.com/oz123/coredns-netbox-plugin: github.com/oz123/[email protected]: parsing go.mod:
	module declares its path as: coredns-netbox-plugin
	        but was required as: github.com/oz123/coredns-netbox-plugin

Instructions on coredns yield error

The instructions to install this module on the CoreDNS website say:

20220211 12_02_55

The trailing slash yields an error and halts building while making CoreDNS:

github.com/coredns/coredns imports
        github.com/coredns/coredns/core/plugin imports
        github.com/oz123/coredns-netbox-plugin/: malformed import path "github.com/oz123/coredns-netbox-plugin/": trailing slash
make: *** [Makefile:23: core/plugin/zplugin.go] Error 1

IPv6 AAAA record support

Hello,
By reading your code, I can see you've prepared the support of IPv6 records.
If it can helps, Netbox's API can be used with '&family=4' or '&family=6' to filter addresses family.
So you don't have to filter by yourself.

But the localCache still lacks support of different record type, that's another thing.

Thanks for this code, we'll now be able to manage internal DNS zones directly from Netbox (as in 'source of truth').

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.