- Refactored README.md, getting-started.md, quick-reference.md - Enhanced setup-homelab.sh with 9-step automated process - Created services-overview.md with all stacks - Added comprehensive documentation for 57 services in docs/service-docs/ - All services include: overview, configuration, resources, educational content - Coverage: Core, Infrastructure, Dashboards, Media, Media-Extended, Home Assistant, Productivity, Utilities, Monitoring, Development stacks - Educational focus with links to tutorials, videos, and guides
605 lines
15 KiB
Markdown
605 lines
15 KiB
Markdown
# Pi-hole - Network-Wide Ad Blocker
|
|
|
|
## Table of Contents
|
|
- [Overview](#overview)
|
|
- [What is Pi-hole?](#what-is-pi-hole)
|
|
- [Why Use Pi-hole?](#why-use-pi-hole)
|
|
- [How It Works](#how-it-works)
|
|
- [Configuration in AI-Homelab](#configuration-in-ai-homelab)
|
|
- [Official Resources](#official-resources)
|
|
- [Educational Resources](#educational-resources)
|
|
- [Docker Configuration](#docker-configuration)
|
|
- [Setup and Management](#setup-and-management)
|
|
- [Advanced Topics](#advanced-topics)
|
|
- [Troubleshooting](#troubleshooting)
|
|
|
|
## Overview
|
|
|
|
**Category:** Infrastructure / Network
|
|
**Docker Image:** [pihole/pihole](https://hub.docker.com/r/pihole/pihole)
|
|
**Default Stack:** `infrastructure.yml`
|
|
**Web UI:** `https://pihole.${DOMAIN}/admin` or `http://SERVER_IP:8181/admin`
|
|
**Authentication:** Admin password set via environment variable
|
|
**DNS Port:** 53 (TCP/UDP)
|
|
|
|
## What is Pi-hole?
|
|
|
|
Pi-hole is a network-level advertisement and internet tracker blocking application that acts as a DNS sinkhole. Originally designed for Raspberry Pi, it now runs on any Linux system including Docker. It blocks ads for all devices on your network without requiring per-device configuration.
|
|
|
|
### Key Features
|
|
- **Network-Wide Blocking:** Blocks ads on all devices (phones, tablets, smart TVs)
|
|
- **DNS Level Blocking:** Intercepts DNS queries before ads load
|
|
- **No Client Software:** Works for all devices automatically
|
|
- **Extensive Blocklists:** Millions of known ad/tracking domains blocked
|
|
- **Web Interface:** Beautiful dashboard with statistics
|
|
- **Whitelist/Blacklist:** Custom domain control
|
|
- **DHCP Server:** Optional network DHCP service
|
|
- **DNS Over HTTPS:** Encrypted DNS queries (DoH)
|
|
- **Query Logging:** See all DNS queries on network
|
|
- **Group Management:** Different blocking rules for different devices
|
|
- **Regex Filtering:** Advanced domain pattern blocking
|
|
|
|
## Why Use Pi-hole?
|
|
|
|
1. **Block Ads Everywhere:** Mobile apps, smart TVs, IoT devices
|
|
2. **Faster Browsing:** Pages load faster without ads
|
|
3. **Privacy Protection:** Block trackers and analytics
|
|
4. **Save Bandwidth:** Don't download ad content
|
|
5. **Malware Protection:** Block known malicious domains
|
|
6. **Family Safety:** Block inappropriate content
|
|
7. **Network Visibility:** See what devices are connecting where
|
|
8. **Free:** No subscription fees
|
|
9. **Customizable:** Full control over blocking
|
|
|
|
## How It Works
|
|
|
|
```
|
|
Device (Phone/Computer/TV)
|
|
↓
|
|
DNS Query: "ads.example.com"
|
|
↓
|
|
Router/DHCP → Pi-hole (DNS Server)
|
|
↓
|
|
Is domain in blocklist?
|
|
├─ YES → Return 0.0.0.0 (blocked)
|
|
└─ NO → Forward to upstream DNS → Return real IP
|
|
```
|
|
|
|
### Blocking Process
|
|
|
|
1. **Device makes request:** "I want to visit ads.google.com"
|
|
2. **DNS query sent:** Device asks "What's the IP for ads.google.com?"
|
|
3. **Pi-hole receives query:** Checks against blocklists
|
|
4. **If blocked:** Returns 0.0.0.0 (null IP) - ad doesn't load
|
|
5. **If allowed:** Forwards to real DNS (1.1.1.1, 8.8.8.8, etc.)
|
|
6. **Result cached:** Faster subsequent queries
|
|
|
|
### Network Setup
|
|
|
|
**Before Pi-hole:**
|
|
```
|
|
Device → Router DNS → ISP DNS → Internet
|
|
```
|
|
|
|
**After Pi-hole:**
|
|
```
|
|
Device → Router (points to Pi-hole) → Pi-hole → Upstream DNS → Internet
|
|
↓
|
|
(blocks ads)
|
|
```
|
|
|
|
## Configuration in AI-Homelab
|
|
|
|
### Directory Structure
|
|
|
|
```
|
|
/opt/stacks/infrastructure/pihole/
|
|
├── etc-pihole/ # Pi-hole configuration
|
|
│ ├── gravity.db # Blocklist database
|
|
│ ├── custom.list # Local DNS records
|
|
│ └── pihole-FTL.db # Query log database
|
|
└── etc-dnsmasq.d/ # DNS server config
|
|
└── custom.conf # Custom DNS rules
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
```bash
|
|
# Web Interface Password
|
|
WEBPASSWORD=your-secure-password-here
|
|
|
|
# Timezone
|
|
TZ=America/New_York
|
|
|
|
# Upstream DNS Servers
|
|
PIHOLE_DNS_=1.1.1.1;8.8.8.8 # Cloudflare and Google
|
|
# PIHOLE_DNS_=9.9.9.9;149.112.112.112 # Quad9 (privacy-focused)
|
|
|
|
# Web Interface Settings
|
|
WEBTHEME=default-dark # or default-light
|
|
VIRTUAL_HOST=pihole.yourdomain.com
|
|
WEB_PORT=80
|
|
|
|
# Optional: DHCP Server
|
|
DHCP_ACTIVE=false # Set true if using Pi-hole as DHCP
|
|
DHCP_START=192.168.1.100
|
|
DHCP_END=192.168.1.200
|
|
DHCP_ROUTER=192.168.1.1
|
|
```
|
|
|
|
## Official Resources
|
|
|
|
- **Website:** https://pi-hole.net
|
|
- **Documentation:** https://docs.pi-hole.net
|
|
- **GitHub:** https://github.com/pi-hole/pi-hole
|
|
- **Docker Hub:** https://hub.docker.com/r/pihole/pihole
|
|
- **Discourse Forum:** https://discourse.pi-hole.net
|
|
- **Reddit:** https://reddit.com/r/pihole
|
|
- **Blocklists:** https://firebog.net
|
|
|
|
## Educational Resources
|
|
|
|
### Videos
|
|
- [Pi-hole - Network-Wide Ad Blocking (NetworkChuck)](https://www.youtube.com/watch?v=KBXTnrD_Zs4)
|
|
- [Ultimate Pi-hole Setup Guide (Techno Tim)](https://www.youtube.com/watch?v=FnFtWsZ8IP0)
|
|
- [How DNS Works (Explained)](https://www.youtube.com/watch?v=72snZctFFtA)
|
|
- [Pi-hole Docker Setup (DB Tech)](https://www.youtube.com/watch?v=NRe2-vye3ik)
|
|
|
|
### Articles & Guides
|
|
- [Pi-hole Official Documentation](https://docs.pi-hole.net)
|
|
- [Docker Pi-hole Setup](https://github.com/pi-hole/docker-pi-hole/)
|
|
- [Best Blocklists (Firebog)](https://firebog.net)
|
|
- [DNS Over HTTPS Setup](https://docs.pi-hole.net/guides/dns/cloudflared/)
|
|
|
|
### Concepts to Learn
|
|
- **DNS (Domain Name System):** Translates domains to IP addresses
|
|
- **DNS Sinkhole:** Returns null IP for blocked domains
|
|
- **Upstream DNS:** Real DNS servers Pi-hole forwards to
|
|
- **Blocklists:** Lists of known ad/tracker domains
|
|
- **Regex Filtering:** Pattern-based domain blocking
|
|
- **DHCP:** Network device IP assignment
|
|
- **DNS Over HTTPS (DoH):** Encrypted DNS queries
|
|
- **Local DNS:** Custom local domain resolution
|
|
|
|
## Docker Configuration
|
|
|
|
### Complete Service Definition
|
|
|
|
```yaml
|
|
pihole:
|
|
image: pihole/pihole:latest
|
|
container_name: pihole
|
|
restart: unless-stopped
|
|
hostname: pihole
|
|
networks:
|
|
- traefik-network
|
|
ports:
|
|
- "53:53/tcp" # DNS TCP
|
|
- "53:53/udp" # DNS UDP
|
|
- "8181:80/tcp" # Web Interface (remapped to avoid conflict)
|
|
# - "67:67/udp" # DHCP (optional, uncomment if using)
|
|
volumes:
|
|
- /opt/stacks/infrastructure/pihole/etc-pihole:/etc/pihole
|
|
- /opt/stacks/infrastructure/pihole/etc-dnsmasq.d:/etc/dnsmasq.d
|
|
environment:
|
|
- TZ=America/New_York
|
|
- WEBPASSWORD=${PIHOLE_PASSWORD}
|
|
- PIHOLE_DNS_=1.1.1.1;8.8.8.8
|
|
- WEBTHEME=default-dark
|
|
- VIRTUAL_HOST=pihole.${DOMAIN}
|
|
- DNSMASQ_LISTENING=all
|
|
cap_add:
|
|
- NET_ADMIN # Required for DHCP functionality
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.pihole.rule=Host(`pihole.${DOMAIN}`)"
|
|
- "traefik.http.routers.pihole.entrypoints=websecure"
|
|
- "traefik.http.routers.pihole.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.pihole.loadbalancer.server.port=80"
|
|
```
|
|
|
|
### Important Notes
|
|
|
|
1. **Port 53:** DNS must be on port 53 (cannot be remapped)
|
|
2. **Web Port:** Can use 8181 externally, 80 internally
|
|
3. **NET_ADMIN:** Required capability for DHCP and network features
|
|
4. **Password:** Set strong password via WEBPASSWORD variable
|
|
|
|
## Setup and Management
|
|
|
|
### Initial Setup
|
|
|
|
1. **Deploy Pi-hole:** Start the container
|
|
2. **Wait 60 seconds:** Let gravity database build
|
|
3. **Access Web UI:** `https://pihole.yourdomain.com/admin`
|
|
4. **Login:** Use password from WEBPASSWORD
|
|
5. **Configure Router:** Point DNS to Pi-hole server IP
|
|
|
|
### Router Configuration
|
|
|
|
**Method 1: DHCP DNS Settings (Recommended)**
|
|
1. Access router admin panel
|
|
2. Find DHCP settings
|
|
3. Set Primary DNS: Pi-hole server IP (e.g., 192.168.1.10)
|
|
4. Set Secondary DNS: 1.1.1.1 or 8.8.8.8 (fallback)
|
|
5. Save and reboot router
|
|
|
|
**Method 2: Per-Device Configuration**
|
|
- Set DNS manually on each device
|
|
- Not recommended for whole-network blocking
|
|
|
|
### Dashboard Overview
|
|
|
|
**Main Dashboard Shows:**
|
|
- Total queries (last 24h)
|
|
- Queries blocked (percentage)
|
|
- Blocklist domains count
|
|
- Top allowed/blocked domains
|
|
- Query types (A, AAAA, PTR, etc.)
|
|
- Client activity
|
|
- Real-time query log
|
|
|
|
### Managing Blocklists
|
|
|
|
**Add Blocklists:**
|
|
1. Group Management → Adlists
|
|
2. Add list URL
|
|
3. Update Gravity (Tools → Update Gravity)
|
|
|
|
**Popular Blocklists (Firebog):**
|
|
```
|
|
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
|
https://v.firebog.net/hosts/AdguardDNS.txt
|
|
https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt
|
|
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
|
|
```
|
|
|
|
**Update Gravity:**
|
|
```bash
|
|
# Via CLI
|
|
docker exec pihole pihole -g
|
|
|
|
# Or Web UI: Tools → Update Gravity
|
|
```
|
|
|
|
### Whitelist/Blacklist
|
|
|
|
**Whitelist Domain (Allow):**
|
|
1. Whitelist → Add domain
|
|
2. Example: `example.com`
|
|
3. Supports wildcards: `*.example.com`
|
|
|
|
**Blacklist Domain (Block):**
|
|
1. Blacklist → Add domain
|
|
2. Example: `ads.example.com`
|
|
|
|
**Via CLI:**
|
|
```bash
|
|
# Whitelist
|
|
docker exec pihole pihole -w example.com
|
|
|
|
# Blacklist
|
|
docker exec pihole pihole -b ads.example.com
|
|
|
|
# Regex whitelist
|
|
docker exec pihole pihole --regex-whitelist "^example\.com$"
|
|
|
|
# Regex blacklist
|
|
docker exec pihole pihole --regex "^ad[sx]?[0-9]*\..*"
|
|
```
|
|
|
|
### Query Log
|
|
|
|
**View Queries:**
|
|
1. Query Log → See all DNS requests
|
|
2. Filter by client, domain, type
|
|
3. Whitelist/Blacklist directly from log
|
|
|
|
**Privacy Modes:**
|
|
- Show Everything
|
|
- Hide Domains
|
|
- Hide Domains and Clients
|
|
- Anonymous Mode
|
|
|
|
## Advanced Topics
|
|
|
|
### Local DNS Records
|
|
|
|
Create custom local DNS entries:
|
|
|
|
**Via Web UI:**
|
|
1. Local DNS → DNS Records
|
|
2. Add domain → IP mapping
|
|
3. Example: `nas.local → 192.168.1.50`
|
|
|
|
**Via File:**
|
|
```bash
|
|
# /opt/stacks/infrastructure/pihole/etc-pihole/custom.list
|
|
192.168.1.50 nas.local
|
|
192.168.1.51 server.local
|
|
```
|
|
|
|
### Group Management
|
|
|
|
Different blocking rules for different devices:
|
|
|
|
1. **Create Groups:**
|
|
- Group Management → Groups → Add Group
|
|
- Example: "Kids Devices", "Guest Network"
|
|
|
|
2. **Assign Clients:**
|
|
- Group Management → Clients → Add client to group
|
|
|
|
3. **Configure Adlists per Group:**
|
|
- Group Management → Adlists → Assign to groups
|
|
|
|
### Regex Filtering
|
|
|
|
Advanced pattern-based blocking:
|
|
|
|
**Common Patterns:**
|
|
```regex
|
|
# Block all subdomains of ads.example.com
|
|
^ad[sx]?[0-9]*\.example\.com$
|
|
|
|
# Block tracking parameters
|
|
.*\?utm_.*
|
|
|
|
# Block all Facebook tracking
|
|
^(.+[_.-])?facebook\.[a-z]+$
|
|
```
|
|
|
|
**Add Regex:**
|
|
1. Domains → Regex Filter
|
|
2. Add regex pattern
|
|
3. Test with Query Log
|
|
|
|
### DNS Over HTTPS (DoH)
|
|
|
|
Encrypt DNS queries to upstream servers:
|
|
|
|
**Using Cloudflared:**
|
|
```yaml
|
|
cloudflared:
|
|
image: cloudflare/cloudflared:latest
|
|
container_name: cloudflared
|
|
restart: unless-stopped
|
|
command: proxy-dns
|
|
environment:
|
|
- TUNNEL_DNS_UPSTREAM=https://1.1.1.1/dns-query,https://1.0.0.1/dns-query
|
|
- TUNNEL_DNS_PORT=5053
|
|
- TUNNEL_DNS_ADDRESS=0.0.0.0
|
|
|
|
pihole:
|
|
environment:
|
|
- PIHOLE_DNS_=cloudflared#5053 # Use cloudflared as upstream
|
|
```
|
|
|
|
### Conditional Forwarding
|
|
|
|
Forward specific domains to specific DNS:
|
|
|
|
**Example:** Local domain to local DNS
|
|
```bash
|
|
# /opt/stacks/infrastructure/pihole/etc-dnsmasq.d/02-custom.conf
|
|
server=/local/192.168.1.1
|
|
```
|
|
|
|
### DHCP Server
|
|
|
|
Use Pi-hole as network DHCP server:
|
|
|
|
```yaml
|
|
environment:
|
|
- DHCP_ACTIVE=true
|
|
- DHCP_START=192.168.1.100
|
|
- DHCP_END=192.168.1.200
|
|
- DHCP_ROUTER=192.168.1.1
|
|
- DHCP_LEASETIME=24
|
|
- PIHOLE_DOMAIN=lan
|
|
|
|
ports:
|
|
- "67:67/udp" # DHCP port
|
|
```
|
|
|
|
**Steps:**
|
|
1. Disable DHCP on router
|
|
2. Enable DHCP in Pi-hole
|
|
3. Restart network devices
|
|
|
|
## Troubleshooting
|
|
|
|
### Pi-hole Not Blocking Ads
|
|
|
|
```bash
|
|
# Check if Pi-hole is receiving queries
|
|
docker logs pihole | grep query
|
|
|
|
# Verify DNS is set correctly on device
|
|
# Windows: ipconfig /all
|
|
# Linux/Mac: cat /etc/resolv.conf
|
|
# Should show Pi-hole IP
|
|
|
|
# Test DNS resolution
|
|
nslookup ads.google.com PIHOLE_IP
|
|
# Should return 0.0.0.0 if blocked
|
|
|
|
# Check gravity database
|
|
docker exec pihole pihole -g
|
|
```
|
|
|
|
### DNS Not Resolving
|
|
|
|
```bash
|
|
# Check if Pi-hole is running
|
|
docker ps | grep pihole
|
|
|
|
# Check DNS ports
|
|
sudo netstat -tulpn | grep :53
|
|
|
|
# Test DNS
|
|
dig @PIHOLE_IP google.com
|
|
|
|
# Check upstream DNS
|
|
docker exec pihole pihole -q
|
|
```
|
|
|
|
### Web Interface Not Accessible
|
|
|
|
```bash
|
|
# Check container logs
|
|
docker logs pihole
|
|
|
|
# Verify port mapping
|
|
docker port pihole
|
|
|
|
# Access via IP
|
|
http://SERVER_IP:8181/admin
|
|
|
|
# Check Traefik routing
|
|
docker logs traefik | grep pihole
|
|
```
|
|
|
|
### High CPU/Memory Usage
|
|
|
|
```bash
|
|
# Check container stats
|
|
docker stats pihole
|
|
|
|
# Database optimization
|
|
docker exec pihole pihole -q database optimize
|
|
|
|
# Reduce query logging
|
|
# Settings → Privacy → Anonymous mode
|
|
|
|
# Clear old queries
|
|
docker exec pihole sqlite3 /etc/pihole/pihole-FTL.db "DELETE FROM queries WHERE timestamp < strftime('%s', 'now', '-7 days')"
|
|
```
|
|
|
|
### False Positives (Sites Broken)
|
|
|
|
```bash
|
|
# Check query log for blocked domains
|
|
# Web UI → Query Log → Find blocked domain
|
|
|
|
# Whitelist domain
|
|
docker exec pihole pihole -w problematic-domain.com
|
|
|
|
# Or via Web UI:
|
|
# Whitelist → Add domain
|
|
|
|
# Common false positives:
|
|
# - microsoft.com CDNs
|
|
# - google-analytics.com (breaks some sites)
|
|
# - doubleclick.net (ad network but some sites need it)
|
|
```
|
|
|
|
### Blocklist Update Issues
|
|
|
|
```bash
|
|
# Manually update gravity
|
|
docker exec pihole pihole -g
|
|
|
|
# Check disk space
|
|
df -h
|
|
|
|
# Clear cache
|
|
docker exec pihole pihole -r
|
|
# Choose: Repair
|
|
```
|
|
|
|
## Security Best Practices
|
|
|
|
1. **Strong Password:** Use complex WEBPASSWORD
|
|
2. **Authelia Protection:** Add Authelia middleware for external access
|
|
3. **Firewall Rules:** Only expose port 53 as needed
|
|
4. **Update Regularly:** Keep Pi-hole container updated
|
|
5. **Backup Config:** Regular backups of `/etc/pihole` directory
|
|
6. **Query Privacy:** Enable privacy mode for sensitive networks
|
|
7. **Upstream DNS:** Use privacy-focused DNS (Quad9, Cloudflare)
|
|
8. **Monitor Logs:** Watch for unusual query patterns
|
|
9. **Network Segmentation:** Separate IoT devices
|
|
10. **HTTPS Only:** Use HTTPS for web interface access
|
|
|
|
## Performance Optimization
|
|
|
|
```yaml
|
|
environment:
|
|
# Increase cache size
|
|
- CACHE_SIZE=10000
|
|
|
|
# Disable query logging (improves performance)
|
|
- QUERY_LOGGING=false
|
|
|
|
# Optimize DNS settings
|
|
- DNSSEC=false # Disable if not needed
|
|
```
|
|
|
|
**Database Maintenance:**
|
|
```bash
|
|
# Optimize database weekly
|
|
docker exec pihole sqlite3 /etc/pihole/pihole-FTL.db "VACUUM"
|
|
|
|
# Clear old queries (keep 7 days)
|
|
docker exec pihole pihole -f
|
|
```
|
|
|
|
## Backup and Restore
|
|
|
|
### Backup
|
|
|
|
**Via Web UI:**
|
|
1. Settings → Teleporter
|
|
2. Click "Backup"
|
|
3. Download tar.gz file
|
|
|
|
**Via CLI:**
|
|
```bash
|
|
# Backup entire config
|
|
tar -czf pihole-backup-$(date +%Y%m%d).tar.gz /opt/stacks/infrastructure/pihole/
|
|
|
|
# Backup only settings
|
|
docker exec pihole pihole -a -t
|
|
```
|
|
|
|
### Restore
|
|
|
|
**Via Web UI:**
|
|
1. Settings → Teleporter
|
|
2. Choose file
|
|
3. Click "Restore"
|
|
|
|
**Via CLI:**
|
|
```bash
|
|
# Restore from backup
|
|
tar -xzf pihole-backup-20240112.tar.gz -C /opt/stacks/infrastructure/pihole/
|
|
docker restart pihole
|
|
```
|
|
|
|
## Summary
|
|
|
|
Pi-hole provides network-wide ad blocking by acting as a DNS server that filters requests before they reach the internet. It:
|
|
- Blocks ads on all devices automatically
|
|
- Improves browsing speed and privacy
|
|
- Provides visibility into network DNS queries
|
|
- Offers extensive customization
|
|
- Protects against malware and tracking
|
|
|
|
**Setup Priority:**
|
|
1. Deploy Pi-hole container
|
|
2. Set strong admin password
|
|
3. Configure router DNS settings
|
|
4. Add blocklists (Firebog)
|
|
5. Monitor dashboard
|
|
6. Whitelist as needed
|
|
7. Configure DoH for privacy
|
|
8. Regular backups
|
|
|
|
**Remember:**
|
|
- DNS is critical - test thoroughly before deploying
|
|
- Keep secondary DNS as fallback
|
|
- Some sites may break - use whitelist
|
|
- Monitor query log initially
|
|
- Update gravity weekly
|
|
- Backup before major changes
|