| Crates.io | etchdns |
| lib.rs | etchdns |
| version | 0.1.2 |
| created_at | 2025-05-16 09:29:26.843153+00 |
| updated_at | 2025-09-22 19:12:36.93643+00 |
| description | A caching DNS proxy with advanced security features, WebAssembly hooks, and comprehensive protection mechanisms |
| homepage | https://github.com/jedisct1/etchdns |
| repository | https://github.com/jedisct1/etchdns |
| max_upload_size | |
| id | 1676258 |
| size | 696,491 |
A caching DNS proxy with advanced security features
Visit the website for complete documentation: EtchDNS
Key Features • Quickstart • Installation • Configuration • Use Cases • Advanced Features • Performance Tuning • Security • Development • License
EtchDNS is a caching DNS proxy designed for security and reliability. It acts as a protective layer between clients and upstream DNS servers, providing robust caching, intelligent load balancing, and comprehensive security features.
Perfect for:
etchdns.toml configuration fileetchdns -c /path/to/etchdns.toml
Reduce load on your primary DNS servers and ensure continuity of service:
# Secondary DNS server mode
authoritative_dns = true
EtchDNS acts as a secondary authoritative DNS server for your zones, handling client requests while reducing load on your primary servers and providing protection against common attacks. Compatible with any DNS provider without requiring zone transfers.
Improve performance and reliability for local devices or provide a public DNS service:
# Cache mode
authoritative_dns = false
Configure your devices to use EtchDNS as their DNS resolver. It will cache responses, distribute queries across multiple upstream servers, and make your DNS experience more reliable and secure. Can be deployed as either a local network cache or as a public DNS service.
Create a protective layer for your network:
# Domain blocklist configuration
nx_zones_file = "nx_zones.txt"
# IP address validation and filtering
enable_strict_ip_validation = true
block_private_ips = true
block_loopback_ips = true
blocked_ip_ranges = ["203.0.113.0/24", "198.51.100.0/24"]
min_client_port = 1024
Block malicious domains, ads, or unwanted content by configuring the nx_zones.txt file with domains that should return NXDOMAIN responses. Additionally, use IP validation to block connections from suspicious or problematic IP ranges.
EtchDNS can be used as an intermediary between a DNSCrypt server proxy (such as encrypted-dns-server) and your resolver to reduce load and enhance reliability.
Implement advanced DNS processing logic:
# WebAssembly hooks
hooks_wasm_file = "hooks.wasm"
hooks_wasm_wasi = false # Set to true if your plugin needs WASI support
Use WebAssembly to implement custom filtering rules, monitoring, or modifications to DNS queries and responses.
Download the latest release from the releases page.
cargo build --release
The executable will be available at target/release/etchdns.
By default, EtchDNS is built without WebAssembly hooks support to keep the binary size smaller. If you want to enable the hooks functionality, build with the hooks feature flag:
cargo build --release --features hooks
Note that enabling the hooks feature includes a WebAssembly runtime which significantly increases the binary size. Only enable this feature if you plan to use WebAssembly extensions.
EtchDNS uses a TOML configuration file to control all aspects of its behavior. A complete example with documentation can be found in the included etchdns.toml file.
Key configuration sections include:
Create a text file with domains that should be allowed:
# Company domains
example.com
example.org
# Third-party services
github.com
google.com
Create a text file with domains that should return NXDOMAIN:
# Advertising domains
ads.example.com
analytics.example.com
# Known malicious domains
malware.example.net
EtchDNS supports EDNS-client-subnet (ECS) as defined in RFC 7871, which can improve CDN and geolocation-based DNS responses:
# EDNS-Client-Subnet configuration
enable_ecs = true
ecs_prefix_v4 = 24 # Send first 24 bits of IPv4 address (hide last 8 bits)
ecs_prefix_v6 = 56 # Send first 56 bits of IPv6 address (hide last 72 bits)
When enabled, EtchDNS will include client IP information in upstream queries, allowing DNS providers to return optimized responses based on the client's location. The prefix lengths control how much of the client's IP address is shared with upstream servers, balancing performance with privacy.
EtchDNS provides an HTTP API for remote management:
# Control API setup
control_listen_addresses = ["127.0.0.1:8080"]
control_path = "/control"
Available endpoints:
GET /control/status: Get comprehensive server status including uptime, connection stats, and health informationGET /control/cache: Get cache status information including size, hit/miss rates, and entry countsDELETE /control/cache: Clear entire cacheDELETE /control/cache/zone/<example.com>: Clear all entries for a specific zoneDELETE /control/cache/name/<example.com>: Clear a specific entry by nameNote: The WebAssembly extension system is currently under active development. While functional, expect API changes and additional features in future releases.
One of EtchDNS's most powerful features is its ability to be extended through WebAssembly modules. This allows you to implement custom DNS processing logic in any language that compiles to WebAssembly, including:
Important: To use WebAssembly extensions, you must compile EtchDNS with the
hooksfeature flag enabled:cargo build --release --features hooksThis includes the Extism WebAssembly runtime, which significantly increases the binary size.
The current implementation supports the following hook points:
hook_client_query_received: Called when a client query is received, before checking the cache
Hooks receive query information in a structured JSON format and can process data from any language that compiles to WebAssembly.
EtchDNS includes an example WebAssembly plugin in the webassembly-plugins directory. This demonstrates how to create a simple plugin that can influence DNS query processing.
To use WebAssembly extensions, specify the path to your compiled WASM file:
# WebAssembly hooks
hooks_wasm_file = "hooks.wasm"
hooks_wasm_wasi = false # Set to true if your plugin needs WASI support
See the WebAssembly Extension Guide in the Development section for details on building your own WebAssembly extensions.
For optimal performance, consider these configuration guidelines:
cache_size based on available memorymax_udp_clients and max_tcp_clients for your environmentfastest for highest performance, p2 for a good balanceserve_stale_grace_time for improved reliabilitymax_inflight_queries for query aggregation efficiencyprobe_interval to balance load balancer accuracy with network overheadEtchDNS includes several security features to protect both clients and upstream servers:
EtchDNS includes a robust IP validation system that allows you to control which client IP addresses can use your server:
# Enable strict IP validation
enable_strict_ip_validation = true
# Block private IP address ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
block_private_ips = true
# Block loopback IP address ranges (127.0.0.0/8, ::1)
block_loopback_ips = true
# Minimum port to allow from clients (ports below this will be rejected)
min_client_port = 1024
# List of blocked IP ranges
blocked_ip_ranges = ["203.0.113.0/24", "198.51.100.0/24"]
This helps protect against IP spoofing, abuse from internal networks, and connections from known problematic IP ranges. Client port validation adds another layer of security by blocking connections from privileged ports, which are commonly used in spoofing attacks.
Run the standard unit tests:
cargo test
EtchDNS includes comprehensive fuzzing tests for the DNS parsers:
Install cargo-fuzz:
cargo install cargo-fuzz
Run a specific fuzz target:
cargo fuzz run validate_dns_packet
For more details on available targets, see the fuzz/README.md file.
To build a WebAssembly extension for EtchDNS:
Make sure you've compiled EtchDNS with hooks support:
cargo build --release --features hooks
Add the WebAssembly target to your Rust toolchain:
rustup target add wasm32-unknown-unknown
Build the example Rust plugin or your own extension:
cd webassembly-plugins/rust
cargo build --target wasm32-unknown-unknown --release
The compiled WebAssembly module will be available at target/wasm32-unknown-unknown/release/etchdns_hooks_rust.wasm
Copy the WebAssembly module to your EtchDNS directory and update the configuration:
cp target/wasm32-unknown-unknown/release/etchdns_hooks_rust.wasm /path/to/etchdns/hooks.wasm
Alternatively, you can build the Zig example plugin:
Navigate to the Zig plugin directory:
cd webassembly-plugins/zig
Build the Zig plugin:
zig build
The compiled WebAssembly module will be available in the zig-out/bin/ directory
For other languages, consult their respective WebAssembly compilation guides. The key requirement is that the resulting WASM module exports functions that match the hook interface defined by EtchDNS.
If your WebAssembly plugin requires access to system resources (file system, environment variables, etc.), you can enable WASI support in the configuration:
# Enable WASI for WebAssembly hooks
hooks_wasm_wasi = true
This allows your plugin to use WASI system calls, but increases the security risk. Only enable this if your plugin specifically needs these capabilities.
Note: If you try to use WebAssembly hooks with an EtchDNS binary that was compiled without the
hooksfeature, the hooks functionality will not be available and any hook-related configuration will be ignored.
This project is licensed under the MIT License.
Note: Current DoH support is limited to traditional DoH, not Oblivious DoH (ODoH). For a mature, battle-tested DoH server implementation, consider doh-server instead.