Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Corefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
password {$OMADA_PASSWORD}
refresh_minutes 1
ignore_startup_errors {$OMADA_IGNORE_STARTUP_ERRORS}
fallthrough ${FALLTHROUGH_ZONES}
}
forward . {$UPSTREAM_DNS}
}
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# docker buildx use multiplatform
# docker buildx inspect --bootstrap

FROM --platform=$BUILDPLATFORM golang:1.24-bookworm as builder
FROM --platform=$BUILDPLATFORM golang:1.25-bookworm as builder
ARG TARGETOS TARGETARCH
RUN apt update
RUN apt install git curl jq -y
Expand Down Expand Up @@ -43,4 +43,5 @@ COPY --from=builder /coredns/coredns /coredns
COPY Corefile /Corefile
EXPOSE 53 53/udp
ENV OMADA_IGNORE_STARTUP_ERRORS=FALSE
ENV FALLTHROUGH_ZONES="."
ENTRYPOINT ["/coredns"]
8 changes: 8 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type config struct {
resolve_dhcp_reservations bool // resolve static 'dhcp reservations'
stale_record_duration time.Duration // duration to keep serving stale records for clients no longer present in the controller)
ignore_startup_errors bool // ignore any errors during the initial zone refresh
fallthrough_zones *[]string // list of fallthrough zones
}

func parse(c *caddy.Controller) (config config, err error) {
Expand Down Expand Up @@ -126,6 +127,13 @@ func parse(c *caddy.Controller) (config config, err error) {
return config, c.ArgErr()
}

case "fallthrough":
fallthroughZones := c.RemainingArgs()
config.fallthrough_zones = &fallthroughZones
if err != nil {
return config, c.ArgErr()
}

default:
return config, c.Errf("unknown property: %q", c.Val())
}
Expand Down
1 change: 1 addition & 0 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func TestConfig(t *testing.T) {
resolve_devices true
resolve_dhcp_reservations true
stale_record_duration 10m
fallthrough
}`, false},

// missing required property: controller url
Expand Down
12 changes: 12 additions & 0 deletions corefile-examples/fallthrough/Corefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
. {
health :8080
omada {
controller_url https://10.0.0.2
site Home
username coredns-omada
password coredns-omada
refresh_minutes 1
fallthrough
}
forward . 10.0.0.1
}
34 changes: 21 additions & 13 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ Example corefiles are located [here](../corefile-examples)

## Omada plugin configuration syntax

| Name | Required | Type | Notes |
|---------------------------|----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| controller_url | ✅ | string | address of the Omada controller. Include `https://` prefix |
| site | ✅ | string | name of the site from the Omada controller (note this is a regex pattern) |
| username | ✅ | string | Omada controller username |
| password | ✅ | string | Omada controller password |
| refresh_minutes | ❌ | int | How often to refresh the zones (default 1 minute) |
| refresh_login_hours | ❌ | int | How often to refresh the login token (default 24 hours) |
| resolve_clients | ❌ | bool | Whether to resolve client addresses (default true) |
| resolve_devices | ❌ | bool | Whether to resolve device addresses (default true) |
| resolve_dhcp_reservations | ❌ | bool | Whether to resolve device addresses (default true) |
| Name | Required | Type | Notes |
| ------------------------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| controller_url | ✅ | string | address of the Omada controller. Include `https://` prefix |
| site | ✅ | string | name of the site from the Omada controller (note this is a regex pattern) |
| username | ✅ | string | Omada controller username |
| password | ✅ | string | Omada controller password |
| refresh_minutes | ❌ | int | How often to refresh the zones (default 1 minute) |
| refresh_login_hours | ❌ | int | How often to refresh the login token (default 24 hours) |
| resolve_clients | ❌ | bool | Whether to resolve client addresses (default true) |
| resolve_devices | ❌ | bool | Whether to resolve device addresses (default true) |
| resolve_dhcp_reservations | ❌ | bool | Whether to resolve device addresses (default true) |
| stale_record_duration | ❌ | duration | How long to keep serving stale records for clients/devices which are no longer present in the Omada controller. Specified in Go time [duration](https://pkg.go.dev/time#ParseDuration) format |
| ignore_startup_errors | ❌ | bool | ignore connection/configuration errors to the omada controller on startup. Set this to true if you want coredns to startup even if unable to connect to omada (default false) |

| ignore_startup_errors | ❌ | bool | ignore connection/configuration errors to the omada controller on startup. Set this to true if you want coredns to startup even if unable to connect to omada (default false) |
| fallthrough [ZONES...] | ❌ | []string | Whether to enable fallthrough. If fallthrough statement is present but no zone is specified then defaults to all zones, equivilent to:<br> `fallthrough .` |

## Credentials

Expand All @@ -30,6 +30,14 @@ For this service you should create a new user in the `Admin` page of the control

A single Omada controller can support multiple network sites. This plugin can be configured to use multiple sites via the `site` configuration property (regex). Multiple sites can be specified using the `|` separator like this `SiteA|SiteB|SiteC` or all sites can be selected by setting it to `.*`

## Fallthrough behaviour

The `fallthrough` option controls the behaviour for records which are not found. If fallthrough is enabled then requests for records which are not found are passed to the next plugin in the chain. If fallthrough is disabled then records which are not found are returned an `NXDOMAIN` response by the coredns_omada plugin and processing stops without being passed down the plugin chain.

The use case for using fallthrough is to use other plugins to handle queries for the same zone as `coredns_omada` such as the [file](https://coredns.io/plugins/file/) plugin.

Note: prior to the fallthrough option being implemented, the default behaviour enabled fallthrough.

## HTTPS Verification

This will depend on your network and configuration, but due to the lack of a suitable internal DNS resolution you may need to disable HTTPS verification to the controller, as even if you have a valid certificate on your controller you need a valid DNS record pointing to your controller where coredns is running.
Expand Down
11 changes: 8 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ CoreDNS plugins need to be compiled into CoreDNS, you can follow the [build](bui

This guide provides three options on how to run CoreDNS:

- [CoreDNS binary](#coredns-binary)
- [Docker container](#docker)
- [Kubernetes](#kubernetes)
- [CoreDNS binary](#coredns-binary)
- [Docker](#docker)
- [Kubernetes](#kubernetes)

### CoreDNS binary

Expand All @@ -52,8 +52,13 @@ Note: If you do not have a valid https certificate on your controller then set t
* `OMADA_PASSWORD`
* `UPSTREAM_DNS`

The pre-built images support these optional environment variables:
* `OMADA_IGNORE_STARTUP_ERRORS` = `true` | `false`
* `FALLTHROUGH_ZONES` - defaults to all zones `.` to maintain previous compatibility. To disable fallthrough completely either set this a a fake zone (e.g `FALLTHROUGH_ZONES=disabled`) or mount a custom Corefile.

Note: If you do not have a valid https certificate on your controller then set the `OMADA_DISABLE_HTTPS_VERIFICATION` environment variable to true


Example docker run command:
```
docker run \
Expand Down
44 changes: 23 additions & 21 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
module github.com/dougbw/coredns_omada

go 1.24.0
go 1.25.0

require (
github.com/coredns/caddy v1.1.2-0.20241029205200-8de985351a98
github.com/coredns/coredns v1.12.3
github.com/coredns/caddy v1.1.4
github.com/coredns/coredns v1.14.1
github.com/dougbw/go-omada v0.6.2
github.com/go-playground/validator/v10 v10.27.0
github.com/miekg/dns v1.1.68
github.com/stretchr/testify v1.10.0
github.com/go-playground/validator/v10 v10.30.1
github.com/miekg/dns v1.1.72
github.com/stretchr/testify v1.11.1
)

require (
Expand All @@ -17,7 +17,7 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
Expand All @@ -28,21 +28,23 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.0 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.19.2 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.59.0 // indirect
go.uber.org/mock v0.6.0 // indirect
golang.org/x/crypto v0.41.0 // indirect
golang.org/x/mod v0.27.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/tools v0.36.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 // indirect
google.golang.org/grpc v1.75.0 // indirect
google.golang.org/protobuf v1.36.8 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/mod v0.33.0 // indirect
golang.org/x/net v0.50.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/tools v0.42.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect
google.golang.org/grpc v1.79.1 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading