Split DNS forwarding from Unifi gateway

When using Traefik, or any other reverse proxy, in front of docker containers you need a proper domain to get an SSL certificate from LetsEncrypt. You also need a proper public DNS for the domain to allow LetsEncrypt to verify ownership via DNS or web requests. If you want to use this for internal systems you either need to add all the private A records to the public DNS or make a split zone. A DNS split means that some requests are forwarded to an internal DNS while all else is resolved by a public DNS on the internet.

Unifi gateways have support for DNS splitting but no UI for configuring it. I have written about the config.gateway.json file before. You can do a lot more config with the file but you have to make sure to keep it backed up and available at all or the settings will be overwritten. The last time I wrote about it was on a proper Ubuiqiti Cloud Key, in this example, I’m using the Unifi Controller in a docker container which presents its own challenges.

Configure the docker container

I’m using the unifi-controller image from linuxserver.io that has more than 100 million pulls from the docker hub, so I presume I’m not alone. As usual, their documentation is really good, I have only changed two things from the recommended config. Besides the volume mounted to /config in the container, I have mounted two more.

/usr/lib/unifi/data/sites – this folder will contain all the sites in your deployment. In my home deployment, I only have the default folder. In this folder, you place the config.gateway.json file to provide additional configuration to your gateway device. By mapping this to a folder on my NFS share I can easily access and change the config.gateway.json file without having to execute a bash inside the docker container.

/usr/lib/unifi/data/backup/autobackup – this has nothing to do with the DNS split but is very nice to have. This gives you access to the backup files the Unifi Controller creates daily and allows you to restore the controller from scratch. The backups also includes the config.gateway.json as well.

Setting up the controller

If your sites folder is empty you need the controller to create the site folder. If you create it your self it will not be picked up. The easiest way to get the controller to initialize the folder is to upload an image in the Map > Floorplan > Add new floorplan. That will create the folder and allow you to drop in the config.gateway.json file with additional config.

{
   "service":{
      "dns":{
         "forwarding":{
            "options":[
               "server=/internaldomain.com/192.168.93.151",
               "server=1.1.1.1",
               "server=8.8.8.8"
            ]
         }
      }
   }
}

The configuration above is put into the config.gateway.json inside the site/default folder in my case. This will send all DNS queries for internaldomain.com to my internal DNS server on 192.168.93.151.

At the same time, my external Cloudflare DNS will resolve the same domain name and allow Traefik to update the DNS to verify ownership of the domain and issue a valid certificate that works for all my internal clients.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: