restructure: move proxmox/ into subfolder, add pihole/ section

All existing content moved from repo root into proxmox/ to make room
for other Debian machine configs. Adds pihole/ with:

- config/pihole.toml — snapshot of current Pi-hole v6 config
- config/dnsmasq.d/99-ipxe-chainload.conf — custom PXE DHCP rules
  (EFI/BIOS iPXE chainload, fixed tag-specificity bug for UEFI boot)
- pull-config.sh <source-host> <dest-dir> — pull live config to disk
- apply-config.sh <source-dir> <dest-host> — push config to a Pi-hole

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XRzqNDrbnYR22ZgZj1Bg3s
This commit is contained in:
beatzaplentyandClaude Sonnet 4.6 committed 2026-07-23 12:16:35 +10:00
1 parent 7a038b534f
commit 2909db5d04
28 files changed
+1894

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
# Apply a Pi-hole configuration directory to a destination Pi-hole instance.
#
# Usage: apply-config.sh <source-dir> <dest-host>
# source-dir Local directory containing config files (as written by pull-config.sh)
# dest-host SSH-reachable hostname or IP of the destination Pi-hole
#
# Example:
# ./apply-config.sh ./config root@pihole-new
# ./apply-config.sh /backup/pihole-20260723 root@192.168.2.101
#
# The destination Pi-hole must already have Pi-hole v6 installed.
# pihole-FTL is restarted at the end to apply the new config.
set -euo pipefail
usage() {
echo "Usage: $(basename "$0") <source-dir> <dest-host>" >&2
echo " source-dir Local directory with config files (from pull-config.sh)" >&2
echo " dest-host SSH target for the destination Pi-hole (e.g. root@pihole)" >&2
exit 1
}
[[ $# -eq 2 ]] || usage
SOURCE="$1"
DEST="$2"
[[ -d "${SOURCE}" ]] || { echo "Error: source directory '${SOURCE}' not found" >&2; exit 1; }
[[ -f "${SOURCE}/pihole.toml" ]] || { echo "Error: '${SOURCE}/pihole.toml' not found — is this a valid config dir?" >&2; exit 1; }
echo "Applying Pi-hole config from ${SOURCE} → ${DEST}"
# ── Verify destination is running Pi-hole ──────────────────────────────────────
ssh "${DEST}" "command -v pihole-FTL >/dev/null 2>&1 || { echo 'pihole-FTL not found on destination'; exit 1; }"
# ── pihole.toml ────────────────────────────────────────────────────────────────
echo " pihole.toml"
ssh "${DEST}" "cp /etc/pihole/pihole.toml /etc/pihole/pihole.toml.pre-apply 2>/dev/null || true"
scp "${SOURCE}/pihole.toml" "${DEST}:/etc/pihole/pihole.toml"
ssh "${DEST}" "chown pihole:pihole /etc/pihole/pihole.toml; chmod 640 /etc/pihole/pihole.toml"
# ── custom dnsmasq drop-ins ────────────────────────────────────────────────────
if [[ -d "${SOURCE}/dnsmasq.d" ]] && [[ -n "$(ls "${SOURCE}/dnsmasq.d/"*.conf 2>/dev/null)" ]]; then
echo " dnsmasq.d/ (custom drop-ins)"
for f in "${SOURCE}/dnsmasq.d/"*.conf; do
name="$(basename "$f")"
echo " ${name}"
scp "${f}" "${DEST}:/etc/dnsmasq.d/${name}"
done
fi
# ── Restart pihole-FTL ─────────────────────────────────────────────────────────
echo " Restarting pihole-FTL"
ssh "${DEST}" "systemctl restart pihole-FTL"
sleep 2
ssh "${DEST}" "systemctl is-active pihole-FTL"
echo "Done. Config applied to ${DEST}."
echo "Note: gravity (blocklists) is not transferred — run 'pihole updateGravity' on ${DEST} to rebuild."
@@ -0,0 +1,20 @@
# Detect iPXE clients (already running iPXE).
dhcp-match=set:ipxe,175
dhcp-userclass=set:ipxe,iPXE
# Detect UEFI x86_64 clients by client architecture.
dhcp-match=set:efi64,option:client-arch,7
dhcp-match=set:efi64,option:client-arch,9
# Boot file selection — more positive tags = higher priority.
# EFI iPXE (2 tags): already running iPXE on EFI, chain to HTTP menu.
dhcp-boot=tag:ipxe,tag:efi64,http://192.168.2.247/boot.ipxe
# BIOS iPXE (1 tag): already running iPXE, chain to HTTP menu.
dhcp-boot=tag:ipxe,http://192.168.2.247/boot.ipxe
# EFI non-iPXE (1 tag): send the EFI iPXE binary.
dhcp-boot=tag:efi64,ipxe.efi,,192.168.2.247
# BIOS/legacy fallback (0 tags): send the BIOS iPXE binary.
dhcp-boot=undionly.kpxe,,192.168.2.247
File diff suppressed because it is too large. Load diff
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Pull Pi-hole configuration from a running instance to a local directory.
#
# Usage: pull-config.sh <source-host> <dest-dir>
# source-host SSH-reachable hostname or IP of the source Pi-hole
# dest-dir Local directory to write config into (created if absent)
#
# Example:
# ./pull-config.sh root@pihole ./config
# ./pull-config.sh root@192.168.2.100 /backup/pihole-$(date +%Y%m%d)
set -euo pipefail
usage() {
echo "Usage: $(basename "$0") <source-host> <dest-dir>" >&2
echo " source-host SSH target for the source Pi-hole (e.g. root@pihole)" >&2
echo " dest-dir Local directory to write config files into" >&2
exit 1
}
[[ $# -eq 2 ]] || usage
SOURCE="$1"
DEST="$2"
echo "Pulling Pi-hole config from ${SOURCE} → ${DEST}"
mkdir -p "${DEST}/dnsmasq.d"
# ── pihole.toml ────────────────────────────────────────────────────────────────
echo " pihole.toml"
ssh "${SOURCE}" "cat /etc/pihole/pihole.toml" > "${DEST}/pihole.toml"
# ── custom dnsmasq drop-ins ────────────────────────────────────────────────────
# Pi-hole manages its own generated config; we only capture user-added files.
echo " dnsmasq.d/ (custom drop-ins)"
ssh "${SOURCE}" "ls /etc/dnsmasq.d/*.conf 2>/dev/null || true" | while read -r f; do
name="$(basename "$f")"
echo " ${name}"
ssh "${SOURCE}" "cat '${f}'" > "${DEST}/dnsmasq.d/${name}"
done
# ── DHCP static leases ─────────────────────────────────────────────────────────
echo " dhcp.leases"
ssh "${SOURCE}" "cat /etc/pihole/dhcp.leases 2>/dev/null || true" > "${DEST}/dhcp.leases"
echo "Done. Config written to ${DEST}/"
View File
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.