Working around incomplete Ubiquiti UniFi Security Gateway DNS Service

I’ve been having a long-running conversation with various folks in the Ubiquiti Forums here and here regarding the DNS service that is provided by the USG. The USG is just a DNS forwarder and will dutifully take DNS queries from your internal hosts and pass them to whatever DNS servers it received from your Internet provider over DHCP (or perhaps you manually changed them in the configuration). However, I run a medium-sized network on my internal LAN and I have various servers that I wish to access when I’m at home. A couple of examples are:

  • Synology DS1415+ Network Attached Storage
  • Mac mini running macOS Server
  • 3 different Linux Workstations
  • Windows workstation
  • The UniFi CloudKey Controller itself (this is a special case, which I’ll cover)

The Problem

The problem is that the USG provides only very rudimentary DNS services for your internal network. In fact, it provides only one type of DNS registration: Dynamic host name registration based on the Client Identifier coming from the DHCP request. The Client Identifier is how the USG records the name of your various systems on the internal network, which are populated in the Clients tab on your Controller. This is why you’ll see “garbage” on your Clients list like these:

You can override the default Client Identifier name for a given client by creating an Alias for it:

However, this is purely cosmetic and the Alias will only be visible in your Clients listing on the Controller (and in reports, analysis, insights, etc.). The issue you’ll face with a moderately complex network (or any network in which you have servers you wish to access) is that you won’t know what names they register with in the USG DNS, and even if you do (by checking the Clients tab on the Controller), you won’t be able to remember them (e.g. st-D052BC263C7B0001, which is my SmartThings Hub). Also, these Client Identifiers can often not be changed on the client, meaning you’ll be stuck always using them for resolution. As of this writing, there is currently no way in the GUI to update a DNS entry for a DHCP client.

There is also the issue of static DNS hosts. I have a Synology NAS and that NAS supports bonding of the two LAN interfaces to give me 2Gbps of throughput to the NAS. Unfortunately, when you bond the two NICs the Synology only supports a Manual IP assignment. That means that it won’t appear in the DNS resolution “table” on the USG at all, because it never retrieved its IP via DHCP. As of this writing, there is currently no way in the GUI to create a static DNS entry.

How DNS Registration works on the USG

When your client requests a DHCP address from the USG, that request includes a Client Identifier. That Identifier might be factory-set by the manufacturer (like in the SmartThings and Sonos examples below (e.g. Both Sonos Play:1’s and Play:5’s will register as “SonosZP”)), or it may be user-configurable on the device itself (e.g. my Apple TV in the Guest Room is named “Guest Room”). That Client Identifier is then inserted into the /etc/hosts table on the USG when requested via DHCP. You can log into your USG via SSH then cat /etc/hosts to see the table.     st-D052BC263C7B0001.localdomain  #on-dhcp-event b0:52:b8:26:37:bf     Guest-Room.localdomain  #on-dhcp-event b0:66:98:d6:b7:3a     SonosZP.localdomain     #on-dhcp-event b0:e:58:a4:d6:e9

The only modification that the USG makes (as of Controller firmware version 5.4.16) is to strip invalid DNS characters (e.g. a space) and replace them with a hyphen (-). Prior versions to Firmware 5.4.16 didn’t have this update and just gleefully registered names with invalid characters (which then couldn’t ever be used to resolve the host). Firmware 5.4.16 also, finally, allowed us to actually register hosts where we had specified an IP Reservation (previously these hosts would not be registered at all).

From Ubiquiti’s release notes for 5.4.16:

[USG] DHCP client hostname DNS registration improvements - strip invalid characters and register the remaining, and allow periods. Removed 'host-decl-name' from registration consideration, so hosts with DHCP reservations defined in the controller will have the client-provided client hostname registered.

These were both welcome improvements, but there were still three issues remaining that make the USG DNS less than useful:

  1. No local domain support, all hosts are registered as HOST.localdomain. So, that’s what you have to use to resolve them internally.
  2. No support for modifying an existing DNS entry that was registered using a Client Identifier.
  3. No support for creating a static DNS entry.

As of Firmware version 5.5.19, Ubiquiti gave us back the local domain:

• Add DHCP default domain support.

So, only the other two issues remain and here’s how to work around them.

The Solution

There is no support in the USG GUI to resolve these remaining two issues, but fortunately we can configure the USG via config.gateway.json. When I initially read that article, I had several difficulties that I had to work through to understand how to perform this configuration. The most glaring issue was that when the article tells you, “For every site, you will find a unique random string that assigns to the site.”, this appears to be completely false. If you haven’t changed your site name from “default”, then that “random string” is actually the string “default”. I suspect that other site names are equally not “random”, but I only have the one site, so it didn’t matter. The other issue I had was figuring out WHERE the config.gateway.json file was to be located. It’s on the CONTROLLER (your CloudKey, or the server on which you installed the UniFi controller software). It’s not on the USG. The USG will be configured when it is Provisioned, based on the contents of the file on the Controller.

Now that you know where to place your config.gateway.json file, you need to understand how it’s going to be used by the Controller. The config.gateway.json will be MERGED with the existing configuration stored on the Controller and will then be Provisioned. This merger will take any sections defined in the config.gateway.json and OVERWRITE the same sections in the standard configuration. This is how you will be able to insert additional DNS entries into the USG in order to both change existing entries and to add static entries (technically, you’re only adding static entries).

To correct the two entries in my example above, I’ll create the following entries in my /usr/lib/unifi/data/sites/default/config.gateway.json file on my CloudKey Controller.

    "service": {
        "dns": {
            "forwarding": {
                "options": [
                    "host-record= st-D052BC263C7B0001.localdomain,",
                    ", st-D052BC263C7B0001.localdomain",

Note: I’ve also created PTR records (reverse DNS) which the USG will do automatically for dynamic entries, but not for static, unless you specify them here. Also, make sure the domain portion of your FQDN matches whatever you’ve configured for the Domain Name in the Controller for that Network.

There is a pair of entries at the beginning of my entries. These were ALREADY present in the configuration of the USG, so if you do not include them, they will be overwritten with your updates. I chose to keep them so that the entry for “unifi” and the reverse entry for “ubnt-usg” would continue to function.

Once you’ve created the config.gateway.json file on your Controller, you’ll then need to Provision these changes to the USG for them to take affect. This can be accomplished by going to Devices > USG > Manage Device > Force Provision:

Once the USG reboots, you should now have your static DNS entries available. I know that Ubiquiti is working on improving the DNS services available with the GUI, but it may be a while. At least now you can keep the USG performing DNS with the changes I’ve outlined here.

Tweet Post Share Update Email RSS

Leader, Mentor, Challenger, Educator, Network Engineer, System Administrator, Developer, Hacker, Writer, Diver, and Technology Explorer