Dynamic DNS allowlist plugin for Traefik: Add your dynamic hostname (your homenetwork router) to the allow list.
Have a look at the official Traefik Plugin Catalog. We would love if you leave a star on this repository.
The ddns-allowlist
plugin for Traefik allows you to add dynamic DNS (DDNS) hosts to the allowed requesters.
Requests from IP addresses that do not resolve to the specified DDNS hosts will be denied.
You might also know this as whitelist instead of allowlist.
The initial idea is that you can add your home router with a floating (non-static) IP address to an allowed list of addresses. You are not limited to your DDNS supporting router - you can add any host you like. If you want so it is more likely a hostname allowlist.
The basic concept is to periodically resolve the hostname to an IP address and add it to the allowlist.
Because server typically have a static IP, you should add its static IPs to the allowlist (sourceRangeIps
).
:warning: IPv6 is supported but e.g. with FritzBox router you maybe have some issues because the IPv6 address your router provides is not the same as the network prefix of your network.
The installation of a Traefik plugin is pretty simple.
To install the ddns-allowlist
plugin follow one of the following methods.
First way to add the plugin is to add the following CLI options to your Traefik setup:
--experimental.plugins.ddns-allowlist.modulename=github.com/taskmedia/ddns-allowlist--experimental.plugins.ddns-allowlist.version=v1.6.1
Another way to add the plugin is to add the following configuration to your Traefik static configuration / Helm chart:
experimental:plugins:ddns-allowlist:moduleName: "github.com/taskmedia/ddns-allowlist"version: v1.6.1
You also need to create a middleware and add it to one of your routes. There are multiple ways to do this - this document will show you how to configure the plugin with dynamic configuration and Kubernetes CRD.
But first we will have a look about the configuration options available for the plugin.
Only mandatory option is sourceRangeHosts
- all other options are optional.
sourceRangeHosts
(required)sourceRangeIps
ipStrategy.*
RemoteAddr
as default.ipStrategy.cloudflareDepth
Cf-Connecting-Ip
) to determine the client IP address.
The cloudflareDepth option expects an integer to determ which IP address should be used (starting from the right).ipStrategy.depth
X-Forwarded-For
) to determine the client IP address.
The depth option expects an integer to determ which IP address should be used (starting from the right).ipStrategy.excludedIPs
X-Forwarded-For
header).rejectStatusCode
logLevel
lookupInterval
allowedIPv6NetworkPrefix
Hint: You can only choose one of the ip strategy options. It is not possible to combine multiple. The strategies are similar to the one provided with middleware IPWhiteList.
Add the ddns-allowlist
middleware to your Traefik dynamic configuration:
# Dynamic configurationhttp:routers:my-router:rule: host(`demo.localhost`)service: service-fooentryPoints:- webmiddlewares:- ddns-allowlist-routerservices:service-foo:loadBalancer:servers:- url: http://127.0.0.1:5000middlewares:ddns-allowlist-router:plugin:my-ddnswl:# optional: log level for the plugin (allowed: ERROR, INFO, DEBUG, TRACE - default: ERROR)logLevel: ERROR# hosts to dynamically add to allowlist via DNS lookupsourceRangeHosts:- my.router.ddns.tld# optional: IP addresses to allowlistsourceRangeIps:- 1.2.3.4# optional: IP strategy to determine the client IP address (default: RemoteAddr)# also see: https://doc.traefik.io/traefik/middlewares/http/ipwhitelist/#ipstrategyipStrategy:depth: 1cloudflareDepth: 1excludedIPs:- 4.3.2.1# optional: allow IPv6 interface identifier based on given prefix# this will skip the interface identifier validation (default: disabled)allowedIPv6NetworkPrefix: 64# optional: lookup interval for DNS hosts in seconds (default: 5 min)lookupInterval: 60
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: my-ddnswlspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tld# see other options in dynamic configuration or in section 'Available options'
Also see more detailed in the examples section.
This section contains example configurations for the ddns-allowlist
plugin.
The examples are provided as in Kubernetes CRD but also can be defined in other formats.
You need to expand the configuration example in each section on the triangle.
It shows different common configuration options. Keep note that the IP strategies can not be combined with each other.
The following examples are alphabetically sorted and not according to the frequency of use.
When using IPv6 your home router will report its full address to the DDNS provider. This address contains the network prefix and the interface identifier. When an device inside your network tries to access your service it will be rejected because the interface identifier is not the same as the one from your router. With this option you can allow any interface identifier based on the given prefix from the looked up sourceRangeHosts IPv6 addresses.
The common value used for that is 64
.
This is the common value which splits the address into network prefix and interface identifier.
If your routers DNS lookup resolves in IP address aaaa:bbbb:cccc:dddd:1111:2222:3333:4444
, the addresses in network aaaa:bbbb:cccc:dddd::/64
will be allowed.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldallowedIPv6NetworkPrefix: 64
If you are using Cloudflare as DNS nameserver (without proxy), you need to use the default configuration using RemoteAddr
(no IP strategy required in plugin config).
Also see RemoteAddr example.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-cloudflare-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tld
If you are using Cloudflare as DNS nameserver (with proxy), you need to get the IP address of the client from the Cf-Connecting-Ip
header.
Therefore use the cloudflareDepth
configuration option.
Usually the header only contains one IP address - so you can use 1
as value.
To ensure the same implementation as in ipStrategy.depth
you are allowed to specify a higher value.
But this configuration should not be necessary.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-cloudflare-proxyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldipStrategy:cloudflareDepth: 1
If you want to get the client IP address from the X-Forwarded-For
header but exclude some IPs from the list (eg. your reverse proxies), you can use the excludedIPs
option.
This will allow you to exclude some IPs from the list and return the first IP address that is not in the excluded list.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-excludeipsspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldipStrategy:excludedIPs:- 1.2.3.4
If you want to see more logs from the plugin, you can set the log level to a more detailed level.
The allowed values are ERROR
(default), INFO
, DEBUG
, TRACE
.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldlogLevel: DEBUG
If you want to change the lookup interval for DNS hosts, you can set the lookupInterval
option.
The default value is 300
seconds (5 minutes).
The lookup will only happen if the middleware is triggered from a new client request.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldlookupInterval: 30 # seconds
If you feel more like a tea pot feel free to change the rejection code:
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldrejectStatusCode: 418
If you are not using any proxy in front of your Traefik instance, you can just use the RemoteAddr
as default IP strategy.
You only need to specify a host to be allowlisted.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tld
If you want to add additional IP addresses to the allowlist (e.g. a server), you can use the sourceRangeIps
option.
This might also be interesting to add your static IPv6 address (network prefix).
You are not only able to add IPv4 addresses but also IPv6 addresses. Also it is possible to add an IP range (CIDR notation) to the list.
Keep note that you always need to specify a source range host.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldsourceRangeIps:- "1.2.3.4"- "192.168.1.0/24"- "2a02:aaaa:bbbb:cccc::/64"
If you are using a reverse proxy in front of your Traefik instance, you can use the X-Forwarded-For
header to determine the client IP address.
You can specify the depth of the IP address in the header to use.
The default value is 1
and will select the first IP address from the header (position starting from the right).
You are not able to specify a depth of 0 - otherwise the RemoteAddr method (default) will be used.
apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: ddnswl-dnsonlyspec:plugin:ddns-allowlist:sourceRangeHosts:- my.router.ddns.tldipStrategy:depth: 1