🌐 Languages: 🇬🇧 English (this file) • 🇩🇪 Deutsch
✅ One-Click Installation - Single command setup
✅ DNS Security - Pi-hole + Unbound with DNSSEC
✅ Network Monitoring - NetAlertX device tracking
✅ API Monitoring - Python FastAPI + SQLite
✅ Production Ready - Systemd hardening & auto-restart
✅ Idempotent - Safe to re-run anytime
git clone https://github.com/TimInTech/Pi-hole-Unbound-PiAlert-Setup.git
cd Pi-hole-Unbound-PiAlert-Setup
chmod +x install.sh
sudo ./install.shDone! 🎉 Your complete DNS security stack is now running.
| Component | Purpose | Access |
|---|---|---|
| 🕳️ Pi-hole | DNS ad-blocker & web UI | http://[your-ip]/admin |
| 🔐 Unbound | Recursive DNS + DNSSEC | 127.0.0.1:5335 |
| 📡 NetAlertX | Network device monitoring | http://[your-ip]:20211 |
| 🐍 Python API | Monitoring & stats API | http://127.0.0.1:8090 |
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Clients │───▶│ Pi-hole │───▶│ Unbound │
│ 192.168.x.x │ │ :53 │ │ :5335 │
└─────────────┘ └──────┬───────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ NetAlertX │ │ Root Servers│
│ :20211 │ │ + Quad9 │
└─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ Python API │
│ :8090 │
└─────────────┘
Data Flow:
- Clients → Pi-hole (DNS filtering)
- Pi-hole → Unbound (recursive resolution)
- Unbound → Root servers (DNSSEC validation)
- NetAlertX → Network monitoring
- Python API → Aggregated monitoring data
All endpoints require the X-API-Key header:
curl -H "X-API-Key: your-api-key" http://127.0.0.1:8090/endpoint{
"ok": true,
"message": "Pi-hole Suite API is running",
"version": "1.0.0"
}[
{
"timestamp": "Dec 21 10:30:45",
"client": "192.168.1.100",
"query": "example.com",
"action": "query"
}
][
{
"id": 1,
"ip": "192.168.1.100",
"mac": "aa:bb:cc:dd:ee:ff",
"hostname": "laptop",
"last_seen": "2024-12-21 10:30:00"
}
]{
"total_dns_logs": 1250,
"total_devices": 15,
"recent_queries": 89
}- Open
http://[your-ip]/admin - Go to Settings → DNS
- Verify Custom upstream:
127.0.0.1#5335 - Configure devices to use Pi-hole as DNS server
- Dashboard:
http://[your-ip]:20211 - Configure scan schedules and notifications
- Review network topology and device list
dig @127.0.0.1 -p 5335 example.com # Test Unbound
pihole status # Test Pi-hole
docker logs netalertx # Test NetAlertX
curl -H "X-API-Key: $SUITE_API_KEY" http://127.0.0.1:8090/health # Test APIsystemctl status pihole-suite unbound pihole-FTL
journalctl -u pihole-suite -f
journalctl -u unbound -f
docker ps| Issue | Solution |
|---|---|
| Port 53 in use | sudo systemctl stop systemd-resolved |
| Missing API key | Check .env file or regenerate with installer |
| Database errors | Run python scripts/bootstrap.py |
| Unbound won’t start | Inspect /etc/unbound/unbound.conf.d/pi-hole.conf |
- Auto-generated API keys (16-byte hex)
- CORS restricted to localhost
- Authentication required for all endpoints
- NoNewPrivileges prevents escalation
- ProtectSystem=strict read-only protection
- PrivateTmp isolated temp dirs
- Memory limits to prevent exhaustion
- Unbound bound to localhost only
- DNS over TLS to upstream resolvers
- DNSSEC validation enabled
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'feat: add amazing feature' - Run tests:
ruff check . && pytest - Push and create a Pull Request
This project is licensed under the MIT License - see LICENSE.
See CHANGELOG.md for history and updates.
Made with ❤️ for the Pi-hole community