DNSHole: A Fast, Lightweight Pi-hole Alternative Written in Rust
Discover how Rust-based DNS sinkholes like crab-hole and rhole offer a memory-safe, low-overhead alternative to Pi-hole for your homelab. Learn to deploy your own network-wide ad blocker with native encrypted DNS support.
Table of Contents
- What Is a DNS Sinkhole, Anyway?
- Why Rust? The Case for Modern DNS
- Memory Safety
- Single Binary Deployment
- Lower Resource Usage
- Native Encrypted DNS
- The Main Contenders: crab-hole, rhole, and DNS-Sinky
- crab-hole
- rhole
- DNS-Sinky
- Comparison at a Glance
- Getting Started: Deploying crab-hole
- Option 1: Docker Deployment (Recommended)
- Option 2: Bare Metal Installation
- Configuring Your Network
- Approach 1: Router Configuration (Recommended)
- Approach 2: DNS Forwarding on Router
- Approach 3: Per-Device Configuration
- Blocklist Management
- Recommended Blocklist Sources
- Managing Whitelists
- Performance Expectations
- When to Choose What
- Hardware Recommendations
- Raspberry Pi Compatibility
- Conclusion
If you’ve been running a homelab for any amount of time, you’ve probably heard of Pi-hole—the beloved network-wide ad blocker that sits at the edge of your network and swallows up tracking requests before they ever leave your house. It’s a classic for a reason: it works, it’s well-documented, and it has a massive community behind it.
But what if you’re looking for something different? Something lighter, faster, and built with modern development practices? Enter DNSHole—a growing category of Rust-based DNS sinkhole projects that aim to give Pi-hole a run for its money.
In this article, we’ll explore what makes Rust-based DNS solutions compelling, compare the main options available today, and walk through setting one up on your homelab. By the end, you’ll have everything you need to decide whether a Rust DNS sinkhole belongs in your infrastructure.
What Is a DNS Sinkhole, Anyway?
Before we dive into the Rust alternatives, let’s quickly cover what a DNS sinkhole actually does—especially if you’re new to homelab networking.
A DNS sinkhole sits between your devices and the internet, acting as your network’s DNS server. Every time a device on your network asks “Where is this domain?” (a DNS query), your sinkhole intercepts that request and checks it against a database of blocked domains. If the domainis on the blocklist—say, an ad tracker or malware domain—the sinkhole returns an empty or redirected response, effectively blocking the request before it ever reaches the outside world.
For legitimate domains, the sinkhole forwards the query to an upstream DNS server (like Cloudflare, Google, or Quad9) and returns the real IP address to your device.
Your Device → DNS Sinkhole → Blocklist Check → Forward to Upstream DNS → Response
↓
Blocked domains return nothing (ads, trackers, malware)
This approach is powerful because it works at the network level. Every device on your network—phones, tablets, smart TVs, evenIoT devices—gets ad blocking without needing individual configuration.
Why Rust? The Case for Modern DNS
Pi-hole has been the go-to choice for network-wide ad blocking since 2015. It’s written primarily in PHP and Python, with a C-based DNS core (FTLDNS, a modified dnsmasq). It’s mature, battle-tested, and has excellent documentation.
So why would anyone want to rewrite this in Rust?
Memory Safety
Rust’s ownership model eliminates entire classes of bugs at compile time. Buffer overflows, use-after-free errors, and null pointer dereferences—common vulnerabilities in C/C++ DNS implementations—simply can’t happen in safe Rust. For a service that sits at the edge of your network and parses untrusted input all day long, this matters.
Single Binary Deployment
Pi-hole requires PHP, Python, a web server, and a database. A Rust solution? It’s a single binary you drop on any system. No runtime dependencies, no package version conflicts, no “it works on my machine” headaches. This makes deployment to ARM devices, embedded systems, or exotic platforms significantly easier.
Lower Resource Usage
Rust binaries typically use less memory than comparable Python applications. Pi-hole’s core is C (so it’s already efficient), but the surrounding infrastructure—web interface, scripts, database—adds overhead. Rust solutions tend to run in 20-50MB of RAM versus Pi-hole’s 50-100MB+. On a Raspberry Pi Zero or similar constrained hardware, every megabyte counts.
Native Encrypted DNS
Here’s where Rust solutions really shine: built-in support for DNS-over-HTTPS (DoH), DNS-over-TLS (DoT), and even DNS-over-QUIC (DoQ). With Pi-hole, you need to run additional services like cloudflared or configure a reverse proxy to get encrypted DNS. With crab-hole or rhole, it’s native—just configure your upstream servers and you’re done.
:::tip[Why Encrypted DNS Matters] Standard DNS queries travel in plaintext. Anyone on your network path—your ISP, a coffee shop operator, or a malicious actor—can see what domains you’re resolving. Encrypted DNS (DoH/DoT) encrypts these queries between your DNS server and the upstream resolver, improving privacyand preventing tampering. :::
The Main Contenders: crab-hole, rhole, and DNS-Sinky
Let’s look at the three main Rust-based DNS sinkhole projects available today.
crab-hole
crab-hole is the most feature-complete Pi-hole alternative, built on thehickory-dns (formerly trust-dns) library. It’s a drop-in replacement that focuses on correctness and performance.
Key features:
- Native DoH, DoT, and DoQ support
- Multiple blocklist sources (remote URLs and local files)
- Whitelist/allowlist support
- DNSSEC validation for upstream queries
- TOML-based configuration
- Privacy-friendly defaults
Trade-offs:
- No web interface (API only)
- Configuration via config file (not GUI)
- Per-client filtering not yet implemented
crab-hole is ideal for users who prefer command-line configuration and want maximum performance with encrypted DNS out of the box.
rhole
rhole takes a different approach—it’s built with a web interface and focuses on ease of use while still being written in Rust/React.
Key features:
- Web interface for monitoring
- YAML configuration
- Custom DNS records
- DNS-over-HTTPS client
- Real-time query logging
Trade-offs:
- No DoT or DoQ support (DoH only for upstream)
- Smaller community
- Less documentation
rhole is worth considering if you want a visual interface and don’t need DoT/DoQ.
DNS-Sinky
DNS-Sinky is the simplest of the three—a minimal DNS sinkhole implementation that’s perfect for learning or lightweight deployments.
Key features:
- Simple JSON configuration
- Terminal-based logging
- Minimal dependencies
- Easy to understand codebase
Trade-offs:
- No web interface
- No encrypted DNS support
- Basic feature set
DNS-Sinky is great for educational purposes or if you want to understand how DNS sinkholes work at a fundamental level.
:::warning[Project Maturity] While Rust-based DNS solutions are promising, they’re newer than Pi-hole and have smaller communities. If you’re running a critical network or need enterprise support, Pi-hole’s maturity might still be the better choice. For homelab use, the Rust options are perfectly viable. :::
Comparison at a Glance
| Feature | Pi-hole | crab-hole | rhole | DNS-Sinky |
|---|---|---|---|---|
| Language | PHP/Python + C | Rust | Rust/React | Rust |
| WebInterface | ✅ Full-featured | ❌ API only | ✅ Basic | ❌ |
| DNS-over-HTTPS | ❌ (needs proxy) | ✅ Native | ✅ Client | ❌ |
| DNS-over-TLS | ❌ (needs proxy) | ✅ Native | ❌ | ❌ |
| DNS-over-QUIC | ❌ | ✅ Native | ❌ | ❌ |
| Custom DNS Records | ✅ | ✅ | ✅ | ❌ |
| Per-client Filtering | ✅ | ❌ | ✅ | ❌ |
| Cross-platform | Linux only | ✅ Any | ✅ Any | ✅ Any |
| Memory Usage | ~50-100MB | ~20-50MB | ~30-60MB | ~10-30MB |
Getting Started: Deploying crab-hole
Let’s walk through deploying crab-hole—the most feature-complete Rust DNS sinkhole. We’ll cover Docker deployment (the easiest approach) and bare metal installation.
Option 1: Docker Deployment (Recommended)
Docker is the simplest way to get started with crab-hole. You’ll need Docker and Docker Compose installed on your system.
Create a docker-compose.yml file:
version: '3.3'
services:
crab-hole:
image: 'ghcr.io/luckyturtledev/crab-hole:latest'
container_name: crab-hole
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:8080" # API port (optional)
volumes:
- './config.toml:/data/config.toml:ro'
- './data:/data'
Now create your config.toml file:
# Blocklist configuration
[blocklist]
include_subdomains =true
lists = [
# Balanced blocklist (recommended to start)
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
# Add more lists as needed
# "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
]
allow_list = ["file:///data/allowed.txt"]
# DNS server configuration
[[downstream]]
protocol = "udp"
listen = "[::]"
port = 53
# Upstream DNS servers (Cloudflare over TLS)
[[upstream.name_servers]]
socket_addr = "1.1.1.1:853"
protocol = "tls"
tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com"
[[upstream.name_servers]]
socket_addr = "1.0.0.1:853"
protocol = "tls"
tls_dns_name = "cloudflare-dns.com"
# API configuration (optional)
[api]
port = 8080
listen = "0.0.0.0"
admin_key = "your-secret-key-here" # Change this!
Create your allowlist file:
mkdir -p data
touch data/allowed.txt
Start the container:
docker compose up -d
:::tip[Testing Your Setup]
After starting crab-hole, test it by querying your server directly: dig @localhost google.com. You should get a valid response. Then test blocking: dig @localhost doubleclick.net should return no results or a redirected address.
:::
Option 2: Bare Metal Installation
If you prefer running directly on hardware without Docker, here’s how to install crab-hole:
Install Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
Install crab-hole:
cargo install crab-hole --locked
Create configuration directory:
sudo mkdir -p /etc/crab-hole
sudo nano /etc/crab-hole/config.toml
# Paste your config here
Create a systemd service:
cat > /tmp/crab-hole.service <<'EOF'
[Unit]
Description=crab-hole DNS server
After=network.target
[Service]
Type=simple
ExecStart=/root/.cargo/bin/crab-hole
WorkingDirectory=/etc/crab-hole
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo mv /tmp/crab-hole.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now crab-hole
:::warning[Port 53 Permissions]
On Linux systems, binding to port 53 (a privileged port below 1024) requires root or the CAP_NET_BIND_SERVICE capability. Either run crab-hole as root, or configure it to listen on a higher port and use firewall rules to redirect traffic.
:::
Configuring Your Network
Once crab-hole is running, you need to tell your devices to use it as their DNS server. There are three main approaches:
Approach 1: Router Configuration (Recommended)
Configure your router to advertise crab-hole as the DNS server via DHCP. All devices will automatically use it:
- Log into your router’s admin interface
- Find the DHCP settings
- Set the DNS server to your crab-hole IP address
- Save and apply (devices may need to reconnect)
Approach 2: DNS Forwarding on Router
Some routers let you configure DNS forwarding, where the router itself forwards queries to your crab-hole server. This keeps your devices pointing at the router while the router does the filtering.
Approach 3: Per-Device Configuration
You can manually configure DNS on each device, but this is tedious and doesn’t cover devices you can’t easily configure (IoT, smart TVs).
:::tip[Router DNS Settings] Many consumer routers have DNS settings under LAN→ DHCP or Network → DHCP. Look for “DNS Server” or “DNS Forwarding” options. If your router doesn’t support custom DNS, consider flashing it with OpenWrt or using crab-hole as your DHCP server instead. :::
Blocklist Management
The effectiveness of your DNS sinkhole depends entirely on your blocklists. Here are the best sources and how to use them.
Recommended Blocklist Sources
StevenBlack’s Hosts (Balanced):
lists = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
]
- ~60,000 blocked domains
- Well-maintained, minimal false positives
Aggressive (Ads+ Gambling + Porn + Fake News):
lists = [
"https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn/hosts"
]
- ~400,000+ blocked domains
- More comprehensive, but higher false positive risk
Privacy-Focused:
lists = [
"https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
"https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt"
]
- Focuses on tracking and ads
- Good for privacy-conscious setups
Managing Whitelists
Eventually, you’ll find that something you need is blocked. Creating a whitelist is simple:
echo "example.com" >> data/allowed.txt
echo "api.needed-service.com" >> data/allowed.txt
Restart crab-hole to apply changes:
docker compose restart
# or
sudo systemctl restart crab-hole
Performance Expectations
Let’s address the elephant in the room: does Rust actually perform better than Pi-hole’s C core?
For home network use (typically under 100 queries per second), both solutions are more than fast enough. You won’t notice a difference browsing the web or streaming video.
However, if you’re running a DNS server for multiple networks, have many IoT devices, or just want the most efficient system possible, Rust’s advantages become apparent:
| Metric | Pi-hole | crab-hole |
|---|---|---|
| Typical Memory | 50-100MB | 20-50MB |
| Startup Time | 2-5 seconds | <1 second |
| Dependencies | PHP, Python, web server, database | Single binary |
| Battery Impact (laptops) | N/A (for laptop power) | Lower CPU = less power |
On a Raspberry Pi Zero W with 512MB of RAM, every megabyte saved is memory available for other services. Rust’s efficiency matters on constrained hardware.
When to Choose What
Choose crab-hole if:
- You want native encrypted DNS (DoH/DoT/DoQ)
- You prefer a single binary with no dependencies
- You’re comfortable with TOML configuration files
- Cross-platform support (ARM, x86, BSD, etc.) matters
- You’re running on constrained hardware
Choose rhole if:
- You want a web interface for monitoring (but not configuration)
- You prefer YAML over TOML
- You need custom DNS records for your network
Choose Pi-hole if:
- You want the easiest setup and best documentation
- You need per-client filtering (different rules for different devices)
- You want a full-featured web interface for all management
- You need DHCP server functionality
- You want proven reliability and massive community support
:::tip[Start Simple] If this is your first DNS sinkhole, start with Pi-hole. The documentation and community support are invaluable when learning. Once you’re comfortable with DNS concepts, explore Rust alternatives to see if they fit your needs better. :::
Hardware Recommendations
One of the beauties of Rust-based DNS solutions is their efficiency. Here’s what you need:
| Hardware | RAM | Storage | Notes |
|---|---|---|---|
| Minimum | 256MB | 4GB | Works, but tight |
| Recommended | 512MB - 1GB | 8-16GB | Comfortable overhead |
| Ideal | 1GB+ | 16GB+ | Room for other services |
Raspberry Pi Compatibility
- Pi Zero W: Works but limited performance
- Pi 3B/3B+: Great balance of performance and power
- Pi 4: Excellent performance; gigabit Ethernet
- Pi 5: Overkill for DNS alone, but great if running other services
Conclusion
The Rust-based DNS sinkhole ecosystem is maturing rapidly. Projects like crab-hole and rhole offer compelling alternatives to Pi-hole, particularly for users who value memory safety, minimal dependencies, and native encrypted DNS support.
Are they ready to replace Pi-hole entirely? For many homelab enthusiasts, yes. The setup is straightforward, performance is excellent, and the security benefits of Rust are real. For production or critical deployments, Pi-hole’s maturity and documentation still give it an edge.
The best part? Trying a Rust DNS sinkhole is risk-free. You can run one alongside Pi-hole on different ports, test it for a few days, and switch when you’re confident. Your network, your choice.
If you’ve been curious about what life looks like after Pi-hole, give crab-hole a spin. It might just become your new favorite homelab service.
Further Reading:

Comments
Powered by GitHub Discussions