PKDNS: Public-Key DNS Server
PKDNS is a DNS server that enables self-sovereign and censorship-resistant domain names by resolving PKARR (Public Key Addressable Resource Records) hosted on the Mainline DHT. It bridges the gap between traditional DNS infrastructure and public key-based domains, allowing anyone to access the decentralized web using standard DNS protocols.
Overview
Section titled “Overview”PKDNS makes public-key domains accessible to everyone by acting as a DNS resolver that understands both traditional ICANN domains and PKARR-based public-key domains. When you query a public-key domain (52-character base32 encoded public key), PKDNS fetches the signed DNS records from the Mainline DHT, verifies the signature, and returns them to your browser or application—just like traditional DNS.
Key Innovation
Section titled “Key Innovation”Instead of relying on ICANN registrars and centralized name servers, PKDNS enables:
- Self-sovereign domains: Your Ed25519 public key IS your domain
- Censorship resistance: Records are distributed across ~10 million DHT nodes
- No registration fees: Publish records directly to the DHT
- Cryptographic verification: All records are signed and verifiable
- ICANN fallback: Still resolves traditional domains seamlessly
How It Works
Section titled “How It Works”Resolution Flow
Section titled “Resolution Flow”- User queries domain: Browser or app requests
7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy - PKDNS recognizes format: Identifies 52-character base32 as a public-key domain
- DHT lookup: Queries the Mainline DHT for PKARR records associated with that public key
- Signature verification: Validates that records were signed by the private key holder
- Cache and return: Caches the verified records and returns DNS response to client
- ICANN fallback: For traditional domains like
example.com, forwards to upstream DNS (default: 8.8.8.8)
Public-Key Domain Format
Section titled “Public-Key Domain Format”Public-key domains use base32-encoded Ed25519 public keys:
- Length: 52 characters (z-base-32 encoding)
- Example:
7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy - Subdomains: Support standard subdomain syntax (e.g.,
blog.7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy)
Supported Record Types
Section titled “Supported Record Types”PKDNS currently supports the most common DNS record types:
- A: IPv4 addresses
- AAAA: IPv6 addresses
- TXT: Text records
- CNAME: Canonical name records
- MX: Mail exchange records
For other record types, use bind9 or similar full-featured DNS servers.
Features
Section titled “Features”DNS-over-HTTPS (DoH)
Section titled “DNS-over-HTTPS (DoH)”PKDNS supports DNS-over-HTTPS, enabling encrypted DNS queries from browsers:
- Configure browser to use a PKDNS DoH endpoint
- All DNS queries encrypted over HTTPS
- Prevents ISP snooping on DNS traffic
- Public DoH endpoints available in servers.txt
Caching
Section titled “Caching”Multi-layer caching for optimal performance:
- Response cache: Caches DNS responses to reduce DHT queries
- PKARR cache: Stores verified PKARR records from DHT
- Configurable TTL: Respects DNS TTL values from records
Rate Limiting
Section titled “Rate Limiting”Built-in protection against abuse:
- Per-IP rate limiting to prevent DoS attacks
- Configurable thresholds and timeouts
- Protects both the server and the DHT network
Dynamic DNS (DynDNS)
Section titled “Dynamic DNS (DynDNS)”Support for dynamic IP updates:
- CLI tool for publishing updated A/AAAA records
- Automated IP detection from multiple providers
- Periodic republishing to keep records alive on DHT
- Perfect for Homeservers and dynamic IP addresses
Hybrid Resolution
Section titled “Hybrid Resolution”Seamlessly resolves both public-key domains and traditional domains:
- Public-key domains (52 chars) → DHT lookup
- ICANN domains → Upstream DNS fallback
- Configurable upstream DNS server
- No special client configuration needed
Getting Started
Section titled “Getting Started”Using Public Hosted Servers
Section titled “Using Public Hosted Servers”The easiest way to try PKDNS:
-
Choose a public server: Check servers.txt for available DNS-over-HTTPS endpoints
-
Configure your browser:
- Firefox: Settings → Network Settings → Enable DNS over HTTPS → Custom → Enter DoH URL
- Chrome: Settings → Privacy and security → Security → Use secure DNS → Custom → Enter DoH URL
- Edge: Settings → Privacy, search, and services → Security → Use secure DNS → Choose provider
-
Test it works: Visit http://7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy/
Self-Hosting PKDNS
Section titled “Self-Hosting PKDNS”Pre-Built Binaries
Section titled “Pre-Built Binaries”# Download latest release for your platformwget https://github.com/pubky/pkdns/releases/latest/download/pkdns-linux-x64.tar.gz
# Extracttar -xzf pkdns-linux-x64.tar.gz
# Run (requires port 53 access)sudo ./pkdns --verboseBuild from Source
Section titled “Build from Source”# Install Rust toolchaincurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone and buildgit clone https://github.com/pubky/pkdns.gitcd pkdnscargo build --release
# Runsudo ./target/release/pkdns --verboseDocker Deployment
Section titled “Docker Deployment”# Using Docker Composegit clone https://github.com/pubky/pkdns.gitcd pkdnsdocker compose up -d
# Or pull directlydocker pull synonymsoft/pkdnsdocker run -p 53:53/udp -p 53:53/tcp synonymsoft/pkdnsConfiguration
Section titled “Configuration”Command-Line Options
Section titled “Command-Line Options”pkdns [OPTIONS]
Options: -f, --forward <FORWARD> # ICANN fallback DNS server [default: 8.8.8.8:53] -v, --verbose # Show verbose output [default: false] -c, --config <CONFIG> # Path to config file -p, --pkdns-dir <PKDNS_DIR> # Base directory for data [default: ~/.pkdns] -h, --help # Print help -V, --version # Print versionConfiguration File
Section titled “Configuration File”Location: ~/.pkdns/pkdns.toml
Example configuration:
# Upstream DNS for ICANN domainsfallback_dns = "8.8.8.8:53"
# Enable DNS-over-HTTPS[doh]enabled = trueport = 443cert_path = "/path/to/cert.pem"key_path = "/path/to/key.pem"
# Rate limiting[rate_limit]requests_per_minute = 100burst_size = 20
# Caching[cache]max_entries = 10000ttl_seconds = 300See sample-config.toml for full options.
Verification
Section titled “Verification”Test that PKDNS is working correctly:
Verify Public-Key Domain Resolution
Section titled “Verify Public-Key Domain Resolution”# Replace SERVER_IP with your PKDNS server IP (127.0.0.1 for local)nslookup 7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy SERVER_IPExpected output: IP address(es) for the public-key domain
Verify ICANN Domain Fallback
Section titled “Verify ICANN Domain Fallback”nslookup example.com SERVER_IPExpected output: Standard DNS response for example.com
Browser Test
Section titled “Browser Test”Navigate to: http://7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy/
Expected: Website loads successfully
Tip: Always add
./at the end of public-key domain URLs, otherwise browsers may search instead of resolve.
Publishing Your Own Public-Key Domain
Section titled “Publishing Your Own Public-Key Domain”To publish a website on a public-key domain:
Generate Key Pair
Section titled “Generate Key Pair”# Using pkdns CLIpkdns-cli generate
# Outputs:# Public key: 7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy# Private key (seed): <52-character secret>⚠️ Security: Store your private key securely. Anyone with the private key can publish records for your domain.
Create DNS Zone File
Section titled “Create DNS Zone File”Create a standard DNS zone file with your records:
@ 3600 IN A 203.0.113.42@ 3600 IN AAAA 2001:db8::1www 3600 IN CNAME @Publish to DHT
Section titled “Publish to DHT”# Using pkdns CLIpkdns-cli publish --seed <your-private-key> --zone-file records.zone
# Or with dynamic IP detectionpkdns-cli publish --seed <your-private-key> --zone-file records.zone --detect-ipKeep Records Alive
Section titled “Keep Records Alive”DHT records expire after a few hours. For persistent domains:
# Manual republishingwhile true; do pkdns-cli publish --seed <your-private-key> --zone-file records.zone sleep 3600 # Republish every hourdone
# Or use DynDNS features for automationSee the publishing guide for detailed instructions.
Use Cases
Section titled “Use Cases”Self-Sovereign Web Publishing
Section titled “Self-Sovereign Web Publishing”Publish websites without:
- Domain registrars (no annual fees)
- DNS hosting services (no third-party control)
- Renewal requirements (keys don’t expire)
- Censorship risk (distributed across DHT)
Decentralized Applications
Section titled “Decentralized Applications”Enable dApps to use human-readable addresses:
- No smart contract required for DNS
- Cryptographic verification built-in
- Works with existing web infrastructure
- Low latency (~100ms typical resolution)
Development & Testing
Section titled “Development & Testing”Instant domain names for development:
- Generate test domains in seconds
- No registration or setup fees
- Update records instantly
- Perfect for CI/CD pipelines
Privacy-Focused Browsing
Section titled “Privacy-Focused Browsing”Access censorship-resistant content:
- Records can’t be seized or altered
- No central authority to pressure
- Works through standard DNS protocols
- Compatible with existing privacy tools
Personal Identity
Section titled “Personal Identity”Use your public key as your digital identity:
- Single domain across all services
- Provable ownership via signatures
- No platform lock-in
- Portable across applications
Architecture
Section titled “Architecture”Components
Section titled “Components”Server (pkdns): Main DNS server process
- Listens on port 53 (UDP/TCP) for DNS queries
- Optional DNS-over-HTTPS endpoint (port 443)
- Multi-threaded request handling
- Integration with Mainline DHT client
CLI Tool (pkdns-cli): Command-line utilities
- Key generation and management
- Record publishing and updates
- Zone file parsing
- Dynamic IP detection
PKARR Resolver: Core resolution logic
- DHT query coordination
- Signature verification
- Record caching and TTL management
- Bootstrap node management
Response Cache: Query optimization
- In-memory cache of DNS responses
- Configurable size and TTL
- LRU eviction policy
Performance Characteristics
Section titled “Performance Characteristics”- Resolution time: ~100-300ms for cold cache (DHT lookup)
- Cached resolution: <1ms (memory lookup)
- Throughput: Thousands of queries per second (cached)
- Memory footprint: ~50MB base + cache size
- DHT network: ~10 million nodes, high availability
Security Model
Section titled “Security Model”- Cryptographic verification: All PKARR records are Ed25519-signed
- No trust required: Clients verify signatures independently
- Censorship resistance: Distributed storage across massive DHT
- DoS protection: Rate limiting and query validation
- Privacy: DoH encryption for DNS queries
Limitations & Considerations
Section titled “Limitations & Considerations”Port 53 Requirement
Section titled “Port 53 Requirement”DNS servers traditionally require port 53, which needs root/admin privileges:
- Linux: Use
sudoor configure capabilities - macOS: System services may occupy port 53 (Docker Desktop)
- Windows: May conflict with other DNS services
- Workaround: Use DNS-over-HTTPS only (doesn’t require port 53)
DHT Ephemeral Storage
Section titled “DHT Ephemeral Storage”Records expire after a few hours and must be republished:
- Active domains: Need periodic republishing (~hourly)
- Automated solutions: DynDNS features handle this
- Trade-off: Prevents DHT pollution but requires maintenance
Record Size Limit
Section titled “Record Size Limit”PKARR packets must be ≤1000 bytes:
- Limits number of records per domain
- Use CNAME indirection for complex setups
- Consider multiple public keys if needed
Limited Record Type Support
Section titled “Limited Record Type Support”Currently supports only: A, AAAA, TXT, CNAME, MX
- Use bind9 for advanced record types (SRV, CAA, etc.)
- May expand in future versions
Browser Trailing Slash
Section titled “Browser Trailing Slash”Browsers may search instead of resolve domains:
- Always append
./to public-key domains in URL bar - Example:
http://7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy./ - Not needed for bookmarks or links
Troubleshooting
Section titled “Troubleshooting””Address already in use” Error
Section titled “”Address already in use” Error”Problem: Port 53 is occupied by another service
Solutions:
- Docker Desktop (macOS): Disable DNS proxy in Docker settings
- systemd-resolved (Ubuntu): Disable or reconfigure
- Alternative: Run only DoH server (doesn’t need port 53)
PKDNS Domains Don’t Resolve
Section titled “PKDNS Domains Don’t Resolve”Check:
- Server running:
ps aux | grep pkdns - Port accessible:
nc -zvu 127.0.0.1 53 - DHT connectivity: Check verbose logs for bootstrap
- Firewall rules: Allow UDP/TCP port 53
ICANN Domains Don’t Resolve
Section titled “ICANN Domains Don’t Resolve”Problem: Upstream DNS not configured correctly
Solution:
# Use reliable upstream DNSpkdns -f 8.8.8.8:53 # Google DNSpkdns -f 1.1.1.1:53 # Cloudflare DNSSlow Resolution Times
Section titled “Slow Resolution Times”Causes:
- Cold cache (first query to DHT is slower)
- DHT connectivity issues
- Network latency
Solutions:
- Pre-warm cache for frequently accessed domains
- Increase cache size in config
- Check network connectivity to DHT bootstrap nodes
Resources
Section titled “Resources”- Repository: https://github.com/pubky/pkdns
- Releases: https://github.com/pubky/pkdns/releases
- Docker Image: https://hub.docker.com/r/synonymsoft/pkdns
- Public Servers: servers.txt
- Zone Explorer: https://pkdns.net
- Telegram Chat: https://t.me/pubkycore
Documentation
Section titled “Documentation”Blog Posts
Section titled “Blog Posts”Related Tools
Section titled “Related Tools”- pkarr: Core PKARR library and specification
- pkdns-digger: Web-based DNS record lookup tool for PKARR/PKDNS
- pkdns-vanity: Generate vanity public-key domains
- awesome-pubky: Curated list of Pubky resources
See Also
Section titled “See Also”- PKARR - Public Key Addressable Resource Records
- Mainline DHT - Distributed hash table powering PKDNS
- DNS - Traditional Domain Name System
- DoH - DNS over HTTPS protocol
- Pubky Core - Core protocol and infrastructure