0

DoH on Cisco IOS XE IOx

Cisco IOS XE does not natively support DoH (other than for/with Umbrella).

For platforms that support IOx, such as in my case an ISR 1k, it is possible to deploy the NextDNS CLI client in a container.

The reason I wanted to implement DoH is to optimise the time it takes to resolve DNS queries by using NextDNS ultralow servers, which are only accessible via their hostnames and only via encrypted protocols such as DoH. NextDNS DNS53 servers are limited to anycast addresses. Of course using DoH also has security and privacy benefits.

The NextDNS DockerHub image cannot be used on IOx as-is because there is default run CMD has not been defined in Dockerfile.

The solution is to download the Dockerfile from the NextDNS Github, adding the CMD configuration in Dockerfile and re-building the image.

IOx documentation can be found at https://developer.cisco.com/docs/iox/introduction-to-iox/

Download NextDNS client and Dockerfile

$ mkdir iox-aarch64-nextdns && cd iox-aarch64-nextdns
$ wget https://github.com/nextdns/nextdns/releases/download/v1.44.3/nextdns_1.44.3_linux_arm64.tar.gz
$ tar -xvzf nextdns_1.44.3_linux_arm64.tar.gz
LICENSE
README.md
nextdns
$ wget https://github.com/nextdns/nextdns/raw/refs/heads/master/Dockerfile

 

 

Add CMD arguments to Dockerfile so that the NextDNS binary will start when IOx starts the container.

echo 'CMD ["run", "-listen :53", "-profile XXXXXX", "-cache-size 10MB", "-forwarder https://doh.opendns.com/dns-query"]' >> Dockerfile

 

 

Additional configuration parameters can be configured via /data/package_config.ini, which can be edited via IOx Local Manager or from within the container.

echo 'CMD ["run", "-config-file /data/package_config.ini"]' >> Dockerfile

 

 

Build and save the container

docker build --platform arm64 -t iox-aarch64-nextdns .
docker save iox-aarch64-nextdns -o iox-aarch64-nextdns.tar

 

 

Enable IOx and configure IOx networking

iox
!
interface VirtualPortGroup0
 ip address 172.16.11.1 255.255.255.0
 ip nat inside
!

app-hosting appid nextdns
 app-vnic gateway0 virtualportgroup 0 guest-interface 0
  guest-ipaddress 172.16.11.2 netmask 255.255.255.0
 app-default-gateway 172.16.11.1 guest-interface 0
 app-resource profile custom
  cpu 100
  memory 32
  persist-disk 10
name-server0 119.252.95.133
name-server1 144.208.222.195

 

 

Copy the container to the IOx host

copy scp://user@172.16.1.81/iox-aarch64-nextdns/iox-aarch64-nextdns.tar bootflash:/iox-aarch64-nextdns.tar

 

 

Install, activate and start the application

app-hosting install appid nextdns package bootflash:/iox-aarch64-nextdns.tar
app-hosting activate appid nextdns
app-hosting start appid nextdns

 

 

Connect to an application's console if you want to observe the start-up (be quick!)

app-hosting connect appid nextdns console
Connected to appliance. Exit using ^c^c^c
Clear existing connection in case of failure
INFO: 09:34:51 Connected 119.252.95.133:443 (con=26ms tls=116ms, TCP, TLS13)
INFO: 09:34:51 Connected 103.137.12.7:443 (con=14ms tls=48ms, TCP, TLS13)
INFO: 09:34:51 Switching endpoint: https://dns.nextdns.io#103.137.12.7,119.252.95.133

 

 

Connect to an application's shell for troubleshooting

app-hosting connect appid nextdns session
/ #

 

 

Configure the NextDNS DoH Proxy as the resolver for the IOS-hosted name server

ip dns view dns-view-primary
domain name-server 172.16.11.2

 

 

Optionally, change the DHCP-offered DNS servers to point directly to the NextDNS DoH Proxy

ip dhcp pool dhcp-pool-ipv4-vlan1
 dns-server 172.16.11.2

 

 

Enable HTTPS server to expose Local IOx Manager for easy editing of package_config.ini. Documentation can be found at https://developer.cisco.com/docs/iox/iox-local-manager/

iox(config-if)#ip http secure-server

 

 

Browse to https://<iox-host>/webui/#/ioxmain

6 replies

null
    • NextDNs
    • 4 mths ago
    • Reported - view

    Did you see this page about docker? https://github.com/nextdns/nextdns/wiki/Docker

    • subliminal
    • 4 mths ago
    • Reported - view
     said:
    The NextDNS DockerHub image cannot be used on IOx as-is because there is default run CMD has not been defined in Dockerfile.
    The solution is to download the Dockerfile from the NextDNS Github, adding the CMD configuration in Dockerfile and re-building the image.

    Yes, the NextDNS Docker image is very helpful and this how-to is based on it.

    However, the Dockerfile CMD parameters need to be added so that the container can start on IOx. 

      • NextDNs
      • 4 mths ago
      • Reported - view

       I see. Would it make it easier if those parameters could be passed via the --env-file argument?

    • subliminal
    • 4 mths ago
    • Reported - view

    Using environment variable may be a possibility if the NextDNS CLI Client can read its configuration from environment variables. I don't think this is (or is documented to be) supported by the NextDNS CLI Client though, but I may have missed it.

    It's possible to specify docker run OPTIONS using IOx, although notably it's not possible to specify container COMMAND or ARGs (which is why we're here).

    This example uses the -config-file option as a COMMAND ARG to configure the NextDNS CLI Client as per the config file reference at https://github.com/nextdns/nextdns/wiki/Configuration-File-Format. On reflection this wasn't super clearly articulated - apologies.

     said:
    Additional configuration parameters can be configured via /data/package_config.ini, which can be edited via IOx Local Manager or from within the container.

    echo 'CMD ["run", "-config-file /data/package_config.ini"]' >> Dockerfile

    This works well, and conveniently the IOx Local Admin > App-ID > App-Config Page provides a way to edit /data/package_config.ini from a browser.

    • subliminal
    • yesterday
    • Reported - view

    When support for UniFi OS 4.3+ was added in v1.46.0, the nextdns/nextdns Dockerfile was updated to include a RUN command and (almost - see below) enables the next-dns/next-dns Docker image to be used on IOx as-is.

    $ docker pull --platform=arm64 nextdns/nextdns
    $ docker image save --platform=arm64 nextdns/nextdns -o iox-aarch64-nextdns.tar

    Copy the container to the IOx host and deploy/upgrade.

    copy scp://user@172.16.1.145/iox-aarch64-nextdns/iox-aarch64-nextdns.tar bootflash:/iox-aarch64-nextdns.tar
    app-hosting upgrade appid nextdns package bootflash:/iox-aarch64-nextdns.tar

    The container will start and run as normal, but without additional configuration parameters will only bind to the container localhost and unable to serve requests made by clients. I'm unsure if this is by design or a side-effect of how the container starts.

    When started without configuration

    / # netstat -tulnp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1/nextdns
    tcp 0 0 ::1:53 :::* LISTEN 1/nextdns
    udp 0 0 127.0.0.1:53 0.0.0.0:* 1/nextdns
    udp 0 0 ::1:53 :::* 1/nextdns

    When started with listen :53

    / # netstat -tulnp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0 :::53 :::* LISTEN 1/nextdns
    udp 0 0 :::53 :::* 1/nextdns

    Binding to any/ addresses would enable the next-dns/next-dns Docker image to be used as-is on IOx.

    • subliminal
    • yesterday
    • Reported - view

    Further configuration would still need to be accomplished separately.

    One option that can be considered for the future is to test whether the NextDNS CLI client  is running inside an IOx container during start-up, and then to load an external config file if available.

    IOx will point CAF_APP_CONFIG_DIR in /data/.env to a directory containing a package_config.ini file that can be used for this purpose. This file is editable outside of the container.

    / # cat /data/.env
    #!/bin/sh
    export CAF_APP_PERSISTENT_DIR=/data
    export CAF_APP_LOG_DIR=/data/logs
    export CAF_APP_APPDATA_DIR=/data/appdata
    export CAF_APP_CONFIG_DIR=/data
    export CAF_APP_USERNAME=root
    export CAF_APP_CORE_DIR=/local/local1/core_dir
    export CAF_SYSTEM_UUID=3c7f0356-75ba-464f-ac3a-xxxxxxxxxxxx
    export CAF_SYSTEM_PRODUCT_ID=C1117-4PLTELA
    export CAF_SYSTEM_SERIAL_ID=FGLXXXXXXXX
    export CAF_SYSTEM_NAME=router
    export CAF_DISK_TYPE=restricted
    export PLATFORM_SYSTEM_LICENSE=NO_PLATFORM_LICENSE_RESTRICTION
    export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    export CAF_APP_MEMORY_SIZE_KB=32768
    export CAF_APP_PERSISTENT_DISK_SIZE_KB=10240
    export CAF_APP_CPU_SHARES=4224
    export CAF_APP_CPU_UNITS=100
    export CAF_APP_ID=nextdns
    export MTU_eth0=1500
    
    / # cat /data/package_config.ini
    [nextdns]
    listen :53
    use-hosts false
    cache-size 10MB
    report-client-info true
    mdns disabled
    profile xxxxxx
    

Content aside

  • yesterdayLast active
  • 6Replies
  • 92Views
  • 2 Following