Files
Redflag/reference/pihole_dns_management.md
Ani (Daemon) bb380849c9 refactor: Add Pi-hole DNS management reference
- CLI method (SSH to Pi-hole, edit custom.list)
- Web admin method (http://pi.hole/admin)
- API method (Pi-hole v6+ REST API with session auth)
- SDK options (pyhole6, python-hole)
- Workflow pattern for adding internal services

QGIS configured on port 3141 (π for science)
Compass audit report created - phantom files identified
2026-03-28 12:35:22 -04:00

243 lines
6.0 KiB
Markdown

---
description: Pi-hole local DNS management workflow - adding internal domains
---
# Pi-hole Local DNS Management
**Pi-hole Location:** 10.10.20.5 (Pi-hole VM or container)
**Access:** Requires SSH key authentication
**Last Updated:** 2026-03-28
## Quick Reference
### Add Local DNS Record
**Method 1: CLI (SSH to Pi-hole)**
```bash
# SSH to Pi-hole
ssh root@10.10.20.5
# Add DNS entry
echo "10.10.20.XXX domain.wiuf.net" >> /etc/pihole/custom.list
# Restart DNS
pihole restartdns
# Verify
pihole -q domain.wiuf.net
```
**Method 2: Web Admin**
1. Navigate to: http://10.10.20.5/admin (or pi.hole/admin)
2. Login with admin password
3. **Local DNS** **DNS Records**
4. **Domain:** `domain.wiuf.net`
5. **IP Address:** `10.10.20.XXX`
6. Click **Add**
7. Verify in **Custom List** section
### Common Internal Domains
| Domain | IP | Service | Added |
|--------|-----|---------|-------|
| `qgis.wiuf.net` | 10.10.20.120 | QGIS Server | 2026-03-28 |
| `deluge.wiuf.net` | 10.10.20.120 | Deluge WebUI | TBD |
| `plex.wiuf.net` | 10.10.20.120 | Plex Media | TBD |
### Remove DNS Record
**CLI:**
```bash
# Remove specific line
sed -i '/domain.wiuf.net/d' /etc/pihole/custom.list
pihole restartdns
```
**Web Admin:**
- Click **Remove** next to entry in Custom List
### Verify DNS Resolution
```bash
# From any client using Pi-hole
dig @10.10.20.5 domain.wiuf.net
# Or nslookup
nslookup domain.wiuf.net 10.10.20.5
# Test with ping
ping domain.wiuf.net
```
## Workflow Pattern
### When Adding New Internal Service:
1. **Deploy service** with compose on target server
2. **Determine IP** (usually 10.10.20.XXX where service runs)
3. **Choose domain** (format: `servicename.wiuf.net`)
4. **Add to Pi-hole** local DNS
5. **Verify resolution** from client
6. **Document** in this file
7. **Update infrastructure map** if needed
### Security Notes
- Only add .wiuf.net domains for internal services
- External domains go through Cloudflare DNS
- Ensure service is properly firewalled before exposing
- Traefik/Pangolin handles external routing for some services
## Troubleshooting
| Issue | Solution |
|-------|----------|
| DNS not resolving | Check `pihole -q domain` shows entry |
| Wrong IP returned | Flush client DNS cache, restart pihole-FTL |
| Entry not persisting | Verify `/etc/pihole/custom.list` is writable |
| Domain unreachable | Check service is running, firewall open |
## Access Required
**Current:** Manual SSH or web admin
**Future:** Consider API access or automation via SSH key
**To add Ani SSH access:**
```bash
# On Pi-hole
cat >> /root/.ssh/authorized_keys << 'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINDOGx8/YnA/5ApTW7QSnjIBUoHUuVMeUrtoUaZWyPFt ani@consciousness
EOF
```
---
*Pattern: Every internal service gets a .wiuf.net domain via Pi-hole local DNS*
## Pi-hole v6+ API Method (Recommended)
Pi-hole v6.0+ includes a comprehensive REST API at `/api/`. Self-documented at `http://pi.hole/api/docs`.
### Authentication
**Session-based (not static tokens):**
```bash
# Step 1: Get session ID (SID)
curl -k -X POST "https://pi.hole/api/auth" \
--data '{"password":"your-password"}'
# Response contains: session.sid and session.csrf
```
**Use SID in requests (4 methods):**
- Query param: `?sid=vFA+EP4MQ5JJvJg+3Q2Jnw=`
- Header: `X-FTL-SID: vFA+EP4MQ5JJvJg+3Q2Jnw=`
- Cookie: `Cookie: sid=vFA+EP4MQ5JJvJg+3Q2Jnw=`
- Body: `{"sid":"vFA+EP4MQ5JJvJg+3Q2Jnw="}`
### API: Add Local DNS Record
**A/AAAA Records:**
```bash
# Add host record via API
SID="your-session-id"
curl -k -X PATCH "https://pi.hole/api/config?sid=$SID" \
-H "Content-Type: application/json" \
--data '{
"config": {
"dns": {
"hosts": ["10.10.20.120 qgis.wiuf.net", "10.10.20.120 deluge.wiuf.net"]
}
}
}'
```
**CNAME Records:**
```bash
curl -k -X PATCH "https://pi.hole/api/config?sid=$SID" \
-H "Content-Type: application/json" \
--data '{
"config": {
"dns": {
"cnameRecords": ["*.qgis.wiuf.net,qgis.wiuf.net"]
}
}
}'
```
**Python Example (requests):**
```python
import requests
PIHOLE = "https://pi.hole"
PASS = "your_password"
# Authenticate
auth = requests.post(f"{PIHOLE}/api/auth", json={"password": PASS}, verify=False)
sid = auth.json()["session"]["sid"]
# Add local DNS record
headers = {"X-FTL-SID": sid}
config = {
"config": {
"dns": {
"hosts": ["10.10.20.XXX domain.wiuf.net"]
}
}
}
response = requests.patch(f"{PIHOLE}/api/config", headers=headers, json=config, verify=False)
# Logout
requests.delete(f"{PIHOLE}/api/auth", headers=headers, verify=False)
```
### API: Management Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/auth` | Get session (authenticate) |
| DELETE | `/api/auth` | End session (logout) |
| GET | `/api/config/dns` | Get DNS configuration |
| PATCH | `/api/config` | Update configuration |
| POST | `/api/dns/blocking` | Enable/disable blocking |
| POST | `/api/dns/cache` | Clear DNS cache |
### SDK/Client Libraries
| Library | Install | Notes |
|---------|---------|-------|
| **pyhole6** | `pip install pyhole6` | Recommended, async, auto session |
| **python-hole** | `pip install hole` | v5 & v6 unified |
| **pi_hole_api** | GitHub | Simple wrapper |
**pyhole6 Example:**
```python
import asyncio
from pyhole6 import Pyhole6
async def add_dns():
async with Pyhole6("https://pi.hole", "password") as client:
# Access config.dns.hosts
config = await client.config.get()
hosts = config["dns"]["hosts"]
hosts.append("10.10.20.XXX domain.wiuf.net")
await client.config.patch({"dns": {"hosts": hosts}})
asyncio.run(add_dns())
```
### Choosing a Method
| Situation | Method | Why |
|-----------|--------|-----|
| One-time quick add | Web UI | Simplest |
| Scripting/automation | API with requests | Flexible, standard |
| Python application | pyhole6 SDK | Cleanest code |
| Ansible/Chef/IaC | API via modules | Infrastructure as code |
| Legacy Pi-hole v5 | `/etc/pihole/custom.list` | Only option |
---
*API documentation auto-generated at: http://pi.hole/api/docs*