Add a shared Docker network (dnsnet, 10.53.0.0/24) connecting Pi-hole and
Technitium containers so Pi-hole can conditionally forward knel.net and
Tailscale-reverse queries to the local authoritative Technitium instance
(10.53.0.53) instead of netboot's upstream 192.168.3.16. Also adds
end-to-end documentation for both the reference node (pfv-netboot) and
the replicated nodes (pfv-netinfra-01/02).
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
117 lines
6.2 KiB
Markdown
117 lines
6.2 KiB
Markdown
# pfv-netboot — Reference Network Infrastructure (READ-ONLY reference)
|
|
|
|
> **Status:** REFERENCE SOURCE ONLY. This node is production infrastructure.
|
|
> Do **not** modify it. This document describes it as audited so its services can
|
|
> be replicated to `pfv-netinfra-01` / `pfv-netinfra-02`. All data below was
|
|
> collected by **read-only** audit scripts (`audit-netboot.sh`,
|
|
> `deep-audit-netboot.sh`, `gather-configs.sh`) on 2026-07-27/28.
|
|
|
|
## 1. Host
|
|
|
|
| Item | Value |
|
|
|---|---|
|
|
| Hostname / FQDN | `pfv-netboot` / `pfv-netboot.knel.net` |
|
|
| OS | Debian GNU/Linux 12 (bookworm), kernel 6.1.0-44-amd64 |
|
|
| Hardware | 2 vCPU, ~1.9 GiB RAM, 491 GB disk (18 GB used) |
|
|
| Timezone | `America/Chicago` (US/Central) |
|
|
| LAN | `eth0` static `192.168.3.250/22`, gw `192.168.3.254` (`/etc/network/interfaces`) |
|
|
| Tailscale | `100.103.64.82` (`tailscale0`) |
|
|
| DNS resolver | Tailscale MagicDNS — `/etc/resolv.conf` → `100.100.100.100` |
|
|
| Docker | Docker Engine 29.6.2 (containerd v2.2.6, runc 1.3.6) |
|
|
| Access | `localuser` has passwordless sudo; **not** in `docker` group (uses `sudo docker`) |
|
|
|
|
`eth1` is up but unconfigured; many docker bridges exist (`pihole_default`,
|
|
`ntp_default`, `dns_default`, and several stale ones).
|
|
|
|
## 2. Services overview
|
|
|
|
| Service | Form | Running? |
|
|
|---|---|---|
|
|
| **Pi-hole** (DNS sinkhole, recursive resolver) | Docker container `pihole` | ✅ healthy |
|
|
| **NTP** — overlay on Tailscale IP | Docker container `tsys-ntp` (`dockurr/chrony`) | ✅ healthy |
|
|
| **NTP** — system clock + LAN serving | bare-metal `ntpsec` (`ntpd`) | ✅ active, enabled |
|
|
| **Technitium DNS** (authoritative for `knel.net`) | Docker container | ❌ **not running**; config preserved in orphaned volume |
|
|
|
|
## 3. Pi-hole (container)
|
|
|
|
- **Compose:** `/root/pihole/docker-compose.yml` (compose project `pihole`)
|
|
- **Image:** `pihole/pihole:latest` — Core **v6.1.2**, Web v6.2.1, FTL v6.2.2
|
|
- **Container:** `pihole`, `restart: always`, `cap_add: [SYS_NICE]`, network `pihole_default`
|
|
- **Ports (host):**
|
|
|
|
| Host | Container | Purpose |
|
|
|---|---|---|
|
|
| `53/tcp`, `53/udp` | 53 | DNS |
|
|
| `10002/tcp` | 80 | Web admin (HTTP) |
|
|
| `10003/tcp` | 443 | Web admin (HTTPS, self-signed) |
|
|
|
|
- **Environment:** `TZ=America/Chicago`, `FTLCONF_webserver_api_password=REDACTED_PASSWORD`, `FTLCONF_dns_listeningMode=all`
|
|
- **Data:** bind mount `/root/pihole/etc-pihole:/etc/pihole` (dir owned by `localuser`; files by container `pihole` uid)
|
|
- **Config (Pi-hole v6 TOML):** `pihole.toml`. Key settings:
|
|
- Upstream DNS: `192.168.3.16`, `8.8.8.8`, `2001:4860:4860::8888`
|
|
- `listeningMode = "ALL"`, `interface = "eth0"`, `dns.port = 53`, `dns.domain = "lan"`
|
|
- `queryLogging = true`, DNSSEC off
|
|
- **Adlists:** one entry — `https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts` (in `gravity.db`/`adlists.list`)
|
|
- **Gravity DB:** `/etc/pihole/gravity.db` (~5.5 MB) holds adlists/domainlists/clients/groups
|
|
- **Web admin:** `http://pfv-netboot:10002/admin/` (password `REDACTED_PASSWORD`)
|
|
- Note: query history `pihole-FTL.db` (~2.5 GB) is transient and **excluded** from replication.
|
|
|
|
## 4. NTP (two layers)
|
|
|
|
### 4a. chrony container (`tsys-ntp`) — overlay on the Tailscale IP
|
|
- **Compose:** `/root/NTP/docker-compose.yml` (project `ntp`)
|
|
- **Image:** `dockurr/chrony`
|
|
- **Env:** `NTP_SERVERS=pool.ntp.org`
|
|
- **Ports:** `100.103.64.82:123:123/udp` — bound specifically to the **Tailscale IP**
|
|
- `restart: always`
|
|
- chrony.conf (generated): `server pool.ntp.org iburst`, `allow all`, `rtcsync`
|
|
- On netboot this coexists with bare-metal ntpsec because ntpsec here does **not** pre-bind the specific Tailscale-IP socket, letting Docker claim it.
|
|
|
|
### 4b. bare-metal `ntpsec`
|
|
- Unit `ntpsec.service` — active, enabled; `/usr/sbin/ntpd -c /etc/ntpsec/ntp.conf -g -N -u ntpsec:ntpsec`
|
|
- **Config** (`/etc/ntpsec/ntp.conf`):
|
|
```
|
|
driftfile /var/lib/ntp/ntp.drift
|
|
leapfile /usr/share/zoneinfo/leap-seconds.list
|
|
server pfvsvrpi.knel.net
|
|
restrict 127.0.0.1
|
|
restrict ::1
|
|
```
|
|
- Listens on all local addresses (incl. Tailscale) for UDP/123; serves LAN clients.
|
|
|
|
## 5. Technitium DNS (currently stopped)
|
|
|
|
- **Not running** — no container and **no compose file** exists for it.
|
|
- A previous deployment left an **orphaned Docker volume** `dns_tsys-dns-config`
|
|
(mountpoint `/var/lib/docker/volumes/dns_tsys-dns-config/_data`) whose contents
|
|
are intact (last activity 2025-06-23). A second typo'd volume
|
|
`dns_tyss-dns-config` is empty.
|
|
- Config files are **binary** (Technitium's own serialization), but copy verbatim:
|
|
`dns.config`, `auth.config`, `log.config`, `scopes/Default.scope`,
|
|
`self-signed-cert.pfx`, `cache.bin`, `zones/`, `stats/`, `logs/`.
|
|
- **Zones present** (12 reverse + 1 forward):
|
|
- `knel.net.zone` — forward zone; SOA `dns.knel.net. hostadmin.knel.net.` (serial `2025062313`). A-records for the internal fleet, including: `tsys1`, `rr-middleware`, `pfv-netboot`, `pfv-k8s-cnode1`…`cnode5`, `pfv-k8s-wnode3`, `tsys-k8scloud-netcup-1`, `tsys-kali-vptechops`, `tsys-kali-dev`; NS `dns.knel.net`.
|
|
- Reverse zones for Tailscale CGNAT ranges (`100.x.in-addr.arpa`): `199.86`, `145.105`, `181.103`, `184.108`, `194.67`, `2.108`, `211.114`, `46.96`, `64.103`, `75.110`, `97.82`, `119.127`.
|
|
- **Auth:** `auth.config` defines user `admin` (Administrators group) with a stored password hash; the plaintext password is whatever was set on the original Technitium instance.
|
|
- The compose project name historically was `dns` (network `dns_default` still exists).
|
|
|
|
## 6. Firewall / misc
|
|
|
|
- nftables/iptables: mostly Docker + Tailscale chains (`ts-input`, `ts-forward`,
|
|
`DOCKER`, `DOCKER-FORWARD`); default `INPUT ACCEPT`, `FORWARD DROP`,
|
|
`OUTPUT ACCEPT`. No UFW / firewalld.
|
|
- Also runs (out of scope for this replication): Samba (137/138/139, 445), NFS
|
|
(2049), rpcbind (111), Postfix (25), Cockpit (9090), Beszel agent, webmin/
|
|
usermin (10000/10002/20000), Tailscale (41641).
|
|
- SELinux absent; AppArmor default docker profile.
|
|
|
|
## 7. How it was audited (no changes made)
|
|
|
|
```bash
|
|
ssh localuser@pfv-netboot 'bash -s' < audit-netboot.sh # broad read-only sweep
|
|
ssh localuser@pfv-netboot 'bash -s' < deep-audit-netboot.sh # docker inspect + compose
|
|
ssh localuser@pfv-netboot 'bash -s' < gather-configs.sh # pihole.toml + technitium
|
|
```
|
|
|
|
Artifacts: `netboot-audit.txt`, `netboot-deep-audit.txt`, `netboot-configs.txt`.
|