DuckDNS is a dynamic host to IP provider that is very popular, and in particular, with the caddy community, namely because DuckDNS has the nameserver setup such that any subdomain that is queried on the registered base domain resolves to the same IP address to which the base domain is registered to.
In other words, and as an example, a user registers, say example.duckdns.org
that points to an IP, say 1.1.1.1
and then any arbitrary subdomain such as test.example.duckdns.org
and the base domain example.duckdns.org
will resolve to 1.1.1.1
.
This is useful for reverse-proxy setups where virtual hosts based on domain names are matched and then redirected to their respective backend servers.
The notes are written symbolically where capital letters represent variable placeholders such that the setup described here should be applicable to any environment:
LAN_NETWORK
is the local LAN IP and netmask, for example 192.168.1.0/24
,DOMAIN
is the registered DuckDNS domain name, the FQDN being DOMAIN.duckdns.org
,VHOST_PROXY_NETWORK_IP
is the IP address of a computer on the local network that runs a reverse-proxy such as nginx, caddy, apache, tailwind, etc,Please be sure to substitute these as it is suitable depending on the given application.
It is favorable to have a split-view DNS setup, where any subdomains of DOMAIN.duckdns.org
will resolve to a local address if the DNS server is queried from within the local LAN network. Obviously, this is a great optimization because any services that are both local and public will then be accessed via LAN from the internal network and not through the Internet via the public IP address.
For a split view, the /etc/bind/named.conf
file should be edited to create an internal LAN zone, for example:
view "lan" { match-clients { localhost; 127.0.0.1; LAN_NETWORK; }; include "/etc/bind/named.conf.DOMAIN.duckdns.org"; }
where:
LAN_NETWORK
is the LAN network IP address and matching netmask (ex: 192.168.1.0/24
)
such that the lan
view will be matched for all clients querying the DNS server from the LAN_NETWORK
network. All other clients will query the DNS server via its external implicit view - or even, none at all, if the DNS server is not exposed to the Internet. For DuckDNS and similar dynamic DNS services, it is not required to have the DNS server exposed to the Internet, because any queries for the base domain DOMAIN.0x90.duckdns.org
or any subdomains thereof will be resolved via the DuckDNS nameservers and not via the local DNS server that is being set up. The local nameserver will just be resolving the IP addresses for the clients on the local network.
In turn the file /etc/bind/named.conf.DOMAIN.duckdns.org
will contain something akin to:
zone DOMAIN.duckdns.org { type master; notify yes; file "/etc/bind/db.DOMAIN.duckdns.org"; };
and /etc/bind/db.DOMAIN.duckdns.org
being:
The following is an example zone file that can be used to emulate the same behavior as DuckDNS on the local network:
$TTL 1H @ IN SOA DOMAIN.duckdns.org. root.DOMAIN.duckdns.org. ( 18 ; serial 2H ; refresh 1H ; retry 1D ; expire 1H ) ; minimum ; START RECORDS 300 IN NS DOMAIN.duckdns.org. * 300 IN A VHOST_PROXY_NETWORK_IP
where:
DOMAIN
is the name that you register with DuckDNS,VHOST_PROXY_NETWORK_IP
is the IP address of the DNS server for the local network (where presumably a caddy instance would be listening to forward requests to the correct backend services)
Depeding on the reverse-proxy, multiple entries would have to be created in order to redirect the subdmains to their correspondng service servers. For instance, the following caddy configuration file will set up the internal service s1
, or, as a FQDN s1.DOMAIN.duckdns.org
:
s1.DOMAIN.duckdns.org { tls VALID_EMAIL_ADDRESS reverse_proxy INTERNAL_HOST_OR_IP:INTERNAL_PORT { trusted_proxies LAN_NETWORK header_up Host {host} header_up X-Real-IP {remote} header_up X-Forwarded-Host {hostport} header_up X-Forwarded-For {remote} header_up X-Forwarded-Proto {scheme} } } s2.DOMAIN.duckdns.org { ... } s3.DOMAIN.duckdns.org { ... } ...
where:
VALID_EMAIL_ADDRESS
is an E-Mail address with which to generate certificates based on caddy's built in ability to use letsencrypt and ZeroDNS,INTERNAL_HOST_OR_IP
and INTERNAL_PORT
representing the local LAN hostname or IP and port where the s1
service is running,s2
and s3
, … are services that are configured more or less the same way,
DuckDNS registration just requires an E-Mail and then a DOMAIN
name can be set up to point to the public IP address of the server (or, following the example, the Gateway
node represented earlier with the diagram).