• 2 min read
  • One of the neat and relatively undocumented feature of Unifi Security Gateway (USG) is the ability to specify alternate DNS servers sent with DHCP replies for specific clients, permitting you to do things like setup pihole for only a few specific devices on your LAN (e.g. the Smart TV or a streaming stick).

    This is perfect as I didn’t want to point my whole network at the pihole, as that would mean any technical issues with my pihole host (config errors, docker failing, etc) means the whole home Internet connection effectively going offline.

    You can test out this feature interactively by SSHing into the USG and running these commands (replace capitals as appropriate):

    configure
    set service dhcp-server shared-network-name net_LANNAME_eth1_SUBNET-MASK subnet SUBNET/MASK static-mapping DASH-SEPARATED-MAC-ADDR ip-address LAN_STATIC_IP
    set service dhcp-server shared-network-name net_LANNAME_eth1_SUBNET-MASK subnet SUBNET/MASK static-mapping DASH-SEPARATED-MAC-ADDR mac-address COLON:SEPARATED:MAC:ADDRESS
    set service dhcp-server shared-network-name net_LANNAME_eth1_SUBNET-MASK subnet SUBNET/MASK static-mapping DASH-SEPARATED-MAC-ADDR static-mapping-parameters  "option domain-name-servers DNS_IP_FOR_OVERRIDE;"
    commit
    save
    exit

    This will edit the running configuration but rebooting or re-provisioning will lose these changes. To persist the configuration, create/edit your config.gateway.json with a snippet like this:

    {
            "service": {
                    "dhcp-server": {
                            "shared-network-name": {
                                    "net_LANNAME_eth1_SUBNET-MASK": {
                                            "subnet": {
                                                    "SUBNET/MASK": {
                                                            "static-mapping": {
                                                                    "DASH-SEPARATED-MAC-ADDRESS": {
                                                                            "host-record": "disable",
                                                                            "ip-address": "LAN_STATIC_IP",
                                                                            "mac-address": "COLON:SEPARATED:MAC:ADDRESS",
                                                                            "static-mapping-parameters": "option domain-name-servers DNS_IP_FOR_OVERRIDE;"
                                                                    }
                                                            }
                                                    }
                                            }
                                    }
                            }
                    }
            }
    }

    Credit for discovering the syntax: tachyonforce on the Unifi forums

    For those curious about the pihole setup specifically, I used docker-compose with the pihole/pihole image on a home server to get it running:

    ---
    version: "2.2"
    
    services:
      pihole:
        image: pihole/pihole
        container_name: pihole
        restart: unless-stopped
        environment:
          - TZ=America/Los_Angeles
          - ServerIP=192.168.1.15
          - WEBPASSWORD=arandompw
          - VIRTUAL_HOST=externalhostname
        ports:
          - "192.168.1.15:53:53/tcp"
          - "192.168.1.15:53:53/udp"
        volumes:
          - /srv/docker-vols/pihole/etc/pihole:/etc/pihole/
          - /srv/docker-vols/pihole/etc/dnsmasq.d:/etc/dnsmasq.d

    Here I used the IP address of the server in the port mapping to as the server has multiple interfaces, and 53 is already used elsewhere. Specifying the IP ensures that Docker attempts to port map on the correct interface.

    VIRTUAL_HOST is required because I use a reverse proxy to expose internal services, so the hostname must be provided to ensure dashboard URLs resolve correctly.