doggo Documentation

Dog: Command-line DNS Client for Humans. Written in Golang

4,256 stars Go Go 1 file ยท ~10,057 tokens #dns#dns-client#doh
RAW Doc

File: README.md


doggo is a modern command-line DNS client (like dig) written in Golang. It outputs information in a neat concise manner and supports protocols like DoH, DoT, DoQ, and DNSCrypt as well.

It's totally inspired by dog which is written in Rust. I wanted to add some features to it but since I don't know Rust, I found it as a nice opportunity to experiment with writing a DNS Client from scratch in Go myself. Hence the name dog + go => doggo.

Installation

shell
curl -fsSL https://raw.githubusercontent.com/mr-karan/doggo/main/install.sh | sh

Package Managers

  • Arch Linux: pacman -S doggo
  • Eget: eget mr-karan/doggo
  • Gentoo: emerge net-dns/doggo
  • Homebrew: brew install doggo
  • MacPorts (macOS): port install doggo
  • Mise: mise use -g doggo@latest
  • Nix: nix profile install nixpkgs#doggo
  • Scoop (Windows): scoop install doggo
  • Winget (Windows): winget install doggo

Binary Install

You can download pre-compiled binaries for various operating systems and architectures from the Releases page.

Linux 32-bit ARM releases are available as doggo-linux-armv6.tar.gz (ARMv6) and doggo-linux-armv7.tar.gz (ARMv7 and 32-bit ARMv8). The doggo-linux-arm.tar.gz compatibility asset is the ARMv7 build.

FreeBSD, OpenBSD, and NetBSD ARMv7 releases use the explicit doggo-<os>-armv7.tar.gz name and retain their historical doggo-<os>-arm.tar.gz aliases.

Go Install

If you have Go installed on your system, you can use the go install command:

shell
go install github.com/mr-karan/doggo/cmd/doggo@latest

The binary will be available at $GOPATH/bin/doggo.

Docker

shell
docker pull ghcr.io/mr-karan/doggo:latest
docker run --rm ghcr.io/mr-karan/doggo:latest example.com

For more installation options, including binary downloads and Docker images, please refer to the full installation guide.

Quick Start

Here are some quick examples to get you started with doggo:

shell
# Simple DNS lookup
doggo example.com

# Query MX records using a specific nameserver
doggo MX github.com @9.9.9.9

# Use DNS over HTTPS
doggo example.com @https://cloudflare-dns.com/dns-query

# JSON output for scripting
doggo example.com --json | jq '.responses[0].answers[].address'

# Reverse DNS lookup
doggo --reverse 8.8.8.8 --short

# Using Globalping
doggo example.com --gp-from Germany,Japan --gp-limit 2

Configuration

Defaults for any flag can be set via a TOML config file or DOGGO_* environment variables, so you don't have to repeat flags on every invocation:

shell
# ~/.config/doggo/config.toml (or $XDG_CONFIG_HOME/doggo/config.toml, ~/.doggo.toml)
strategy = "first"
color    = false
timeout  = "10s"

# HTTP/3 must be paired with a persistent HTTPS (DoH) nameserver.
nameserver = ["https://cloudflare-dns.com/dns-query"]
http3     = true
shell
# Equivalent environment variables
export DOGGO_STRATEGY=first
export DOGGO_COLOR=false
export DOGGO_NAMESERVER=https://cloudflare-dns.com/dns-query
export DOGGO_HTTP3=true

Precedence (lowest to highest): flag defaults < config file < environment variables < command line flags. Use --config=PATH or DOGGO_CONFIG to load a file from a custom location.

config-cli-sample.toml documents every supported key with its default. See the CLI reference for details.

Features

  • Human-readable output with color-coded and tabular format
  • JSON output support for easy scripting and parsing
  • Multiple transport protocols: DoH, DoT, DoQ, TCP, UDP, DNSCrypt
  • Explicit DNS-over-HTTPS over HTTP/3 with --http3
  • EDNS support with Client Subnet (ECS), NSID, Cookies, Padding, and Extended Errors
  • Additional section support for glue records and supplementary data
  • Internationalized Domain Names (IDN) with automatic punycode conversion
  • Support for ndots and search configurations
  • Multiple resolver support with customizable query strategies
  • Bind queries to a local source address with -b/--source, like dig -b
  • IPv4 and IPv6 support
  • Web interface available
  • Shell completions for zsh and fish
  • Reverse DNS lookups
  • Flexible query options including various DNS flags
  • Debug mode for troubleshooting
  • Response time measurement
  • Cross-platform support

Documentation

For comprehensive documentation, including detailed usage instructions, configuration options, and advanced features, please visit our official documentation site.

Sponsorship

If you find doggo useful and would like to support its development, please consider becoming a sponsor. Your support helps maintain and improve this open-source project.

Every contribution, no matter how small, is greatly appreciated and helps keep this project alive and growing. Thank you for your support! ๐Ÿถโค๏ธ

License

LICENSE


File: docs/src/content/docs/guide/examples.md


title: Usage Examples

These examples showcase how to combine different features for powerful DNS querying.

Basic Queries

  1. Simple A record lookup:

    bash
    doggo example.com
  2. Query for a specific record type:

    bash
    doggo AAAA example.com

    Record types can also be written as decimal numbers or in RFC 3597
    TYPE<number> notation:

    bash
    doggo example.com HTTPS
    doggo example.com 65
    doggo example.com TYPE65

    Bare decimal arguments and names matching TYPE<number> are interpreted
    as record types. To query a numeric single-label hostname, make the intent
    explicit with --query, for example doggo --query 65.

    Record type 0 is reserved and rejected. OPT, TKEY, and TSIG are also
    rejected because they are not legal DNS question types; transfer query
    types such as AXFR and IXFR remain supported.

  3. Query multiple record types simultaneously:

    bash
    doggo A AAAA MX example.com
  4. Query using Globalping API from a specific location:

    bash
    doggo example.com --gp-from Germany

Using Different Resolvers

  1. Query using a specific DNS resolver:

    bash
    doggo example.com @1.1.1.1
  2. Use DNS-over-HTTPS (DoH):

    bash
    doggo example.com @https://cloudflare-dns.com/dns-query
  3. Use DNS-over-TLS (DoT):

    bash
    doggo example.com @tls://1.1.1.1
  4. Query multiple resolvers and compare results:

    bash
    doggo example.com @1.1.1.1 @8.8.8.8 @9.9.9.9
  5. Using Globalping API

    bash
    doggo example.com @1.1.1.1  --gp-from Germany

Advanced Queries

  1. Perform a reverse DNS lookup:

    bash
    doggo --reverse 8.8.8.8
  2. Set query flags for DNSSEC validation:

    bash
    doggo example.com --do --cd
  3. Use the short output format for concise results:

    bash
    doggo example.com --short
  4. Show query timing information:

    bash
    doggo example.com --time

Combining Flags

  1. Perform a reverse lookup with short output and custom resolver:

    bash
    doggo --reverse 8.8.8.8 --short @1.1.1.1
  2. Query for MX records using DoH with JSON output:

    bash
    doggo MX example.com @https://dns.google/dns-query --json
  3. Use IPv6 only with a specific timeout and DNSSEC checking:

    bash
    doggo AAAA example.com -6 --timeout 3s --do

Scripting and Automation

  1. Use JSON output for easy parsing in scripts:

    bash
    doggo example.com --json | jq '.responses[0].answers[].address'
  2. Batch query multiple domains from a file:

    bash
    cat domains.txt | xargs -I {} doggo {} --short
  3. Find all nameservers for a domain and its parent domains:

    bash
    doggo NS example.com example.com. com. . --short
  4. Extract all MX records and their priorities:

    bash
    doggo MX gmail.com --json | jq -r '.responses[0].answers[] | "\(.address) \(.preference)"'
  5. Count the number of IPv6 addresses for a domain:

    bash
    doggo AAAA example.com --json | jq '.responses[0].answers | length'

EDNS Options

  1. Request Name Server Identifier (NSID) to see which server responded:

    bash
    doggo example.com --nsid @1.1.1.1
  2. Use EDNS Client Subnet (ECS) for geo-aware CDN responses:

    bash
    doggo example.com --ecs 8.8.8.0/24 @8.8.8.8

    This is particularly useful for testing how CDNs route traffic based on client location.

  3. Compare responses from different geographic locations using ECS:

    bash
    # North America subnet
    doggo example.com --ecs 8.8.8.0/24 @8.8.8.8
    
    # Europe subnet
    doggo example.com --ecs 1.1.1.0/24 @8.8.8.8
  4. Real-world example: Test geo-aware DNS with Netflix

    Netflix uses geo-aware DNS to route users to regional servers. Query from different locations to see how they return different IP addresses:

    bash
    # From USA (using subnet 8.8.8.0/24)
    doggo netflix.com --ecs 8.8.8.0/24 @8.8.8.8
    # Returns: 3.225.92.8 (AWS US-East servers)
    
    # From India (using subnet 49.207.0.0/24)
    doggo netflix.com --ecs 49.207.0.0/24 @8.8.8.8
    # Returns: 54.246.79.9 (AWS EU-Ireland servers)
    
    # From Germany (using subnet 5.9.0.0/24)
    doggo netflix.com --ecs 5.9.0.0/24 @8.8.8.8
    # Returns: 54.74.73.31 (AWS EU-Ireland servers)

    Notice how Netflix returns completely different IP addresses based on your location. This ensures you connect to the closest data center for faster streaming.

    Understanding CDN behavior:

    • Some services like Netflix use geo-aware DNS (different IPs per region)
    • Others like Cloudflare use Anycast (same IPs globally, routing happens at network level)
    • ECS lets you test this without actually traveling!
  5. Use DNS Cookie for enhanced security:

    bash
    doggo example.com --cookie @1.1.1.1
  6. Combine EDNS options for privacy and debugging:

    bash
    doggo example.com --nsid --cookie --padding @1.1.1.1

    The --padding flag helps protect against traffic analysis attacks.

Troubleshooting and Debugging

  1. Enable debug logging for verbose output:

    bash
    doggo example.com --debug
  2. Enable EDNS to receive Extended DNS Errors (EDE) with detailed failure information:

    bash
    doggo nonexistent.example --ede @1.1.1.1

    --ede adds an OPT record without sending an EDE payload. Doggo also displays EDEs returned to queries where another option, such as --do or --bufsize, enabled EDNS.

  3. Test DNSSEC validation:

    bash
    doggo rsasecured.net --do @8.8.8.8

    This example uses a domain known to be DNSSEC-signed. The --do flag sets the DNSSEC OK bit.

    Note: DNSSEC validation can be complex and depends on various factors:

    • The domain must be properly DNSSEC-signed
    • The resolver must support DNSSEC
    • The resolver must be configured to perform DNSSEC validation

    If you don't see DNSSEC-related information in the output, try using a resolver known to support DNSSEC, like 8.8.8.8 (Google) or 9.9.9.9 (Quad9).

  4. Check for DNSSEC records (DNSKEY, DS, RRSIG):

    bash
    doggo DNSKEY example.com @8.8.8.8
    doggo DS example.com @8.8.8.8
    doggo RRSIG example.com @8.8.8.8
  5. Verify DNSSEC chain of trust:

    bash
    doggo example.com --type=A --do --cd=false @8.8.8.8

Internationalized Domain Names (IDN)

  1. Query Unicode domain names directly:

    bash
    doggo mรผnchen.de

    Doggo automatically converts Unicode to punycode for DNS queries and displays results in Unicode for readability.

  2. Query international domains in different scripts:

    bash
    # German (Umlauts)
    doggo die-fรถrderer.net
    
    # Arabic
    doggo ู…ุตุฑ.eg
    
    # Chinese
    doggo ไธญๅ›ฝ.cn
    
    # Japanese
    doggo ๆ—ฅๆœฌ.jp
  3. Use IDN domains with different resolvers:

    bash
    doggo mรผnchen.de @https://dns.google/dns-query

DNS Additional Section (Glue Records)

  1. Query TLD nameservers to see glue records:

    bash
    doggo NS com. @a.gtld-servers.net --rd=false

    The Additional section shows IPv4 and IPv6 addresses for nameservers, preventing circular dependencies.

  2. Investigate DNS delegation for a domain:

    bash
    doggo NS example.org @a.gtld-servers.net --rd=false

    This reveals how the domain is delegated at the TLD level, including glue records for in-zone nameservers.

  3. Query root servers for TLD nameserver information:

    bash
    doggo NS org. @a.root-servers.net --rd=false
  4. Debug nameserver configuration:

    bash
    doggo NS yourdomain.com @ns1.yourdomain.com --rd=false

    Verify that nameserver IPs are correctly configured in glue records.

  5. See MX target addresses in Additional section:

    bash
    doggo MX gmail.com

    The Additional section may include A/AAAA records for mail servers, optimizing resolution.


File: docs/src/content/docs/guide/reference.md


title: CLI Reference Guide

This guide provides a comprehensive list of all command-line options and flags available in Doggo.

Basic Syntax

text
doggo [--] [query options] [arguments...]

Free-form decimal arguments and TYPE<number> are interpreted as record
types. Use --query=65 when querying a numeric single-label hostname.
Invalid, reserved, and non-question record types are rejected before a DNS
request is sent; the lookup API reports the same validation failures as HTTP
400 responses.

Query Options

Option Description
-q, --query=HOSTNAME Hostname to query the DNS records for (e.g., example.com)
-t, --type=TYPE DNS record type by name, number, or RFC 3597 notation (e.g., HTTPS, 65, TYPE65)
-n, --nameserver=ADDR Address of a specific nameserver to send queries to (e.g., 9.9.9.9, 8.8.8.8)
-c, --class=CLASS Network class of the DNS record (IN, CH, HS, etc.)
-x, --reverse Performs a reverse DNS lookup for an IPv4 or IPv6 address

Resolver Options

Option Description
--strategy=STRATEGY Specify strategy to query nameservers (all, random, first)
--ndots=INT Specify ndots parameter
--search Use the search list defined in resolv.conf (default: true)
--timeout=DURATION Specify timeout for the resolver to return a response (e.g., 5s, 400ms, 1m)
-4, --ipv4 Use IPv4 only
-6, --ipv6 Use IPv6 only
--http3 Use HTTP/3 for HTTPS (DoH) nameservers
--tls-hostname=HOSTNAME Provide a hostname for TLS certificate verification
--skip-hostname-verification Skip TLS Hostname Verification for DoT lookups

Query Flags

Flag Description
--aa Set Authoritative Answer flag
--ad Set Authenticated Data flag
--cd Set Checking Disabled flag
--rd Set Recursion Desired flag (default: true)
--z Set Z flag (reserved for future use)
--do Set DNSSEC OK flag

EDNS Options

EDNS (Extension Mechanisms for DNS) provides additional capabilities beyond basic DNS queries.

Option Description
--nsid Request Name Server Identifier (NSID) to identify which nameserver responded
--cookie Request DNS Cookie for enhanced security and protection against spoofing and amplification attacks
--padding Request EDNS padding for privacy (helps mitigate traffic analysis attacks by standardizing packet sizes)
--ede Enable EDNS to receive Extended DNS Errors with detailed error information when queries fail
--ecs=SUBNET EDNS Client Subnet - sends client subnet information for geo-aware responses (e.g., 192.0.2.0/24 or 2001:db8::/32)
--bufsize=BYTES EDNS UDP buffer size in bytes (512-65535). Setting this enables EDNS even without other EDNS options. Default is 1232 when EDNS is enabled โ€” the DNS Flagday 2020 recommendation to avoid IP fragmentation.

--ede enables EDNS by adding an OPT record; it does not send an EDE option or payload. A resolver may return EDE information for any query carrying an OPT record, and Doggo displays it regardless of which EDNS-enabling option (--do, --nsid, --cookie, --padding, --ede, --ecs, or --bufsize) added that record.

EDNS Examples

  1. Query with NSID to identify the responding nameserver:

    text
    doggo example.com --nsid @1.1.1.1
  2. Use EDNS Client Subnet for geo-aware CDN responses:

    text
    doggo example.com --ecs 8.8.8.0/24 @8.8.8.8
  3. Combine multiple EDNS options for privacy and debugging:

    text
    doggo example.com --nsid --cookie --padding @1.1.1.1

Output Options

Option Description
-J, --json Format the output as JSON
--short Short output format (shows only the response section)
--color Enable/disable colored output (default: true)
--debug Enable debug logging
--time Show query response time

Transport Options

Specify the protocol with a URL-type scheme. UDP is used if no scheme is specified.

Scheme Description Example
@udp:// UDP query @1.1.1.1
@tcp:// TCP query @tcp://1.1.1.1
@https:// DNS over HTTPS (DoH) @https://cloudflare-dns.com/dns-query
@tls:// DNS over TLS (DoT) @tls://1.1.1.1
@sdns:// DNSCrypt or DoH using DNS stamp @sdns://...
@quic:// DNS over QUIC @quic://dns.adguard.com

Globalping API Options

Option Description Example
--gp-from Specify the location to query from --gp-from Europe,Asia
--gp-limit Limit the number of probes to use --gp-limit 5

General Options

Option Description
--config=PATH Load defaults from a TOML config file at PATH, bypassing the default search locations
--version Show version of doggo

Configuration File and Environment Variables

Defaults for any long flag can be set via a TOML config file or environment variables, so you don't have to repeat flags like --color=false or --strategy=first on every invocation.

Precedence (lowest to highest):

text
flag defaults < config file < environment variables < command line flags

Config file locations

The config file is resolved in the following order (first match wins):

  1. --config=PATH flag
  2. DOGGO_CONFIG environment variable
  3. $XDG_CONFIG_HOME/doggo/config.toml (or the OS user config dir: ~/Library/Application Support/doggo/config.toml on macOS, %AppData%\doggo\config.toml on Windows)
  4. ~/.doggo.toml

A missing file at a default location is silently ignored. A file requested explicitly via --config or DOGGO_CONFIG that is missing or malformed is an error.

Keys are the long flag names. Example config.toml:

toml
# Always pick the first nameserver instead of querying all.
strategy = "first"

# Disable colored output.
color = false

# Longer timeout for slow resolvers.
timeout = "10s"

Unknown keys are rejected, so a typo like strategiy fails immediately instead of being silently ignored.

config-cli-sample.toml in the repository documents every supported key with its default value. Copy it to one of the locations above and uncomment what you need:

shell
mkdir -p ~/.config/doggo
curl -fsSL https://raw.githubusercontent.com/mr-karan/doggo/main/config-cli-sample.toml -o ~/.config/doggo/config.toml

Environment variables

Environment variables are the DOGGO_ prefix plus the upper-cased flag name with - replaced by _:

shell
export DOGGO_STRATEGY=first
export DOGGO_COLOR=false
export DOGGO_TIMEOUT=10s

# HTTP/3 requires an HTTPS (DoH) nameserver.
export DOGGO_NAMESERVER=https://cloudflare-dns.com/dns-query
export DOGGO_HTTP3=true

# List flags accept comma-separated values.
export DOGGO_TYPE="A,AAAA"

Web lookup API resolver security

POST /api/lookup/ accepts the resolver URL and encrypted-transport policy in
the JSON payload. The relevant fields are nameservers, http3,
tls_hostname, and skip_hostname_verification.

The API client controls both the resolver destination and its certificate
verification policy. Setting skip_hostname_verification to true disables
TLS certificate verification for that client-selected resolver. Deployments
that expose this API should apply appropriate authentication and outbound
network controls.

Examples

  1. Query a domain using defaults:

    text
    doggo example.com
  2. Query for a CNAME record:

    text
    doggo example.com CNAME
  3. Use a custom DNS resolver:

    text
    doggo example.com MX @9.9.9.9
  4. Using named arguments:

    text
    doggo -q example.com -t MX -n 1.1.1.1
  5. Query with specific flags:

    text
    doggo example.com --aa --ad
  6. Query using Globalping API from a specific location:

    text
    doggo example.com --gp-from Europe,Asia --gp-limit 5

For more detailed usage examples, refer to the Examples section.


File: docs/src/content/docs/features/any.md


title: Common record types

The --any flag in Doggo allows you to query all supported DNS record types for a given domain in a single command. This can be particularly useful when you want to get a comprehensive view of a domain's DNS configuration without running multiple queries.

Syntax

bash
doggo [domain] --any

Supported Record Types

When you use the --any flag, Doggo will query for the following common DNS record types:

  • A (IPv4 address)
  • AAAA (IPv6 address)
  • CNAME (Canonical name)
  • MX (Mail exchange)
  • NS (Name server)
  • PTR (Pointer)
  • SOA (Start of authority)
  • SRV (Service)
  • TXT (Text)
  • CAA (Certification Authority Authorization)

Example Usage

bash
doggo mrkaran.dev --any

Example Output

bash
$ doggo example.com --any
NAME            TYPE    CLASS   TTL     ADDRESS                         NAMESERVER
example.com.    A       IN      3401s   93.184.215.14                           127.0.0.53:53
example.com.    AAAA    IN      3600s   2606:2800:21f:cb07:6820:80da:af6b:8b2c  127.0.0.53:53
example.com.    MX      IN      77316s  0 .                                     127.0.0.53:53
example.com.    NS      IN      86400s  a.iana-servers.net.                     127.0.0.53:53
example.com.    NS      IN      86400s  b.iana-servers.net.                     127.0.0.53:53
example.com.    SOA     IN      3600s   ns.icann.org.                           127.0.0.53:53
                                        noc.dns.icann.org. 2024041841
                                        7200 3600 1209600 3600
example.com.    TXT     IN      86400s  "v=spf1 -all"                           127.0.0.53:53
example.com.    TXT     IN      86400s  "wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn"      127.0.0.53:53

Considerations

  • The --any query may take longer to complete compared to querying a single record type, as it's fetching multiple record types.

File: docs/src/content/docs/features/ip.md


title: IPv4 and IPv6 Support

Doggo provides support for both IPv4 and IPv6, allowing you to perform DNS queries over either protocol.

Default Behavior

By default, when no query type is specified, Doggo will query for both A (IPv4) and AAAA (IPv6) records. This provides a complete view of all available IP addresses for a domain.

bash
$ doggo mrkaran.dev
NAME            TYPE    CLASS   TTL     ADDRESS                         NAMESERVER
mrkaran.dev.    A       IN      300s    104.21.7.168                    127.0.0.53:53
mrkaran.dev.    A       IN      300s    172.67.187.239                  127.0.0.53:53
mrkaran.dev.    AAAA    IN      300s    2606:4700:3030::ac43:bbef       127.0.0.53:53
mrkaran.dev.    AAAA    IN      300s    2606:4700:3035::6815:7a8        127.0.0.53:53

Querying for Specific IP Versions

You can explicitly request only IPv4 or IPv6 addresses by specifying the record type:

IPv4 Only (A Records)

bash
$ doggo A mrkaran.dev
NAME            TYPE    CLASS   TTL     ADDRESS         NAMESERVER
mrkaran.dev.    A       IN      300s    104.21.7.168    127.0.0.53:53
mrkaran.dev.    A       IN      300s    172.67.187.239  127.0.0.53:53

IPv6 Only (AAAA Records)

bash
$ doggo AAAA mrkaran.dev
NAME            TYPE    CLASS   TTL     ADDRESS                         NAMESERVER
mrkaran.dev.    AAAA    IN      300s    2606:4700:3030::ac43:bbef       127.0.0.53:53
mrkaran.dev.    AAAA    IN      300s    2606:4700:3035::6815:7a8        127.0.0.53:53

Forcing IPv4 or IPv6 Transport

You can force Doggo to use only IPv4 or IPv6 network transport with the -4 and -6 flags. These flags control both the query type and which nameservers are used:

IPv4 Only

The -4 flag forces IPv4 transport and filters system nameservers to use only IPv4 addresses:

bash
$ doggo -4 mrkaran.dev
# Queries only A records and uses only IPv4 nameservers from /etc/resolv.conf

IPv6 Only

The -6 flag forces IPv6 transport and filters system nameservers to use only IPv6 addresses:

bash
$ doggo -6 mrkaran.dev
# Queries only AAAA records and uses only IPv6 nameservers from /etc/resolv.conf

:::note[Nameserver Filtering]
When using -4 or -6, Doggo automatically filters system nameservers from /etc/resolv.conf (or Windows DNS settings) to match the requested IP version. This prevents errors like "no suitable address found" when your system has both IPv4 and IPv6 nameservers configured.
:::

Using IPv6 Nameservers

Doggo supports IPv6 nameservers and accepts them in multiple formats for convenience:

With Brackets (Standard Format)

bash
$ doggo mrkaran.dev @[2606:4700:4700::1111]

Without Brackets (dig-compatible)

For compatibility with dig, you can omit the brackets:

bash
$ doggo mrkaran.dev @2606:4700:4700::1111

You can use link-local IPv6 addresses with zone identifiers:

bash
$ doggo mrkaran.dev @fe80::1%eth0

With Protocols

IPv6 addresses work with all supported protocols:

bash
# DNS over TLS
$ doggo mrkaran.dev @tls://[2606:4700:4700::1111]:853

# DNS over HTTPS
$ doggo mrkaran.dev @https://dns.google/dns-query

# DNS over QUIC
$ doggo mrkaran.dev @quic://dns.adguard-dns.com:853

File: docs/src/content/docs/features/multiple.md


title: Multiple Resolvers

Doggo supports querying multiple DNS resolvers simultaneously, allowing you to compare responses or use different resolvers for different purposes.

Using Multiple Resolvers

To use multiple resolvers, simply specify them in your command:

bash
$ doggo mrkaran.dev @1.1.1.1 @8.8.8.8 @9.9.9.9

This will query the domain mrkaran.dev using Cloudflare (1.1.1.1), Google (8.8.8.8), and Quad9 (9.9.9.9) DNS servers.

Mixing Resolver Types

You can mix different types of resolvers in a single query:

bash
doggo mrkaran.dev @1.1.1.1 @https://dns.google/dns-query @tls://9.9.9.9

This command uses a standard DNS resolver (1.1.1.1), a DoH resolver (Google), and a DoT resolver (Quad9).


File: docs/src/content/docs/features/output.md


title: Output Formats

Doggo provides flexible output formats to suit different use cases, from human-readable colored output to machine-parsable JSON.

Colored Output

By default, Doggo uses a colored, tabular format for easy readability.

bash
doggo mrkaran.dev
NAME            TYPE    CLASS   TTL     ADDRESS         NAMESERVER
mrkaran.dev.    A       IN      300s    104.21.7.168    127.0.0.53:53
mrkaran.dev.    A       IN      300s    172.67.187.239  127.0.0.53:53
bash
doggo mrkaran.dev --gp-from Europe,Asia --gp-limit 2
LOCATION                      	NAME        	TYPE	CLASS	TTL 	ADDRESS       	NAMESERVER
Vienna, AT, EU, EDIS GmbH
(AS57169)
                              	mrkaran.dev.	A   	IN   	300s	104.21.7.168  	private
                              	mrkaran.dev.	A   	IN   	300s	172.67.187.239	private
Tokyo, JP, AS, Tencent
Building, Kejizhongyi Avenue
(AS132203)
                              	mrkaran.dev.	A   	IN   	300s	104.21.7.168  	private
                              	mrkaran.dev.	A   	IN   	300s	172.67.187.239	private

To disable colored output, use the --color=false flag:

bash
doggo mrkaran.dev --color=false

JSON Output

For scripting and programmatic use, Doggo supports JSON output using the --json or -J flag:

bash
doggo internetfreedom.in --json | jq

When a response contains EDNS data, edns.nameserver identifies the resolver that returned that metadata. For Extended DNS Errors, edns.extended_errors is the authoritative array and preserves every EDE in response order with its code, standardized description, and raw extra_text. The legacy string field edns.extended_error remains for compatibility and contains only the first EDE.

Compatibility note: before this EDE correctness fix, a multi-EDE response repeatedly overwrote edns.extended_error, making the scalar last-wins. It is now intentionally first-wins; consumers that need complete or stable multi-EDE diagnostics should use edns.extended_errors.

json
{
  "responses": {
    "answers": [
      {
        "name": "internetfreedom.in.",
        "type": "A",
        "class": "IN",
        "ttl": "22s",
        "address": "104.27.158.96",
        "rtt": "37ms",
        "nameserver": "127.0.0.1:53"
      }
      // ... more entries ...
    ],
    "queries": [
      {
        "name": "internetfreedom.in.",
        "type": "A",
        "class": "IN"
      }
    ]
  }
}
bash
doggo mrkaran.dev --gp-from Europe,Asia --gp-limit 2 --json | jq
json
{
  "responses": [
    {
      "location": "Groningen, NL, EU, Google LLC (AS396982)",
      "answers": [
        {
          "name": "mrkaran.dev.",
          "type": "A",
          "class": "IN",
          "ttl": "300s",
          "address": "172.67.187.239",
          "status": "",
          "rtt": "",
          "nameserver": "private"
        }
        // ... more entries ...
      ]
    },
    {
      "location": "Jakarta, ID, AS, Zenlayer Inc (AS21859)",
      "answers": [
        {
          "name": "mrkaran.dev.",
          "type": "A",
          "class": "IN",
          "ttl": "300s",
          "address": "172.67.187.239",
          "status": "",
          "rtt": "",
          "nameserver": "private"
        }
        // ... more entries ...
      ]
    }
  ]
}

Short Output

For a more concise view, use the --short flag to show only the response section:

bash
doggo mrkaran.dev --short
104.21.7.168
172.67.187.239
bash
doggo mrkaran.dev --gp-from Europe,Asia --gp-limit 2 --short
Frankfurt, DE, EU, WIBO Baltic UAB (AS59939)
104.21.7.168
172.67.187.239
Saratov, RU, AS, LLC "SMART CENTER" (AS48763)
172.67.187.239
104.21.7.168

File: docs/src/content/docs/features/reverse.md


title: Reverse IP Lookups

Doggo supports reverse IP lookups, allowing you to find the domain name associated with a given IP address. This feature is particularly useful for network diagnostics, security analysis, and understanding the ownership of IP addresses.

Performing a Reverse IP Lookup

To perform a reverse IP lookup, use the --reverse flag followed by the IP address:

bash
doggo --reverse 8.8.4.4

Short Output Format

You can combine the reverse lookup with the --short flag to get a concise output:

bash
doggo --reverse 8.8.4.4 --short
dns.google.

This command returns only the domain name associated with the IP address, without any additional information.

Full Output Format

Without the --short flag, Doggo will provide more detailed information:

bash
$ doggo --reverse 8.8.4.4
NAME                    TYPE    CLASS   TTL     ADDRESS     NAMESERVER
4.4.8.8.in-addr.arpa.   PTR     IN      21599s  dns.google. 127.0.0.53:53

IPv6 Support

Reverse IP lookups also work with IPv6 addresses:

bash
$ doggo --reverse 2001:4860:4860::8888 --short
dns.google.

File: docs/src/content/docs/features/shell.md


title: Shell Completions

Doggo provides shell completions for zsh and fish, enhancing your command-line experience with auto-completion for commands and options.

Bash Completions

To enable Bash completions for Doggo:

  1. Generate the completion script:

    bash
    doggo completions bash > doggo_completion.bash
  2. Source the generated file in your .bashrc or .bash_profile:

    bash
    echo "source ~/path/to/doggo_completion.bash" >> ~/.bashrc

    Replace ~/path/to/ with the actual path where you saved the completion script.

  3. Restart your shell or run source ~/.bashrc.

Zsh Completions

To enable Zsh completions for Doggo:

  1. Ensure that shell completions are enabled in your .zshrc file:

    zsh
    autoload -U compinit
    compinit
  2. Generate the completion script and add it to your Zsh functions path:

    bash
    doggo completions zsh > "${fpath[1]}/_doggo"
  3. Restart your shell or run source ~/.zshrc.

Now you can use Tab to auto-complete Doggo commands and options in Zsh.

Fish Completions

To enable Fish completions for Doggo:

  1. Generate the completion script and save it to the Fish completions directory:

    bash
    $ doggo completions fish > ~/.config/fish/completions/doggo.fish
  2. Restart your Fish shell or run source ~/.config/fish/config.fish.

You can now use Tab to auto-complete Doggo commands and options in Fish.

Using Completions

With completions enabled, you can:

  • Auto-complete command-line flags (e.g., doggo --<Tab>)
  • Auto-complete DNS record types (e.g., doggo -t <Tab>)
  • Auto-complete subcommands and options

File: docs/src/content/docs/features/tweaks.md


title: Protocol Tweaks

Doggo provides several options to tweak the DNS protocol parameters, allowing for fine-grained control over your queries.

Query Flags

Doggo supports setting various DNS query flags:

text
--aa    Set Authoritative Answer flag
--ad    Set Authenticated Data flag
--cd    Set Checking Disabled flag
--rd    Set Recursion Desired flag (default: true)
--z     Set Z flag (reserved for future use)
--do    Set DNSSEC OK flag

Examples

  1. Request an authoritative answer:

    bash
    doggo example.com --aa
  2. Request DNSSEC data:

    bash
    doggo example.com --do
  3. Disable recursive querying:

    bash
    doggo example.com --rd=false

EDNS Options

EDNS (Extension Mechanisms for DNS) provides additional capabilities beyond basic DNS queries. Doggo supports several EDNS0 options:

text
--nsid      Request Name Server Identifier
--cookie    Request DNS Cookie for enhanced security
--padding   Request EDNS padding for privacy
--ede       Enable EDNS to receive Extended DNS Errors
--ecs       EDNS Client Subnet (e.g., '192.0.2.0/24')

--ede adds an OPT record to enable EDNS; it does not send an EDE option or fabricated EDE payload. Resolvers can return EDE information for any query carrying an OPT record, so Doggo also displays returned EDEs when EDNS is enabled by --do, --nsid, --cookie, --padding, --ecs, or --bufsize.

EDNS Examples

  1. Name Server Identifier (NSID) - Identify which server responded:

    bash
    doggo google.com --nsid @8.8.8.8

    Output includes:

    text
    EDNS Information:
      NSID: gpdns-maa
  2. EDNS Client Subnet (ECS) - Get geo-aware responses:

    bash
    # Query as if from USA
    doggo netflix.com --ecs 8.8.8.0/24 @8.8.8.8
    
    # Query as if from India
    doggo netflix.com --ecs 49.207.0.0/24 @8.8.8.8

    This reveals how CDNs route traffic based on client location. Netflix will return different IP addresses for different regions!

  3. DNS Cookie - Enhanced security against spoofing:

    bash
    doggo example.com --cookie @1.1.1.1
  4. EDNS Padding - Privacy protection against traffic analysis:

    bash
    doggo example.com --padding @1.1.1.1
  5. Extended DNS Errors (EDE) - Detailed error information:

    bash
    doggo nonexistent.example --ede @1.1.1.1
  6. Combine multiple EDNS options:

    bash
    doggo example.com --nsid --cookie --padding --do @8.8.8.8

Understanding ECS (EDNS Client Subnet)

ECS allows DNS resolvers to include client subnet information in queries, enabling authoritative servers to provide location-aware responses. This is commonly used by:

  • CDNs (Content Delivery Networks) to direct users to nearby servers
  • Streaming services like Netflix to serve region-specific content
  • Cloud providers to optimize latency

How it works:

  1. You specify a subnet (e.g., --ecs 8.8.8.0/24)
  2. DNS resolver includes this in the query to the authoritative server
  3. Server responds with IPs optimized for that geographic region
  4. Response includes the actual scope used (e.g., Scope: 24)

Real-world example:

bash
# From USA - returns AWS US-East servers
doggo netflix.com --ecs 8.8.8.0/24 @8.8.8.8

# From India - returns AWS EU-Ireland servers
doggo netflix.com --ecs 49.207.0.0/24 @8.8.8.8

# Different IPs returned based on location!

This lets you test geo-routing without traveling to different countries!