NEXTDNS(1)

NAME
nextdns - DNS-over-HTTPS proxy client for NextDNS and other DoH providers

SYNOPSIS
nextdns command [options]

DESCRIPTION
nextdns is a daemon that acts as a local DNS proxy. It receives standard DNS queries from the system on port 53 (UDP and TCP) and forwards them encrypted over HTTPS (DNS-over-HTTPS, DoH) to NextDNS servers or any other DoH provider.

Applications on the system require no changes: they continue to speak plain DNS to localhost, while nextdns transparently handles encryption, caching, filtering and logging.

Advanced filtering and analytics features require a NextDNS account and profile ID, obtainable at https://nextdns.io. The daemon can also be used as a plain DoH client for any compatible provider.

QUICK START

Create a NextDNS account and obtain your Profile ID:

        https://nextdns.io

Configure NextDNS before starting the service:

        sudo nextdns config set -profile <profile-id>

Alternatively, edit the configuration file:

        sudo editor /etc/nextdns.conf

Enable and start the service:

        sudo systemctl enable --now nextdns

Verify that the service is running:

        nextdns status
        systemctl status nextdns

Test DNS resolution through NextDNS:

        dig @127.0.0.1 debian.org

COMMANDS

install [options]
    Not supported on Debian systems. The service is managed by the package manager. To enable and start the service use:

        sudo systemctl enable --now nextdns

uninstall
    Not supported on Debian systems. To remove the package use:

        sudo apt remove nextdns

start
    Start the installed service.

stop
    Stop the running service.

restart
    Restart the running service.

status
    Print the current service status (running, stopped, or not installed).

log Display the service logs.

run [options]
    Run the DNS proxy daemon in the foreground. Useful for testing or for environments where a service manager is not available. See RUN OPTIONS below.

config list
    List all current configuration options and their values.

config set [options]
    Set one or more configuration options persistently. Accepts the same flags as run. Run nextdns config set -h for the full list.

config edit
    Open the configuration file in the default editor.

config wizard
    Run an interactive configuration wizard.

activate
    Configure the local system to use nextdns as its DNS resolver (writes to /etc/resolv.conf or configures systemd-resolved).

deactivate
    Restore the original system DNS configuration.

discovered
    Display the list of clients discovered on the local network via ARP, NDP, mDNS and DHCP, along with their resolved names and addresses.

cache-stats
    Display hit/miss statistics for the local DNS cache.

cache-keys
    Dump the list of domain names currently held in the local cache.

trace
    Print a full goroutine stack trace of the running daemon. Useful for debugging hangs or unexpected behaviour.

arp Dump the current ARP table (IPv4 address to MAC address mappings).

ndp Dump the current NDP table (IPv6 address to MAC address mappings).

upgrade
    Not supported on Debian systems. To upgrade use:

        sudo apt update && sudo apt install nextdns

version
    Print the current version string.

RUN OPTIONS
The following options are accepted by run.

-profile ID
    NextDNS profile ID (6 hexadecimal characters, e.g. ab12cd). The profile determines which filtering rules, blocklists and analytics apply to queries. This option may be repeated with a condition prefix to select different profiles based on source subnet, MAC address, interface or user:

    10.0.3.0/24=abcdef
        Apply profile abcdef to queries from the given IPv4 CIDR.

    2001:db8::/32=abcdef
        Apply profile to queries from the given IPv6 CIDR.

    00:1c:42:2e:60:4a=abcdef
        Apply profile to the host with the given MAC address.

    eth0=abcdef
        Apply profile to all hosts reachable through the given interface.

    @alice=abcdef
        On Linux (systemd-logind), macOS and Windows, apply profile when the interactive user is alice.

    The first matching rule wins.

-listen addr
    Address and port to listen on for DNS queries. May be repeated to listen on multiple addresses. Default: localhost:53. Example: 0.0.0.0:53.

-setup-router
    Configure nextdns for router mode: listen on all interfaces, set up DNS forwarding rules for the detected router type (OpenWrt, DD-WRT, EdgeOS, etc.) and undo all changes on exit. When this option is active, the -listen option is ignored.

-auto-activate
    Automatically run activate at startup and deactivate on exit, updating the system resolver configuration.

-cache-size size
    Size of the in-memory DNS cache. Accepts units: kB, MB, GB. Set to 0 to disable caching (default). Example: 10MB.

-cache-max-age duration
    Maximum age for cached entries regardless of their TTL. Example: 1h.

-cache-metrics
    Enable collection of cache hit/miss metrics accessible via cache-stats.

-max-ttl duration
    Cap the TTL returned to clients. The internal cache still uses the true TTL for freshness evaluation. Useful with -cache-size to make profile changes propagate faster to LAN clients.

-forwarder [domain=]addr[,addr...]
    Forward queries for domain to the specified DNS server instead of NextDNS. If no domain is given, the forwarder acts as a catch-all fallback. May be repeated; first match wins. addr may be an IP[:port] for plain DNS or an HTTPS URL for DoH. A bootstrap IP may be appended after # for DoH addresses. Example: -forwarder corp.example.com=192.168.1.1

-report-client-info
    Attach device name, model and a short non-reversible ID to each query sent upstream. Enables per-device analytics in the NextDNS dashboard.

-discovery-dns addr
    DNS server used to resolve client names from IP addresses in router mode. Defaults to the server learned via DHCP. Only active when -report-client-info is set.

-mdns all|disabled|interface
    Control mDNS-based client discovery. Use all (default) to listen on all interfaces, an interface name to restrict discovery, or disabled to turn it off entirely.

-bogus-priv
    Answer reverse lookups for private IP ranges (RFC 1918, RFC 4193) with NXDOMAIN instead of forwarding them upstream. Enabled by default.

-detect-captive-portals
    Fall back to plain DNS when a captive portal is detected, allowing the initial connection to succeed. Disabled by default. Warning: enabling this option may allow an attacker to force unencrypted DNS traffic.

-timeout duration
    Maximum time to wait for an upstream response before failing. Default: 5s.

-max-inflight-requests n
    Maximum number of concurrent in-flight requests. Default: 256.

-control path
    Path to the Unix domain socket used by control commands (cache-stats, trace, arp, etc.). Default: /var/run/nextdns.sock.

-log-queries
    Log every DNS query and its result to the system logger.

-use-hosts
    Consult /etc/hosts before sending queries upstream. Enabled by default.

-debug
    Enable verbose debug logging.

-config-file path
    Path to an alternative configuration file.

EXAMPLES

  Getting started
Create a free account at https://nextdns.io and note your Profile ID (a 6-character hex string, e.g. ab12cd). Then configure and start the service:

        # Set your profile
        sudo nextdns config set -profile ab12cd

        # Enable and start the service
        sudo systemctl enable --now nextdns

        # (Optional) Redirect system DNS to NextDNS
        sudo nextdns activate

Check that the service is running:

        nextdns status

  Running in the foreground (testing)
Run the daemon interactively on a non-standard port, with caching and query logging enabled. Useful for verifying behaviour before committing to a permanent configuration:

        sudo nextdns run -profile ab12cd -listen localhost:5454 \
            -cache-size 10MB -log-queries

In a second terminal, send a query and observe the response:

        dig @127.0.0.1 -p 5454 example.com A

Repeat the same query to verify the cache is working — the query time should drop to 0 ms on the second and subsequent calls:

        dig @127.0.0.1 -p 5454 example.com A    # first:  ~300 ms (upstream)
        dig @127.0.0.1 -p 5454 example.com A    # second: ~0 ms   (cache hit)

  Inspecting the cache
After the daemon has been running for a while (started with -cache-size), check how many queries were served from the local cache versus forwarded upstream:

        nextdns cache-stats

Example output:

        {
            "hit": 5,
            "miss": 11
        }

To also collect detailed metrics (hits ratio, keys added/updated, etc.), start the daemon with both -cache-size and -cache-metrics:

        sudo nextdns run -profile ab12cd -cache-size 10MB -cache-metrics

Then retrieve the extended counters at any time:

        nextdns cache-metrics

  Controlling TTL handed to clients
Cap the TTL returned to LAN clients at 5 seconds so they always re-query the daemon (and pick up profile changes immediately) rather than caching answers themselves. The daemon's internal cache still honours the true TTL:

        sudo nextdns run -profile ab12cd -cache-size 10MB -max-ttl 5s

  bogus-priv: blocking private reverse lookups
By default, -bogus-priv is enabled. Reverse lookups for private IP ranges (RFC 1918, RFC 4193) are answered locally with NXDOMAIN and never forwarded upstream:

        # returns NXDOMAIN immediately — not forwarded to NextDNS
        dig @127.0.0.1 -p 5454 -x 192.168.1.1

        # public IP — forwarded and resolved normally
        dig @127.0.0.1 -p 5454 -x 8.8.8.8

To disable this behaviour (forward all reverse lookups upstream):

        sudo nextdns run -profile ab12cd -bogus-priv=false

  use-hosts: resolving /etc/hosts entries
With -use-hosts (enabled by default), queries for names present in /etc/hosts are answered locally before any upstream lookup is attempted:

        # Add a local entry
        echo '10.0.0.10 myserver.home' | sudo tee -a /etc/hosts

        # Resolved instantly from /etc/hosts, 0 ms, no upstream query
        dig @127.0.0.1 -p 5454 myserver.home A

  Split-horizon DNS with forwarders
Forward queries for an internal corporate domain to an on-premises DNS server, while sending everything else to NextDNS:

        sudo nextdns config set -profile ab12cd \
            -forwarder corp.example.com=192.168.1.1
        sudo systemctl restart nextdns

Use a DoH forwarder with a bootstrap IP for a specific domain. The bootstrap address avoids a chicken-and-egg problem when the DoH hostname itself needs to be resolved:

        sudo nextdns config set -profile ab12cd \
            -forwarder internal.lan=https://doh.company.com#10.0.0.1
        sudo systemctl restart nextdns

Multiple forwarders are evaluated in order; the first matching rule wins:

        sudo nextdns config set -profile ab12cd \
            -forwarder corp.example.com=192.168.1.1 \
            -forwarder lab.example.com=192.168.2.1
        sudo systemctl restart nextdns

  Using public DoH providers as forwarders
NextDNS can forward queries for specific domains to any public DNS-over-HTTPS resolver. The general format is:

        -forwarder DOMAIN=https://PROVIDER/dns-query

The following well-known public providers are supported:

Provider | URL | Notes
Cloudflare (1.1.1.1) | https://cloudflare-dns.com/dns-query | No IP logs
Cloudflare + malware | https://security.cloudflare-dns.com/dns-query | Blocks malware and phishing
Google (8.8.8.8) | https://dns.google/dns-query | High availability
Quad9 (9.9.9.9) | https://dns.quad9.net/dns-query | Blocks malware + DNSSEC + no logs
AdGuard | https://dns.adguard-dns.com/dns-query | Blocks ads and trackers
AdGuard Family | https://family.adguard-dns.com/dns-query | Ads + adult content blocked
Mullvad | https://dns.mullvad.net/dns-query | Strict no-logs policy
OpenDNS | https://doh.opendns.com/dns-query | Cisco-backed

Forward example.com to Cloudflare and everything else to NextDNS:

        sudo nextdns run -profile ab12cd \
            -forwarder example.com=https://cloudflare-dns.com/dns-query

Forward different domains to different providers simultaneously:

        sudo nextdns run -profile ab12cd \
            -forwarder work.example.com=https://dns.google/dns-query \
            -forwarder games.example.com=https://dns.quad9.net/dns-query

Route all queries through a single public DoH provider (wildcard rule), bypassing NextDNS entirely:

        sudo nextdns run -forwarder .=https://dns.quad9.net/dns-query

Add a bootstrap IP to avoid circular resolution when the DoH hostname is not yet reachable:

        sudo nextdns run -profile ab12cd \
            -forwarder example.com=https://cloudflare-dns.com/dns-query#1.1.1.1

Define multiple servers for a domain to implement failover (tried left to right):

        sudo nextdns run -profile ab12cd \
            -forwarder example.com=https://dns.quad9.net/dns-query,https://dns.google/dns-query

To verify that the forwarder is active, query the NextDNS metadata endpoint from a second terminal while the daemon is running. The proto field should read DOH:

        dig @127.0.0.1 whoami.cloudflare TXT CH

The ADDITIONAL SECTION of the response contains metadata injected by the NextDNS daemon itself:

        profile.nextdns.io.   0  CH  TXT  "default"
        client.nextdns.io.    0  CH  TXT  "203.0.113.10"
        proto.nextdns.io.     0  CH  TXT  "DOH"
        server.nextdns.io.    0  CH  TXT  "edgeuno-for-1"

  Per-device profiles (router mode)
Configure as a router serving the whole LAN with device-name discovery and per-device profile assignment by subnet:

        sudo nextdns config set \
            -profile 10.0.1.0/24=ab12cd \
            -profile 10.0.2.0/24=ef34gh \
            -setup-router \
            -report-client-info
        sudo systemctl enable --now nextdns

Assign a specific profile to a single device by MAC address:

        sudo nextdns config set -profile ab12cd \
            -profile 00:1c:42:2e:60:4a=ef34gh \
            -setup-router -report-client-info
        sudo systemctl restart nextdns

On Linux with systemd-logind, assign a profile per interactive user:

        sudo nextdns config set \
            -profile @alice=ab12cd \
            -profile @bob=ef34gh
        sudo systemctl restart nextdns

View devices discovered on the LAN (ARP, NDP, mDNS, DHCP):

        nextdns discovered

  Diagnostics
Display the ARP table (IPv4 address to MAC mappings):

        nextdns arp

Display the NDP table (IPv6 address to MAC mappings):

        nextdns ndp

Print a goroutine stack trace of the running daemon (useful when the daemon appears hung):

        nextdns trace

Follow the live service logs:

        nextdns log

  Managing the configuration file
List the current persistent configuration:

        nextdns config list

Persistently enable caching and client reporting without reinstalling:

        sudo nextdns config set -cache-size 10MB -report-client-info
        sudo nextdns restart

Open the configuration file in the default editor:

        sudo nextdns config edit

FILES

/etc/nextdns.conf
    Default configuration file, managed by nextdns config.

/var/run/nextdns.sock
    Unix domain control socket used for cache-stats, cache-keys, discovered, trace and similar commands.

SEE ALSO
systemctl(1), resolv.conf(5), dig(1)

NextDNS documentation and profile management: https://nextdns.io

AUTHOR
NextDNS Inc. <support@nextdns.io>

This manual page was written for the Debian package by Josenilson Ferreira da Silva <nilsonfsilva@hotmail.com>.