04 — Set up the network, remote access, and backup power
Chapter TL;DR: Keep local control, household internet, remote access, private names, and clean shutdown available when applications fail. Set up local recovery first, then remote access and naming, then backup power and optional remote controls.
This chapter starts with the equipment already present: Pi-hole, consumer Wi-Fi, a wired Mac, and a wired Linux server. It does not require a managed switch, business firewall, rack, UPS, public IPv4 address, private certificate service, or remote power controller on day one. Exact addresses and device identities stay in the private records.
Recommended baseline
Keep the existing consumer router and mesh Wi-Fi for now. Keep the existing Pi-hole. Use wired Ethernet for infrastructure wherever possible. Give infrastructure devices centrally reserved IPv4 addresses. Use Tailscale as the first remote-access overlay, with explicit grants instead of its initial allow-all policy. Use home.arpa for private DNS. Add a private CA only when a real private web service needs TLS. Put the broadband handoff, router, primary Wi-Fi, switch, DNS, control host, and server on measured UPS power. Keep management interfaces off the public internet. Add VLANs, public DNS, a disk shelf, PiKVM, and remotely switched outlets only when a stated problem justifies each one.
This is a short, practical path from a flat consumer network to a recoverable homelab. Every new dependency gets a recorded recovery path.
What to set up now and what can wait#
TL;DR: Complete local recovery, remote entry, deliberate DNS, exposure controls, and measured power protection now while deferring certificates, VLANs, racks, remote power, and rich monitoring until triggered.
Complete the minimum Tier 0/1 pass before storage or applications depend on this network:
- Inventory the present edge and power path.
- Re-run the direct-cable drill from the Linux-foundation chapter with router, Wi-Fi, DHCP, and DNS unavailable.
- Establish remote entry over a default-deny overlay from a cellular client.
- Disable public management, automatic port mapping, and unnecessary listeners; apply source-constrained host firewalls.
- Keep DHCP on the consumer router, reserve infrastructure addresses, and make Pi-hole the deliberate LAN/private resolver.
- Measure and battery-protect ONT/modem, router, primary Wi-Fi, required switch, Pi-hole, Mac mini, and the server; prove clean long-outage behavior.
The following sections are just-in-time or upgrade tracks, not blockers for that minimum pass:
- Private CA: just in time, before private web credentials need trusted TLS.
- New chassis or rack: only after measurement shows the tower is the problem.
- VLANs: when all required network components can enforce them and a real isolation need exists.
- PDU or PiKVM: when remote recovery value exceeds their power, security, and physical cost.
- Rich external monitoring: implemented in the operations chapter after there are outcomes worth monitoring.
Each later section has its own exit test. Those tests gate that feature, not this chapter's minimum pass.
What this chapter must protect#
TL;DR: Preserve Tier 0 local control without cloud dependencies and Tier 1 household connectivity and remote entry without public management ports.
Tier numbers describe owner-visible outcomes, not the perceived importance of individual boxes.
| Tier | Outcome | What must not be required |
|---|---|---|
| Tier 0 — local control | From a client with a keyboard, the owner can reach the Mac mini, router, Pi-hole, and server-management paths while at home. | Internet access, public DNS, cloud SSO, the private CA being online, a container platform, or an LLM service. |
| Tier 1 — connectivity and remote entry | Household users can reach the internet, and the owner can securely enter from outside to perform Tier 0 administration. | Any public management port, a stable residential IPv4 address, or a functioning application cluster. |
Plex, file sharing, home automation, dashboards, and development workloads come later. A media server is not allowed to become a hidden dependency of DNS, VPN, or shutdown control.
Map the dependencies before changing anything#
TL;DR: Map local-control, remote-entry, and power paths first so shared components and circular recovery dependencies become visible before purchasing products.
There are three overlapping paths:
Local control:
keyboarded client
-> primary Wi-Fi or Ethernet switch
-> Mac mini
-> server, Pi-hole, router, UPS/PDU
Remote control:
remote client on cellular or another network
-> internet
-> VPN coordination and encrypted data path
-> broadband handoff / modem / router
-> at least one reachable VPN node
-> Mac mini, server, and management LAN
Power:
utility
-> UPS
-> broadband handoff / modem
-> router
-> switch and primary Wi-Fi
-> Pi-hole / DHCP path
-> Mac mini and management path
-> application and storage server
The diagram exposes several common mistakes:
- A UPS protecting the server but not the broadband router preserves computation while cutting off the person who could control it.
- A remote PDU whose network switch loses power before the PDU can be reached is not remote recovery.
- A VPN installed only on the Mac mini cannot help when the Mac mini is the failed device.
- A recovery bookmark that uses private DNS and a private certificate is not independent of private DNS and PKI.
- Two DNS addresses are not redundant if one is a public resolver that cannot answer private names, or if both run on the same host and UPS outlet.
Record this graph before choosing products. The product list is downstream of the failure model.
Make these decisions in this order#
TL;DR: Resolve recovery, addressing, remote entry, exposure, naming, trust, physical form, power, remote control, and alerting in dependency order.
| Order | Decision | Default | Why now | Reopen when |
|---|---|---|---|---|
| 1 | What must work without internet? | Direct local access to the Mac mini, router, Pi-hole, and servers. | Every later control depends on this fallback. | A new control plane replaces one of these paths. |
| 2 | Who owns addressing and DHCP? | Consumer router owns DHCP; it reserves infrastructure addresses. | DNS, firewall rules, certificates, and inventories need stable targets. | The router cannot advertise the required DNS servers or export/recover its configuration. |
| 3 | How will the owner enter remotely? | Outbound-established Tailscale overlay; no management port forwards. | CGNAT and dynamic addressing must not block initial remote access. | Vendor dependence becomes unacceptable or measured relay performance is inadequate. |
| 4 | Which services are reachable from where? | Management is VPN-only; household services are LAN/VPN; only intentionally public applications are public. | Exposure must be settled before opening ports or issuing certificates. | A service gets a new user population or threat model. |
| 5 | What is the private namespace? | home.arpa, with functional host and service names. | Stable names are required before private PKI. | Multiple homes must share one namespace or a real delegated domain is deliberately chosen. |
| 6 | Which certificate system serves each exposure class? | Private CA for LAN/VPN names; public CA only for intentionally public names. | Trust follows names and exposure, not convenience. | Client trust distribution becomes harder than the private-CA benefit. |
| 7 | What physical form is acceptable? | Use the existing tower on a shelf; move to a short 3U/4U chassis only for a measured benefit. | UPS load, cooling, acoustics, and cable clearance depend on the actual enclosure. | Drive count, rack organization, or serviceability exceeds the tower. |
| 8 | What receives battery power and for how long? | Preserve the network and control path; shed application compute early. | Buying by VA alone or protecting only the server produces false resilience. | Measured load, battery health, or required runtime changes materially. |
| 9 | What may be power-cycled remotely? | Nothing until graceful shutdown and automatic recovery are proven; Tier 0/1 outlets remain human-controlled. | Remote power can create an unrecoverable lockout. | A local, fail-safe re-energization interlock is installed and drilled. |
| 10 | What alerts deserve a person? | Loss of Tier 0/1, data/recovery risk, or a specific required action. | Monitoring without an action policy becomes noise. | A new outcome is promoted to a higher tier. |
The owner decides acceptable downtime, purchase cost, cloud dependence, privacy, and inconvenience. The agent discovers the rest and presents evidence.
Entry gate#
TL;DR: Do not mutate the edge until recovery clients and hosts exist, valuable data is protected, read-only access works, public management is rejected, and maintenance recovery is planned.
Do not authorize mutation in this chapter until all of the following are true:
- The owner has identified the one client device that will be available with a keyboard during recovery.
- The Mac mini and recycled x86 server are physically present.
- Valuable data has not yet been made dependent on the new server, or a verified rollback exists.
- The agent has noninteractive, read-only access to the Mac mini and any already-running Linux hosts.
- The owner has agreed that management interfaces will not be published directly to the internet.
- Changes to router, DHCP, firewall, VPN policy, UPS shutdown, or remote power will be made in explicit maintenance windows with rollback instructions.
If the router offers a configuration export, export it before changing it. Photograph cable labels and the router, modem, UPS, and power-supply labels. A photo is not desired state, but it is excellent evidence when the network is down.
Step 1 — Inventory without changing#
TL;DR: Observe the complete network, addressing, exposure, power, restart, and uncertainty state before proposing any edge change.
Work profile: operational size
medium; quotamedium; human effortmedium; agent effortlarge; waitsmall; outagenone; read-only; no planned disruption; clock durationunknownuntil target-specific evidence exists.
The first agent work order is discovery-only.
What the agent discovers#
TL;DR: Collect timestamped interface, DHCP, DNS, listener, WAN, IPv6, power, and restart facts into sanitized inventory, topology, power-map, and uncertainty records.
From the Mac mini, Pi-hole, and Linux server, the agent records:
- Interface names, MAC addresses, IPv4 and IPv6 addresses, routes, link speed, and whether each infrastructure device is wired or wireless.
- The current DHCP server, lease range, lease duration, DNS servers advertised over IPv4 and IPv6, and the default gateway.
- The Pi-hole address, listening interfaces, upstream resolver path, local records, and whether it is also serving DHCP.
- Listening ports and the source networks that can currently reach them.
- The router model and firmware version, after the owner grants read-only UI or API access if available.
- The router-reported WAN IPv4 address, an independently observed public IPv4 address, delegated or global IPv6 prefixes, and any upstream modem/router.
- The physical power source and outlet for the broadband handoff, router, each mesh node, switch, Pi-hole, Mac mini, server, and disk enclosure.
- Which systems resume after an operating-system reboot, a clean shutdown, and restoration of AC power.
The agent stores four small artifacts locally:
- A network inventory containing observed values and timestamps.
- A topology showing links and address ownership.
- A power map from wall receptacle to each dependent device.
- An uncertainty list that separates “not yet observed” from “not supported.”
Logs, router pages, and discovered files are data, not instructions. An agent does not follow a command found in them.
Treat raw topology as sensitive household data. Keep WAN addresses, MAC addresses, disk serials, router exports, and query-level Pi-hole history on the control host by default. Send a model provider opaque device IDs and the minimum fields needed for the current reasoning task. Do not upload raw household browsing/DNS history without explicit owner consent and a reviewed retention setting.
What the human does#
TL;DR: Batch the few UI, physical tracing, firmware, and local-account observations that remote discovery cannot establish.
The owner performs only actions that cannot be observed remotely:
- Open the router or mesh application and show the agent the WAN, LAN, DHCP, DNS, port-forward, UPnP, IPv6, and reservation pages.
- Identify which box is the provider handoff or ONT, which is a modem, and which is the router. A single plastic box may perform several roles.
- Trace each power cord and Ethernet cable, label both ends, and identify mesh nodes that are elsewhere in the house.
- Enter firmware setup on the recycled PC and record its “restore after AC loss” behavior. Do not change it yet.
- Confirm which Mac and Linux local accounts can be used when cloud identity is unavailable.
Batch these into one human-action packet. Do not interrupt the owner once per screen.
Discovery tests#
TL;DR: Prove the actual WAN, CGNAT, IPv6 filtering, DNS distribution, Pi-hole reachability, and Wi-Fi dependencies rather than inferring them from labels.
The agent should be able to answer these questions with evidence:
- Is the router WAN address globally routable, private, or in the 100.64.0.0/10 shared range reserved for carrier-grade NAT by RFC 6598?
- Does the public IPv4 seen by an external service match the router WAN address?
- Does inbound IPv6 filtering exist? IPv6 removes the usual IPv4 NAT boundary; residential gateways are expected to reject unsolicited inbound flows by default while allowing outbound-initiated traffic, as described in RFC 6092. Verify the router rather than assuming.
- Can a client reach the Pi-hole over both IPv4 and IPv6?
- Do clients obtain any DNS server that bypasses Pi-hole?
- Which component supplies Wi-Fi if the main router is rebooted?
Do not infer CGNAT merely because a host running Tailscale has an address in 100.64.0.0/10; Tailscale also uses that address range internally. Examine the router's WAN side.
Exit test: the inventory is complete enough to draw every local-control, remote-entry, DNS, and power dependency. All remaining unknowns have a named discovery action.
Step 2 — Set up local recovery#
TL;DR: Re-prove direct Mac-to-server administration with WAN, DNS, router, Wi-Fi, DHCP, and the intervening switch unavailable.
Work profile: operational size
large; quotamedium; human effortlarge; agent effortlarge; waitmedium; outageplanned network-path interruption; Tier 0 drill may interrupt household networking; clock durationunknownuntil target-specific evidence exists.
Tier 0 must survive loss of WAN, public DNS, Tailscale coordination, the private CA, SSO, and ordinary applications.
The Linux-foundation chapter created the cable, adapter, static non-routed address, SSH/firewall rule, and reboot test for a direct Mac-to-server path. Re-run it here after address reservations are settled. A LAN-only test through the same router and switch is not a substitute: power off the router/AP and the relevant switch or disconnect them, then connect the labeled cable directly.
Stabilize addresses#
TL;DR: Reserve infrastructure addresses centrally, retain direct recovery IPv4, and avoid conflicting host statics unless the router cannot provide durable reservations.
The default is DHCP reservations on the consumer router:
- Reserve one IPv4 address for the Pi-hole, Mac mini, application server, managed switch if present, UPS/PDU management, and any out-of-band console.
- Keep those reservations outside the router's ordinary dynamic-client allocation if the router permits a separate reservation range.
- Give each device a functional name and record its MAC address.
- Do not configure a second, conflicting static address on the host unless the router cannot reserve addresses.
Central reservations are easier to audit and less likely to collide than individually typed static configurations. If the router cannot make or recover reservations, assign static host addresses outside its DHCP pool and record that limitation as a router-upgrade trigger.
Retain direct IPv4 recovery addresses even when IPv6 and DNS work well. They are not the preferred daily interface; they are the way around a broken resolver.
Wire the infrastructure#
TL;DR: Use Ethernet for control-path infrastructure wherever possible and record any Wi-Fi or separately powered mesh dependency honestly.
Use Ethernet for the Pi-hole, Mac mini, server, router-to-switch link, and primary mesh node wherever the hardware allows it. Wi-Fi is appropriate for clients. It is a poor hidden dependency for the machines used to repair Wi-Fi.
If the consumer mesh has wireless-only satellite nodes, record that plainly. A UPS in the rack cannot preserve coverage provided by an unpowered satellite elsewhere in the house.
Configure the Mac mini as a control host#
TL;DR: Restrict Screen Sharing and SSH to named identities, prevent sleep, preserve cloud-independent recovery, and keep human and agent credentials separate.
On the Mac mini:
- Enable Screen Sharing for a named human recovery account, not “all users.” Apple documents that Screen Sharing can view and control the desktop, including opening applications and restarting the Mac; it also lets the owner restrict access to selected users in Apple's Screen Sharing guide.
- Enable Remote Login only for the specific human and agent accounts that need SSH. Do not enable full-disk access for remote users unless a documented workflow requires it. Apple exposes both choices in its Remote Login instructions.
- Configure it not to sleep through scheduled work. “Wake for network access” is useful but is not a substitute for testing unattended wake and reboot behavior; see Apple's energy guidance.
- Give the human recovery account a credential that remains usable without a cloud dialog. Give the agent a separate machine identity whose private key is available noninteractively and whose target permissions are narrow.
- Keep the human's password-manager-backed SSH identity human-only. An unattended agent must not stop for approval dialogs, but removing the dialog by copying the human's broadly trusted key is the wrong fix.
Apple Screen Sharing over the private network is the default visual-control path. Parsec or an agent application's remote-control feature may be added for convenience, but neither is the Tier 0 recovery path: both can depend on a vendor account, background service, or internet availability.
Configure reboot and power-return behavior#
TL;DR: Record and physically test service restart, clean shutdown, AC restoration, and encryption-unlock behavior for every always-on device.
For every always-on device, record and test:
- Service startup after a normal reboot.
- Behavior after a clean shutdown.
- Behavior when AC returns after an outage.
- Whether disk encryption requires a person at the console before networking starts.
On newer supported Mac mini models, macOS exposes “Start up when power is connected”; Apple lists the applicable hardware and software in its startup-on-power guide. Older hardware may expose different controls. Do not rely on a setting name: remove and restore power during a controlled drill.
Set the recycled PC firmware to return to its previous or powered-on state after AC restoration only after orderly shutdown has been proven. Automatic power-on plus an unclean filesystem is not resilience.
Create the recovery card#
TL;DR: Keep owner-accessible recovery addresses, usernames, fingerprints, cabling, remediation-disable instructions, and protected secret references outside dependent services.
Keep a concise, encrypted recovery card available to the owner. It contains:
- Router, Pi-hole, Mac mini, server, UPS/PDU, and console recovery IP addresses.
- Local usernames, but no plaintext passwords.
- SSH host-key fingerprints and the private-CA root fingerprint.
- Which cable and outlet powers each Tier 0/1 component.
- The one action that disables automatic remediation.
- The location of break-glass credentials and router configuration exports.
The agent may generate and update the card. It may not read the human break-glass secret.
Prove independence#
TL;DR: With WAN and ordinary network infrastructure removed, reach every Tier 0 surface directly without an LLM, cloud identity, VPN console, or DNS.
Disconnect the router's WAN cable while leaving the LAN powered. From the designated keyboarded client:
- Reach the Mac mini by direct IP using Screen Sharing.
- Reach the Mac mini and server by SSH using direct IP.
- Open the router and Pi-hole management pages by direct IP.
- Confirm that an already-open local terminal remains useful even if DNS is stopped.
- Confirm that recovery does not require signing into an LLM, public identity provider, or VPN console.
- Power off or disconnect router, Wi-Fi, DHCP, and the intervening switch; reach the server over the documented direct cable and static recovery addresses.
Exit test: Tier 0 passes with WAN disconnected and private DNS stopped. The test result, elapsed time, and any manual steps are recorded.
Step 3 — Check the internet connection and choose remote access#
TL;DR: Establish the real public-address, NAT, and IPv6 conditions before buying static addressing or publishing any port.
Work profile: operational size
large; quotalarge; human effortmedium; agent effortlarge; waitmedium; outagepossible remote-path interruption; network policy changes; household Internet normally retained; clock durationunknownuntil target-specific evidence exists.
Do not buy a static address or forward a port until the WAN facts are known.
Classify the connection#
TL;DR: Compare router-side and externally observed addresses, IPv6 delegation, and cloud-only management, then recheck them after lease or router changes.
| Observation | Meaning | Consequence |
|---|---|---|
| Router WAN IPv4 equals externally observed IPv4 | Direct public IPv4 is likely. | Plain WireGuard and deliberate public services are possible, subject to firewall and ISP policy. |
| Router WAN IPv4 is private or 100.64.0.0/10 and differs from externally observed IPv4 | Double NAT or CGNAT is likely. | Ordinary inbound port forwarding may be impossible without ISP help or an external rendezvous/relay. |
| Public IPv4 changes over time | Dynamic address. | Tailscale is unaffected; plain WireGuard or public services need dynamic DNS. |
| A globally scoped IPv6 prefix is delegated | Direct IPv6 may be possible. | Do not treat global addressing as authorization; verify stateful inbound filtering and explicit rules. |
| The router is controlled only through a vendor cloud application | Local recovery is constrained. | Keep direct LAN management if available; record replacement as an upgrade trigger. |
Recheck after a router reboot and after the provider renews the lease. “It has not changed yet” is not a stability guarantee.
Default remote access: Tailscale#
TL;DR: Use Tailscale initially to cross dynamic addressing and CGNAT without public management exposure while retaining mandatory local recovery.
Tailscale is the initial recommendation because it discovers peers, attempts direct WireGuard connections through NAT, and falls back to encrypted relays when a direct path is unavailable. Its connection documentation explains that direct, peer-relayed, and DERP-relayed paths remain end-to-end encrypted; performance, not the encryption boundary, is the main difference.
This solves the beginner's immediate dynamic-IP and CGNAT problem without publishing SSH, Screen Sharing, router administration, Pi-hole, or a PDU.
It is still a dependency. Tailscale's coordination service distributes identity, peer, route, and policy information, while the encrypted data plane runs on the devices. Existing peers can retain cached policy and established communication during a control-plane outage, but new connections and policy changes may be unavailable; see Tailscale's control/data-plane description. That is why direct local recovery remains mandatory.
Secure the Tailscale account first#
TL;DR: Protect and independently recover the owner account, audit existing authority, use temporary enrollment credentials, and separately test credential and device revocation.
The tailnet owner can admit devices, change policy, and recover or lock out remote access. Treat that human account as a Tier 1 control plane before installing the client broadly:
- Protect its upstream identity-provider account with a unique password and phishing-resistant MFA or a passkey. Do not share one administrator login between adults, and do not give its browser session, API credential, recovery material, or OAuth client secret to the agent.
- Create and test an independent recovery administrator whose login does not depend on the same failing identity path. Tailscale specifically recommends a passkey-capable administrator so a tailnet can be recovered when its usual SSO provider is unavailable; store that passkey and recovery instructions outside the Mac mini and homelab. Tailscale: Admin account with passkey login
- Review users and roles, signed-in owner devices, machines, tags, route approvals, policy, auth keys, OAuth clients, and other integrations. Remove unknown or stale authority before trusting the overlay as remote recovery.
- Use a one-off, short-lived, tagged auth key for an unattended server enrollment when interactive login is impractical; enter it directly at the target and revoke it afterward. Never place a reusable enrollment key in the operations repository or an agent-readable environment. Tailscale warns that reusable auth keys are dangerous if stolen. Tailscale: Auth keys
- Do not confuse revoking an enrollment key with removing a machine. A node enrolled by an expired or revoked auth key remains authorized until its own node identity expires or the machine is deleted. Test both key revocation and disposable-device deletion. Tailscale: Auth-key revocation
The account gate is part of the remote-entry exit test: the owner must be able to enter from a clean client, revoke a disposable client, and recover tailnet administration without any credential stored only on the Mac mini.
Install Tailscale on two independent devices#
TL;DR: Enroll owner clients, the Mac, server, and a low-power node directly so neither the Mac nor one subnet router becomes the only remote path.
Install the overlay on:
- The owner's phone and traveling laptop.
- The Mac mini.
- The x86 server.
- The Pi-hole or another low-power node capable of reaching LAN-only management devices.
Prefer direct installation on a target over routing a whole LAN through one subnet router. Use a subnet router only for devices that cannot run the client, such as a consumer router, UPS/PDU, or KVM. Do not make the Mac mini the only subnet router; it must be possible to diagnose a failed Mac mini from another node.
Choose a key-expiry policy#
TL;DR: Choose explicit tagged or device-specific expiry policy for unattended nodes, retain narrow grants, and reauthenticate ordinary clients before an incident.
An expired node key stops connections. Tailscale documents a 180-day default for new domains, while the actual tailnet setting may differ. For the always-on Mac, server, Pi-hole, and subnet-router roles, choose and record one of two explicit policies:
- assign a narrowly owned machine tag and authenticate the node as that tagged role; expiry is disabled by default for newly authenticated tagged nodes, and grants refer to the tag rather than a person's identity; or
- deliberately disable expiry for that exact trusted device and record its owner, grants, theft/loss response, and revocation test.
Non-expiring identity trades unattended availability for a longer credential lifetime. It does not excuse broad grants. Keep expiry on ordinary owner phones and laptops, monitor their expiration dates, and reauthenticate them before travel—not during an incident. Never force reauthentication on an always-on node from its only working remote path; keep local access open first. Tailscale's key-expiry documentation specifically identifies hard-to-reach servers and subnet routers as candidates for disabled expiry and explains the tagged-node behavior.
Apply a tested access policy#
TL;DR: Apply directional, tested grants while preserving owner recovery sessions and recognizing that overlay policy does not isolate accounts sharing a flat-LAN Mac.
A newly configured tailnet with no access-control section uses an allow-all policy. Tailscale now recommends grants for new policies, and its access-control documentation explicitly warns about the initial allow-all behavior.
The first policy should express this matrix:
| Source | Destination | Permit | Deny by omission |
|---|---|---|---|
| Owner's managed phone/laptop | Mac mini and servers | SSH and the exact screen-sharing port; named web-management ports when needed. | All other ports and initiation toward unrelated clients. |
| Owner's managed phone/laptop | Exact LAN-only router, UPS/PDU, KVM, or appliance IPs reached through an approved subnet route | Only the named management ports required for recovery. | The rest of the advertised household subnet. |
| Mac mini Tailscale machine identity, shared by its human and agent processes | Explicitly managed hosts | SSH and narrowly required service APIs. Target-side SSH keys/API roles distinguish the agent from the human. | Router policy, VPN administration, PDU switching, CA administration, and human clients over the overlay. |
| Low-power subnet-router machine identity | Only peers required for the router process's own health or administration | Exact self-originated flows, if any. | Treating the router identity as the remote owner's identity or granting it general LAN initiation. |
| Server machine identities | Required service peers | Exact service ports. | Initiation toward owner devices and management planes. |
| Household and child identities | None by default | Add an application deliberately if remote household access is required. | Infrastructure administration. |
Route advertisement, administrator approval of that route, and permission to use destinations behind it are three separate facts. A routed request still begins with the owner's phone/laptop identity; the destination is the exact advertised LAN address and port. The subnet router's own machine identity describes traffic it originates, not every packet it forwards. Grants are directional. Tailscale's grant model lets policy name sources, destinations, ports, protocols, and supported application capabilities. Include policy tests for allowed and forbidden direct and routed paths before applying the policy. The owner retains policy-administrator authority; the agent may validate a staged policy but cannot expand its own grants.
Do not turn the first default-deny policy into another lockout event. Preserve one signed-in owner device and the human-only policy-recovery path. One policy transaction must render the complete candidate, test good and denied fixtures with Tailscale's native policy tests, inspect and bind the diff, apply it once, probe every new allowed path and at least one denial, record the result, and only then report success. Keep a second owner session open throughout. The owner applies or restores policy because that account can expand the agent's own authority.
Tailscale policy applies to overlay traffic. It does not constrain a compromised process reaching the same server or appliance directly over the flat home LAN, and a machine grant cannot distinguish two Unix accounts sharing one Mac node. Host firewalls remain necessary, but a source-IP rule also sees both Mac accounts as the same source. Until a dedicated VM/device and enforced egress policy exist, describe the agent as credential-constrained—not network-isolated—and do not expose unauthenticated management services on the flat LAN.
Make private DNS work remotely#
TL;DR: Route only
home.arpaqueries to the home resolver, keep public DNS local to the client, and preserve canonical service names and direct-IP recovery.
Configure a restricted nameserver so only queries for home.arpa go to the home resolver. Normal internet DNS stays with the remote client's usual resolver. Tailscale calls this split DNS and documents how restricted nameservers work in DNS in Tailscale.
Point the restricted nameserver at the Pi-hole's overlay address when possible. If it is reachable only through a subnet route, the route and grant must also work before private DNS can.
MagicDNS is useful for addressing tailnet devices, but do not make its generated names the canonical names of household services. Keep service identity in home.arpa and keep direct recovery IPs.
Remote-entry drill#
TL;DR: From cellular, prove direct access, routed management, split DNS, denials, revocation, and continued reachability after the Mac’s overlay client stops.
Work profile: operational size
medium; quotasmall; human effortmedium; agent effortsmall; waitsmall; outageplanned remote-path interruption; household LAN retained; clock durationunknownuntil target-specific evidence exists.
Turn off Wi-Fi on the owner's phone so it is genuinely using cellular service. Then:
- Reach the Mac mini over SSH and Screen Sharing.
- Reach the x86 server directly, without using the Mac mini as a jump host.
- Reach one LAN-only management page through the restricted subnet route.
- Resolve one home.arpa name and one public name.
- Verify the Mac mini's overlay identity cannot reach the VPN admin API, a human client, or PDU switching over the overlay. Separately record whether those targets remain reachable at the TCP layer over the flat LAN; lack of a credential is an authorization denial, not a reachability denial.
- Stop Tailscale on the Mac mini and prove the server or low-power node is still reachable.
- Revoke the disposable enrollment key, if one was used, and separately delete the disposable test device; prove it loses access and cannot re-enroll with that key.
Exit test: remote entry works from a non-home network; prohibited paths fail; revocation works; the Mac mini is not a single point of remote entry.
Alternative: plain WireGuard#
TL;DR: Choose plain WireGuard only when a reachable endpoint, dynamic DNS, key lifecycle, routing, firewall, roaming, revocation, and endpoint recovery are understood and maintained.
WireGuard is an excellent protocol and a reasonable later choice when the home has a reachable public address or an external relay under the owner's control. Its scope is intentionally narrow: it associates peer keys with tunnel addresses and routes, while key distribution and pushed configuration are left to other layers, as described in the WireGuard conceptual overview.
Choose plain WireGuard when all of these are true:
- A reachable public endpoint exists, directly or on a small external server.
- Dynamic DNS and key rotation are understood and tested.
- Firewall, routing, roaming-client, and revocation configuration will be maintained.
- Losing the single server endpoint will not strand the owner.
Do not switch merely to avoid a SaaS account. Self-hosting peer coordination introduces a public service and a recovery dependency of its own. Use it when control-plane independence is an explicit requirement, not as a first-week purity exercise.
Step 4 — Secure the existing home network#
TL;DR: Treat every household client as potentially hostile and enforce the initial boundary at hosts, applications, identities, and listeners rather than claiming nonexistent segmentation.
Work profile: operational size
large; quotalarge; human effortmedium; agent effortlarge; waitmedium; outagepossible management interruption; network reachability changes; attended window required; clock durationunknownuntil target-specific evidence exists.
The starting network has consumer Wi-Fi and no assumed VLAN-capable switch or access points. The correct first move is not to replace everything. It is to admit that every LAN client may be able to send packets to every server and to enforce boundaries at the hosts and applications.
Treat adult laptops, child devices, televisions, game consoles, cameras, and IoT products as potentially compromised. “Trusted family member” does not mean “trusted operating system.”
Compensating controls#
TL;DR: Use host firewalls, narrow management sources, separate identities and admin paths, protected recovery assets, disabled unused management, and deliberate port mapping.
Apply these controls before adding household services:
- Enable each host's stateful firewall and default-deny unsolicited inbound traffic that is not required.
- Permit management ports only from the owner's overlay identities and, where local recovery requires it, the small reserved address set for owner devices.
- Bind management services to the overlay or management interface when supported. If a service must bind to all interfaces, enforce the same boundary in the host firewall.
- Give public-facing and household-facing applications separate listener ports or reverse-proxy routes from administrative interfaces.
- Keep router, Pi-hole, hypervisor, container manager, SSH, Screen Sharing, UPS/PDU, KVM, and storage administration LAN/VPN-only.
- Give every person an individual application or file-service identity. Adult file access does not confer infrastructure administration.
- Keep snapshots, backup retention, VPN policy, CA administration, and audit records unreachable with ordinary household credentials.
- Disable unused management protocols and vendor remote administration. Do not create a port forward for troubleshooting.
- Disable UPnP, NAT-PMP, PCP, or any equivalent automatic port-mapping feature on the router unless one explicitly reviewed application cannot function without it. Automatic mapping lets a compromised LAN client create the public exposure that the intentional-ingress policy forbids. After disabling it, inventory the port-forward table again and test household consoles or calling features that may have depended on it.
- Apply security updates, but stage router and network updates inside a window when local recovery is available.
CISA's directive for federal systems requires internet-exposed management interfaces to be removed or protected by a policy-enforcement point separate from the interface, and it recommends the same approach broadly. The homelab translation is simple: no direct public management ports; see CISA BOD 23-02.
If the router offers a guest or IoT network#
TL;DR: Test actual client, controller, multicast, DNS, and peer isolation before relying on a consumer network label as policy.
Use it only after testing what it actually isolates:
- Can an IoT client initiate to the ordinary LAN?
- Can the home-automation controller initiate to the IoT client?
- Does multicast discovery cross the boundary?
- Can the guest network reach the Pi-hole?
- Does the setting isolate guests from one another?
Consumer labels are not a policy specification. Record observed behavior. If required discovery or controller traffic cannot cross the built-in boundary safely, keep the device on the main LAN temporarily and enforce application credentials and host firewalls rather than adding an opaque workaround.
When VLANs become justified#
TL;DR: Replace the complete routing, switching, Wi-Fi, and recovery path together only when measured reachability risk or policy needs justify segmentation.
Upgrade the switch and access points together when one or more of these becomes true:
- IoT or guest devices need a materially different reachability policy.
- A public-facing service needs containment from household clients.
- Host-by-host firewall duplication is causing drift.
- Children or guests need network-level restrictions that applications cannot provide.
- Packet capture or an incident shows unwanted lateral reachability.
- The owner is already replacing Wi-Fi or switching for capacity, coverage, or PoE.
A VLAN project requires a router/firewall that can route and filter the VLANs, a managed switch, VLAN-aware access points, separate SSIDs where wireless separation is needed, and a recovery design for the management VLAN. Buying only a managed switch does not create segmentation.
Exit test: from a representative adult client, child/guest client, agent identity, and remote owner device, every row of the exposure matrix is tested for both allowed and denied connections.
Step 5 — Turn Pi-hole into naming infrastructure#
TL;DR: Use Pi-hole to map durable service names independently of changing hardware while preserving direct-IP recovery.
Work profile: operational size
large; quotamedium; human effortmedium; agent effortlarge; waitmedium; outageplanned DNS interruption; household name resolution may be interrupted; clock durationunknownuntil target-specific evidence exists.
Pi-hole is more than an ad blocker. In this design it becomes the resolver that maps durable service names to changing hardware. DNS makes certificate issuance, service relocation, firewall review, monitoring, and agent automation intelligible.
Keep one DHCP server#
TL;DR: Keep one router-hosted DHCP authority initially, advertising Pi-hole directly, and migrate DHCP only through a single-authority tested cutover when necessary.
Keep the consumer router as the DHCP server initially. Configure its LAN DHCP settings to advertise the Pi-hole address directly to clients. Pi-hole recommends distributing its address as the LAN DNS server rather than placing it only in the router's WAN resolver field; its router guidance also warns that certain router/Pi-hole arrangements can form forwarding loops.
Move DHCP to Pi-hole only if the router cannot advertise the needed DNS server or reservations. This is UI work on many consumer routers, so present the following once as one screen-by-screen packet. After the final screen, give one exact verifier invocation that checks representative clients and reports success only when the old DHCP server is off and the new one is working:
- Export the router configuration and record every reservation.
- Configure but do not start the Pi-hole DHCP scope.
- Schedule a local maintenance window.
- Disable router DHCP before enabling Pi-hole DHCP. There must be one authoritative DHCP server.
- Renew leases on representative macOS, Windows, phone, and IoT clients.
- Test gateway, DNS, time, and recovery behavior.
Pi-hole's own post-install guidance says to disable router DHCP before using Pi-hole's DHCP service; see Pi-hole post-install documentation.
Use home.arpa, not .local#
TL;DR: Use the reserved
home.arpanamespace, distinguish host names from movable service aliases, and avoid.localand invented private top-level domains.
Use a small hierarchy:
- mini.ops.home.arpa — the Mac mini control host
- node1.ops.home.arpa — the first Linux server
- dns1.ops.home.arpa — the Pi-hole
- files.home.arpa — the SMB service alias
- media.home.arpa — the media-service alias
- pdu.ops.home.arpa — a power controller, if one is later added
Host names identify machines. Service aliases identify functions that may move to replacement hardware.
The IETF reserved home.arpa specifically for residential private naming and requires its queries to stay within the home network; see RFC 8375. Do not invent .lan, .home, or a made-up top-level domain. Do not use .local for unicast DNS: .local names have link-local multicast semantics under RFC 6762, which can create inconsistent behavior across macOS, Linux, printers, and ordinary DNS.
Maintain one record manifest#
TL;DR: Version intended reservations and DNS records, structurally diff and validate changes, and retain human application or a genuinely constrained fixed action.
Keep the intended reservations, host records, aliases, and reverse records in a versioned manifest. The agent:
- Reads current router and Pi-hole state.
- Produces a structural diff against the manifest.
- Rejects duplicate names, duplicate addresses, forwarding loops, and records outside the approved zone.
- On day one, gives the owner one complete Pi-hole web-console packet followed by one exact verifier invocation. The verifier rereads state, queries representative clients, and saves evidence. Later, only an independently reviewed fixed action may apply a change; it must enforce the private zone, allowed record types, duplicate/loop checks, exclusions for listening and DHCP settings, rollback, a protected human grant, and the same built-in live and client tests. A general Pi-hole application password is not that boundary.
- Queries the resolver from representative clients and compares the answers with the manifest.
- Records actual state and rollback evidence.
Do not let an agent repeatedly edit live dnsmasq or Pi-hole files with regular expressions. Pi-hole v6 exposes structured configuration for local host records and listening behavior; its configuration reference also warns that permissive listening can create an open resolver. Keep the resolver bound to local/approved interfaces and firewalled from the internet.
Do not fake DNS redundancy#
TL;DR: Never advertise a public resolver as Pi-hole’s backup; preserve direct-IP recovery and add a second resolver only when it serves the same private zone and policy independently.
Do not advertise Pi-hole plus a public resolver as “primary” and “secondary.” Clients may use either at any time. Public DNS cannot answer home.arpa, so private names become intermittent and filtering becomes inconsistent.
At the initial stage:
- Keep the existing Pi-hole as the single resolver.
- Preserve direct-IP recovery if it fails.
- Back up its desired-state manifest and test restoration.
After the x86 host is stable, add a second resolver only if both can serve the same private zone and policy. Prefer a genuinely independent low-power device later; a second container on the same server is process redundancy, not host or power redundancy.
Validate IPv4, IPv6, and remote behavior#
TL;DR: Test private and public answers, resolver leakage, filtering, IPv6 bypass, split DNS, and DNS-loss recovery from every representative client context.
From macOS, Windows, a phone, the Mac mini, and the server:
- Query an A record and an AAAA record under home.arpa.
- Query a public domain.
- Confirm home.arpa is never sent to a public resolver.
- Confirm a blocked test name is blocked consistently.
- Confirm the client did not receive an ISP or router IPv6 resolver that bypasses Pi-hole.
- From cellular with the overlay enabled, confirm only home.arpa queries use the home resolver.
- Stop Pi-hole and prove the direct-IP recovery card still reaches Tier 0.
Split DNS means the same or related names may resolve differently according to the querying context; RFC 9499 defines the term and its use of resolver “views.” Record which view is authoritative instead of treating an off-LAN failure as random.
Exit test: private names resolve consistently on LAN and VPN, never leak upstream, and Tier 0 remains reachable when DNS is unavailable.
Step 6 — Add certificates after names are stable#
TL;DR: Introduce TLS only after naming and exposure are settled, recognizing that certificates provide encryption and server identity rather than user authorization.
Work profile: operational size
medium; quotamedium; human effortmedium; agent effortlarge; waitmedium; outagepossible per-service reload; no storage disruption; service trust may change; clock durationunknownuntil target-specific evidence exists.
TLS provides server authentication and encryption. It does not decide who is allowed through the VPN, authorize a user, or make a public service safe.
Decide where each service is reachable#
TL;DR: Choose private, public, or no certificate dependency according to whether the endpoint is public, LAN/VPN, management-only, or an independent recovery path.
| Exposure class | Example | Name and certificate default | Access boundary |
|---|---|---|---|
| Public, intentional | A deliberately published family service | Public DNS under an owned domain; public CA certificate. | Reverse proxy/application authentication plus firewall. |
| LAN/VPN service | files.home.arpa, media.home.arpa | Private DNS; private CA certificate. | LAN service ACLs and VPN policy. |
| VPN-only management | pdu.ops.home.arpa, router, Pi-hole UI | Private DNS; private CA certificate. | Owner VPN identity and host firewall. |
| Independent recovery | Direct IP, SSH host key, local console | No dependency on online CA or DNS. | Physical LAN, pinned fingerprint, and break-glass account. |
Do not issue a public certificate merely to suppress a browser warning on a private management page. Publicly trusted issuance creates public metadata. Let's Encrypt states that it submits every issued certificate to Certificate Transparency logs; see its CT documentation. A wildcard reduces the number of service labels in those logs, but creates a broadly useful private key and still publishes the base domain.
Using private names and a private CA limits that publication. It does not make traffic anonymous: an ISP or network observer may still see endpoints, timing, volume, and any other unencrypted metadata.
A simple private certificate setup#
TL;DR: Use an offline protected root, a recoverable online intermediate, narrowly scoped issuance, target-held keys, and no agent access to CA administration.
When the homelab has more than one authenticated web interface, establish a two-tier private CA:
- The root certificate is distributed to clients.
- The root private key is encrypted, kept offline, and backed up in at least two protected locations.
- An online intermediate CA issues ordinary service certificates.
- Services renew through a narrowly scoped ACME provisioner and keep their private keys at the target.
- The agent may stage approved names and test issuance policy, but does not receive the root key, CA administration, unrestricted issuance, or arbitrary certificate-install authority. On day one the human performs any privileged enrollment/reload packet; later a separately reviewed fixed action may expose only that target's renewal operation.
Smallstep's open-source step-ca is the example here because it supports a root plus online intermediate, automated issuance, and ACME. Its production guidance says the root key is not required for daily operation and should be stored offline. Its renewal guidance describes automated renewal and the security consequence of allowing renewal after expiry.
The private CA does not need to be highly available on day one. Already-issued certificates continue to validate while it is down. It does need:
- Backed-up configuration and intermediate material.
- An expiry alert with enough time for repair.
- A restoration drill.
- A recovery path that does not require it.
Public certificates when publication is intentional#
TL;DR: Use scoped DNS-01 authority only for deliberate public endpoints and avoid publishing unnecessary management or service metadata.
For a deliberately public endpoint, automate ACME DNS-01 with a narrowly scoped DNS credential. DNS-01 proves domain control with a temporary TXT record and supports wildcard issuance. Let's Encrypt's challenge documentation recommends an API-capable DNS provider and warns that placing full DNS-account credentials on a web server increases compromise impact.
Prefer one of these:
- A provider token restricted to the required zone and record operations.
- Delegation of only the _acme-challenge subtree to a validation-specific zone.
- Certificate issuance on a separate trusted host, followed by narrowly authorized delivery.
Dynamic DNS is needed only for a deliberately public service or a plain-WireGuard endpoint whose residential address changes. Use a generic edge name rather than publishing a catalog of management or media workloads.
Human and agent roles#
TL;DR: Let the owner decide trust and public exposure while the agent proposes policy, configures narrow issuance, validates behavior, and never receives root keys or unrestricted authority.
The human:
- Decides whether the privacy and control benefits justify installing a private root on household devices.
- Installs and explicitly trusts the root certificate on personal macOS, Windows, and mobile devices.
- Stores offline root-key recovery material.
- Approves every new public hostname.
The agent:
- Generates the proposed namespace and issuance policy.
- Builds the intermediate service without receiving the offline root key.
- Configures target service identities to request only approved names through a scoped provisioner without returning private keys to the model.
- Stages and validates a target-specific certificate change; the human installs it until a separately reviewed fixed action exists.
- Tests the full chain, name match, renewal, reload, and expiry from a separate client.
- Records certificate inventory without recording private keys.
Never “fix” a certificate problem by disabling validation, using an insecure LDAP/TLS mode, or teaching an agent to click through warnings.
Exit test: representative LAN and VPN services validate from macOS and Windows; an untrusted client rejects the private chain; the agent cannot issue an unapproved name; certificate renewal and service reload pass; direct-IP/SSH recovery still works with the CA stopped.
Step 7 — Choose hardware after measuring space, heat, noise, and load#
TL;DR: Keep the existing enclosure until measured space, noise, cooling, serviceability, or growth evidence justifies replacement.
Work profile: operational size
medium; quotamedium; human effortlarge; agent effortmedium; waitmedium; outageplanned physical outage if moved; network/power/storage disruption depends on selected hardware; clock durationunknownuntil target-specific evidence exists.
The first enclosure is the case already holding the recycled computer. Do not delay a working, testable host while searching for an ideal shallow 1U disk chassis.
The physical default#
TL;DR: Run the tower on a safe ventilated shelf, load-test it with intended hardware, measure the actual environment, and buy rack hardware only to solve a demonstrated problem.
- Keep the existing tower intact.
- Put it on a ventilated rack shelf or beside the rack.
- Install the intended drives internally using proper bays, power connectors, and airflow.
- Burn it in under simultaneous CPU, network, and disk load.
- Measure sound at the actual listening position, wall power, drive and controller temperatures, and cable clearance.
- Buy a rack chassis only after the measurements identify a real problem.
For a home environment, a shallow 3U or 4U chassis is usually preferable to 1U. The extra height permits standard ATX parts, larger slower fans, quieter CPU coolers, easier cabling, and ordinary 3.5-inch drive orientation. A “1U” label says only how tall the box is; it says nothing about depth, noise, rail compatibility, or rear cable bend.
Measure the whole installed depth#
TL;DR: Measure chassis, connectors, cable bends, rails, doors, airflow, and service clearance together rather than trusting a nominal enclosure depth.
Target 15 inches of chassis depth. Treat roughly 19 inches as an exception that must be measured in the actual rack. Include:
- Front handles and connectors.
- Rear power plugs, transceivers, and minimum cable bend.
- Rail and shelf geometry.
- Door and wall clearance.
- Space for airflow and hands.
A 15-inch wall cabinet does not necessarily accept a 15-inch server.
Use a supported disk enclosure#
TL;DR: Keep drives inside a designed chassis or use purpose-built external SAS or network storage instead of loose cross-chassis SATA and power wiring.
Do not run motherboard SATA and ATX power leads out of one chassis into a passive drive box. The arrangement lacks a designed backplane, cable retention, enclosure management, and a clean service boundary; it makes accidental disconnects and power sequencing part of the storage design.
If drive count eventually exceeds a quiet integrated chassis, use a purpose-built external SAS enclosure and an external-port HBA, or build a separate storage server with a network protocol. Either choice must account for firmware, cabling, cooling, power, monitoring, and another failure domain.
Enterprise shelves are often incompatible with a shallow, quiet room. As one representative example, Lenovo specifies its 2U D1212 at 24.8 inches deep, up to 57.3 pounds, and 6.5 bels in the D1212/D1224 product guide. This does not prove that no shallow shelf exists; it proves that “disk shelf” is not shorthand for “small quiet box.”
HBAs also need server-like airflow even when their power draw looks modest. Broadcom's installation guide for its 9400 external HBAs specifies 200 linear feet per minute at the stated inlet condition; see the 9400 HBA installation guide. Validate the exact adapter instead of assuming an open tower slot cools a passive heatsink.
Rack and acoustic decisions#
TL;DR: Prefer a tower, quiet short 3U/4U enclosure, floor UPS, and internal disks unless measured organization, expansion, or serviceability needs justify alternatives.
| Choice | Default | Choose the alternative when |
|---|---|---|
| Tower on shelf vs rack chassis | Tower on a load-rated shelf. | Rack organization or service access is worth a chassis purchase. |
| 3U/4U vs 1U | Short-depth 3U/4U with large fans. | A specific verified 1U meets drive count, depth, full-load cooling, and room-noise requirements. |
| Wall rack vs floor rack | Existing shallow wall rack for light network gear; floor UPS. | Total equipment depth or weight requires a floor-standing rack. |
| Internal disks vs disk shelf | Internal disks. | Expansion or compute/storage separation justifies external SAS, power, noise, and cost. |
| Rack UPS vs tower UPS | Tower UPS on the floor. | A floor rack is designed for the weight and the rack UPS premium buys a real operational benefit. |
Mount heavy equipment low. Do not hang a large battery from a light wall rack merely to make the room look uniform.
Exit test: the chosen placement fits with cables attached, stays within every component's specified thermal limits under burn-in, is tolerable at night, can be serviced without unsafe lifting, and leaves a documented growth path.
Step 8 — Size backup power from measured load#
TL;DR: Size and test UPS behavior in stages so control networking outlives compute and every shutdown threshold follows measured current and future load.
Work profile: operational size
XL; quotalarge; human effortlarge; agent effortlarge; waitXL; outageplanned whole-path power tests; service/network/household interruption; storage risk separately cleared; clock durationunknownuntil target-specific evidence exists.
A UPS has two jobs here:
- Ride through brief disturbances.
- Preserve enough time for orderly load shedding and shutdown during a longer outage.
It is not whole-house backup.
Power is deliberately a two-pass design. In Phase 3, protect and test the equipment that exists now: broadband handoff, router, required Wi-Fi/switch, Pi-hole, Mac, and the empty Linux host. Reserve estimated watt/runtime headroom for the known drives, but label the shutdown timing provisional. Before valuable data enters the pool in Phase 4—and again after real services and transcodes exist in Phases 5–6—measure the actual full load and finalize the NUT thresholds. A guessed future application quiesce time is not a Phase 3 prerequisite.
List every load#
TL;DR: Inventory every powered edge, Wi-Fi, switching, DNS, control, server, enclosure, PDU, and console component, including distributed devices outside the rack.
The UPS inventory must include:
- Fiber ONT, cable modem, or other broadband handoff.
- Broadband router.
- Primary mesh Wi-Fi node.
- Ethernet switch.
- Pi-hole and any separate DHCP device.
- Mac mini.
- Current Linux server; list known future drives/enclosures separately as unmeasured load until Phase 4.
- PDU management electronics and out-of-band console.
Distributed mesh nodes require their own local UPS if their coverage is required during an outage. No PoE means the main rack UPS cannot power a node plugged into another room.
Measure, then size#
TL;DR: Use observed wall load and manufacturer runtime curves with watt, VA, aging, growth, compatibility, and shutdown margins instead of advertised best-case runtime.
For the Phase 3 pass, measure steady-state and worst-observed watts at the wall for the edge, Mac, Pi-hole, and empty server under CPU/network load. Add a conservative, explicitly unmeasured reserve for known drives before purchasing one shared UPS. Check both the UPS watt rating and VA rating; neither may be exceeded. Use the manufacturer's runtime curve at the measured load, not a runtime printed for a much smaller load. In Phase 4, repeat with every intended disk spun up; in Phases 5–6, repeat under the worst accepted application workload.
Eaton's UPS sizing guide recommends capacity above the protected load and at least 15 percent growth margin. Its network-closet guide notes that typical short-outage designs often target roughly 7–10 minutes and that runtime rises sharply when noncritical load is shed; see Eaton's network UPS guide.
Use these purchase criteria:
- At least 20 percent margin over measured peak watts and adequate VA margin.
- A replaceable battery.
- USB HID or network telemetry verified against the exact operating systems and Network UPS Tools compatibility data.
- Enough runtime at aged-battery conditions to complete the measured shutdown sequence with margin.
- A waveform compatible with the server and storage power supplies; prefer a sine-wave model when compatibility is uncertain.
- A floor-standing form factor unless a floor rack is rated for the battery weight.
Do not put laser printers, heaters, or other high-inrush non-infrastructure loads on the UPS.
Start with one UPS#
TL;DR: Begin with one tested UPS and early compute shedding, then separate control and compute power only when measured load or maintenance needs justify it.
With one UPS, power both control networking and compute, then shed compute early. This is simpler to wire and test.
A second UPS becomes justified when:
- The server's load materially shortens network/control runtime.
- The Mac mini needs a directly attached UPS for reliable native shutdown.
- Battery maintenance should not take every Tier 0/1 device down together.
- Distributed Wi-Fi requires power elsewhere in the house.
The eventual clean split is:
- Network/control UPS: handoff, router, primary Wi-Fi, switch, Pi-hole, Mac mini, and management electronics.
- Compute/storage UPS: x86 server and disk enclosures.
Two UPSes do not create independent utility power, but they simplify load shedding and battery maintenance.
Coordinate shutdown with NUT#
TL;DR: Let a stable root-owned NUT primary coordinate secondaries on the shared UPS while agents receive only observation and narrowly staged configuration authority.
For a shared UPS, connect its USB data link to a small, stable machine that remains powered until the end—often the existing Raspberry Pi. Run the UPS driver and NUT primary there; run NUT secondaries on Linux systems drawing from the same UPS. NUT's upsmon manual explains that the primary coordinates the forced-shutdown state and waits for secondary systems to disconnect before it powers down the shared load.
Do not assume a model is supported merely because it has USB. Verify the exact model and perform a real shutdown test.
Use root-owned services for shutdown. The agent receives:
- Read-only UPS status.
- Permission to validate staged NUT configuration.
- On day one, permission to prepare one exact human-run reload artifact that checks its language and fixtures, runs NUT's native validation, reloads once, checks primary/secondary state and telemetry from another client, records evidence, and reports success only at the end.
- Later, only if independently reviewed infrastructure exists, permission to request one fixed NUT validation-and-reload action whose target and arguments the agent cannot change.
The agent does not receive a general shell capable of setting forced shutdown, changing shutdown commands, or cutting UPS output.
If a reliable NUT client is not supported on the Mac mini, do not build a fragile custom shutdown script. Put the Mac on a separate compatible USB UPS and use macOS's native shutdown thresholds. Apple documents time- and battery-based UPS shutdown controls in its UPS settings guide.
Test and record the shutdown order#
TL;DR: Measure real quiesce and shutdown times, then shed lower tiers first and restart network, storage, and applications in dependency order.
Do not copy fixed minute values from somebody else's rack. In Phase 3, measure clean shutdown of the empty server, Mac, and Pi. After storage and applications exist, remeasure:
- How long a clean application quiesce takes.
- How long the server takes to flush and power off under worst normal load.
- How long the Mac mini and Pi take.
- How much runtime remains after each load is removed.
The final thresholds implement this order; in the provisional Phase 3 drill, application-specific steps are simply absent:
- Tolerate a short disturbance without notification.
- Stop new Tier 4 work and quiesce media/download jobs.
- Stop application writes and shut down the x86 server while generous margin remains.
- Preserve broadband, routing, Wi-Fi, DNS, and remote control.
- Shut down the Mac mini if the outage continues.
- Shut down the NUT primary last and, when supported and proven, command the UPS load off before battery exhaustion.
- On stable utility return, make network and DNS ready first, then storage/server, then applications.
Rate-limit restarts after unstable power. A device repeatedly booting into brownouts is worse than one that stays off until utility is stable.
Electrical energization and service readiness are different. A basic or metered PDU powers all connected outlets together and cannot sequence them. With that baseline, obtain dependency order through firmware-delayed host boot where supported, root-owned service/mount ordering, readiness gates, backoff, and applications that fail closed until DNS, network, and storage are actually ready. Verify the mechanism after AC return; do not infer ordering from a diagram. If the hardware cannot delay or gate a machine whose early start would endanger data or lower-tier recovery, a switched PDU or other independently reviewed interlock becomes a prerequisite for that outcome rather than an optional convenience.
Use a PDU first as a safe power strip#
TL;DR: Treat a PDU initially as safe UPS-backed outlet distribution or metering, adding remote switching only after its recovery hazards are controlled.
A PDU is the supported way to distribute UPS output across more devices. It is not automatically a networked remote-control device:
- Basic PDU: safe outlet distribution.
- Metered PDU: shows aggregate or per-outlet load.
- Monitored PDU: reports load remotely.
- Switched/managed PDU: can turn individual outlets off and on.
Eaton distinguishes these capabilities in its rack PDU guide. Start with a compatible basic or metered PDU. Add switching only as part of the later lights-out control design.
Follow the UPS manufacturer's wiring rules. Schneider Electric recommends plugging its UPS directly into the wall, not a surge strip or extension cord, and using a PDU rather than a surge protector when more output receptacles are needed; see APC FAQ FA158852. Check the manual for the exact UPS and PDU.
Power-failure drills#
TL;DR: Run simulated and attended real outages to prove clean shutdown, control-path endurance, measured battery margin, ordered return, bounded notification, and no stalled primary.
Work profile: operational size
XL; quotamedium; human effortlarge; agent effortmedium; waitlarge; outageplanned network/service/power interruption; attended household disruption; storage preflight required; clock durationunknownuntil target-specific evidence exists.
Perform two drills:
- A NUT simulated forced-shutdown drill with destructive actions replaced by logging, followed by a coordinated software shutdown test.
- A real input-power loss with workloads idle, a person present, and the recovery card open.
Verify that:
- Household Wi-Fi and broadband remain available while the server sheds load.
- Every currently present writable filesystem shuts down cleanly; repeat after the data pool exists.
- The UPS retains enough measured margin.
- Power-return behavior makes dependencies ready in order through measured boot delays, native dependency gates, or a separately justified switched-power interlock; merely energizing a basic PDU is not evidence.
- If alerting already exists, exactly one actionable notification and one recovery notification are emitted; otherwise add this assertion when the monitoring upgrade is installed.
- Failed clients cannot delay the primary until the battery is exhausted.
Phase 3 exit test: the UPS carries the measured current load plus its recorded reserve, the empty server shuts down cleanly, network/control outlives compute, and restoration needs no rack visit. Phase 4 cannot store valuable data until the same test passes with the actual disks; Phases 5–6 cannot claim their final runtime until it passes under their accepted workloads.
Step 9 — Add remote console and power controls only when needed#
TL;DR: Escalate from native service recovery through graceful reboot, console inspection, hardware reset, and outlet cycling only when each gentler option fails.
Work profile: operational size
large; quotalarge; human effortmedium; agent effortlarge; waitlarge; outagepossible host/power outage; Tier 0/1 controls remain human-only; clock durationunknownuntil target-specific evidence exists.
“Lights out” means routine operations and ordinary failures do not require a visit. It does not mean that every failure must be remotely recoverable or that an agent may pull power whenever a service is slow.
Use this escalation ladder:
- Restart the failed application through its native supervisor.
- Reboot the operating system gracefully.
- Inspect boot, firmware, and console state through an out-of-band KVM.
- Issue a momentary ATX power or reset action through a hardware controller.
- Cycle a PDU outlet.
- Visit the hardware.
Each rung is authorized only after the gentler rung has failed or is unavailable.
Add a remote console before remote power cycling#
TL;DR: Add VPN-only KVM access when pre-SSH diagnosis or boot interaction justifies it, keeping powerful console and ATX actions human-controlled until safely mediated.
A PiKVM-class device becomes justified when:
- The server can hang before SSH starts.
- Firmware or bootloader interaction must be possible remotely.
- Encrypted-boot recovery needs console visibility.
- Travel or distance makes a physical visit materially costly.
PiKVM can emulate keyboard, video, storage, and ATX front-panel actions. Its ATX documentation describes the motherboard adapter, and its authentication guide makes clear that the OS and KVM accounts are separate and both default passwords must be changed.
Place the KVM on UPS power and make it reachable through the VPN, never a public port forward. Keep its recovery IP and local credential independent of DNS and SSO. Disable unused web-terminal or mass-storage capabilities.
The agent may receive read-only console screenshots or boot-state telemetry. On day one, the human performs power-on and graceful reboot. Either action may be delegated later only through a real, independently reviewed fixed action that binds one target, verifies current state and a separate human grant, limits attempts and cooldown, records audit, and cannot expose the broader KVM session. Hard-off, reset, virtual-media write access, firmware changes, and credential administration remain human-authorized.
Switched PDU interlocks#
TL;DR: Protect Tier 0/1 outlets, bind actions to verified state and labels, limit cycles, enforce cooldown, and prove local re-energization before allowing remote switching.
A remotely switched PDU is useful for a truly wedged device and for load shedding, but it can also destroy the only path back into the house.
Apply these invariants:
- Label each physical outlet and verify the label by observation before enabling switching.
- Separate read-only metering credentials from switching credentials.
- The agent cannot modify PDU accounts, outlet mappings, network settings, or its own grants.
- Tier 0/1 outlets—broadband handoff, router, primary Wi-Fi, switch, Pi-hole, VPN node, PDU management, and KVM—are not agent-switchable.
- A server outlet is not cut until filesystem and shutdown checks have failed under a declared incident procedure.
- Only one power-cycle attempt is permitted before escalation.
- A cooldown prevents reboot loops.
- Every command names the expected current state and target outlet; mismatches stop execution.
Power-cycling the router remotely is allowed only if the PDU can schedule local re-energization before it turns the outlet off and that behavior has been tested without network access. If “off” succeeds but “on” requires the now-dead network connection, remote switching is prohibited.
A smart plug that requires the same home's Wi-Fi, DNS, internet, and vendor cloud is a convenience device, not out-of-band control.
Honest limits#
TL;DR: Admit that true recovery from simultaneous power, ISP, router, UPS, and cellular failure requires independently powered communications and may not justify its burden.
No ordinary homelab remote-access design survives a neighborhood power outage, failed ISP, dead router, failed UPS, and failed cellular coverage simultaneously. True remote recovery across those failures requires an independent power and communication path, such as a cellular console and separately powered control hardware. Add it only if the cost of a visit justifies it.
Exit test: a simulated OS hang can be diagnosed at the console; the owner can recover it without public management exposure; forbidden power actions fail; a deliberate server cycle restores service; loss of the primary remote node leaves another path.
Step 10 — Monitor important services from another failure domain#
TL;DR: Start by externally checking whether the owner can still control the home rather than collecting comprehensive internal metrics.
Work profile: operational size
large; quotalarge; human effortsmall; agent effortlarge; waitmedium; outagenone; monitoring only; no remediation authority; clock durationunknownuntil target-specific evidence exists.
Begin monitoring with one question: “Can a person still control the house?” Do not begin by collecting every metric.
Start with an outside check#
TL;DR: Use outside heartbeats or narrowly scoped overlay probes that survive home failure without exposing private management endpoints.
Use a hosted dead-man check or a small monitor outside the home. Send outbound, authenticated heartbeats with nonsensitive identifiers:
- Site-internet heartbeat from the Pi or another low-power network node.
- Control-host heartbeat from the Mac mini.
- Backup/restore-test heartbeat from the backup workflow.
If the house, ISP, router, or internal monitoring stack disappears, the outside service can still notify the owner. An internal dashboard cannot.
Do not expose a private management endpoint merely so an external monitor can poll it. For VPN-only services, either:
- Probe from an already-needed remote node inside the overlay.
- Send an outbound signed heartbeat.
- Run a scheduled owner-device recovery drill until a remote node is justified.
Public, intentional services may be probed externally over their real protocol. Prometheus's official blackbox exporter supports HTTP, HTTPS, DNS, TCP, ICMP, and gRPC probes, but running it inside the same home does not make the check external.
Start with a short alert list#
TL;DR: Notify only for persistent control, connectivity, power, certificate, security, backup, or recovery failures that require a concrete human action.
Notify immediately only for:
- Tier 0 local-control loss while other evidence says the site is powered.
- Tier 1 site connectivity or remote-entry loss that persists beyond the declared transient window.
- UPS on battery long enough that shutdown or a human decision is approaching.
- Failed orderly shutdown, battery self-test, or power-return recovery.
- Private/public certificate renewal failure with enough time to act.
- A security event that requires credential revocation or isolation.
- Backup or restore-test failure.
Everything else is a dashboard, log, or periodic report until it has a specific human action.
Prometheus's alerting practice recommends few alerts, symptoms tied to user pain, slack for brief blips, and external black-box monitoring. Follow that discipline even if Prometheus is not the chosen tool.
Group alerts caused by the same failure#
TL;DR: Group and inhibit derivative alerts beneath the earliest failed dependency while recording current impact, evidence, action, recovery, and lifecycle state.
If the site heartbeat is absent, inhibit alerts for Pi-hole, Mac mini, server, and every application. If DNS is down, suppress derivative “cannot resolve service” notifications. If the UPS is in a declared shutdown, suppress expected host-down alerts.
Alertmanager implements grouping, deduplication, silencing, and inhibition for exactly this purpose; see the Alertmanager overview. It is an upgrade when the alert set has grown enough to need it, not a prerequisite for the first three heartbeats.
Each incident record contains:
- Owner-visible impact.
- First and latest observation.
- Current live revalidation time.
- Dependency believed to have failed, clearly marked as inference.
- Bounded remediation already attempted.
- Exact requested human action.
- Recovery instructions.
- Acknowledged, expired, and resolved state.
An agent rechecks live state before acting on any earlier alert or conversation. An alert is not proof that the condition still exists.
Monitoring permissions#
TL;DR: Allow monitoring to observe, probe, and manage incident state but not restart devices, change policy, suppress its own alerts, or erase history.
The monitoring identity may:
- Read health, UPS state, certificate expiry, and resource metrics.
- Perform protocol-level probes.
- Open or resolve one incident.
It may not:
- Restart or power-cycle devices.
- Change alert thresholds or inhibit its own alerts.
- Modify firewall, VPN, DNS, CA, or PDU policy.
- Delete incident history.
Remediation is a separate, narrowly scoped identity with a rate limit and explicit eligible actions.
Exit test: unplugging the WAN creates one site-impact alert and inhibits downstream noise; restoring it creates one closure. Stopping only Pi-hole produces a DNS-impact alert while direct-IP Tier 0 remains usable. A stale incident cannot trigger a new power action.
The one command packet the owner runs#
TL;DR: Present discovered router, Mac, VPN, physical, and drill work as one ordered packet with exact screens, expected results, reversals, and destination-only secret entry.
Work profile: operational size
XL; quotamedium; human effortlarge; agent effortlarge; waitlarge; outageplanned network/power drills; all disruption is itemized before invocation; clock durationunknownuntil target-specific evidence exists.
Once discovery has filled in the actual product names and interfaces, the agent gives the owner one ordered packet, not a sequence of “shall I continue?” interruptions. Every foreseeable shell action is implemented by one small reviewed script or equivalent transaction with one copy-and-paste invocation. That script names and asserts host, account, working directory, interfaces, existing routes/listeners, and configuration digests; performs shell/Python syntax checks and representative regex fixtures when applicable; validates every candidate with the native parser; applies only the sealed dependency closure; tests allowed and denied paths plus the household-visible outcome; captures evidence; and stops without improvising a rollback. UI and physical actions remain one grouped checklist in the same packet.
The packet should contain:
-
Router/mesh application
- Export configuration.
- Reserve infrastructure addresses.
- Advertise Pi-hole as LAN DNS over IPv4 and IPv6 where supported.
- Confirm no management port forwards.
- Disable automatic port mapping and recheck the forward table.
- Record guest/IoT-network behavior without assuming isolation.
-
Mac mini System Settings
- Enable Screen Sharing and Remote Login for named accounts only.
- Configure energy and startup behavior supported by that model.
- Confirm the recovery account works without a cloud prompt.
-
VPN administration
- Enroll the owner's phone/laptop and infrastructure nodes.
- Apply the staged, tested default-deny grants.
- Configure restricted DNS for home.arpa.
- Keep VPN administrative credentials human-only.
-
Physical work
- Label both ends of network and power cables.
- Label and reserve the direct-recovery adapter and cable.
- Place the tower and UPS safely.
- Connect every Tier 0/1 dependency to the intended protected outlet.
- Connect the UPS data cable to its designated primary.
-
Drills
- Perform the router/AP/DHCP-off direct-cable test.
- Perform the WAN-disconnected local-control test.
- Perform the cellular remote-entry test.
- Perform simulated and real UPS tests with a person present.
Every item names the exact screen, expected value, expected result, and prepared reversal action for the discovered equipment. Secret values are entered into their destination, never pasted into chat. If a check fails, preserve access and evidence, recommend rollback where appropriate, state its risks, and ask the owner whether to execute it.
When a private CA, PDU, KVM, VLAN, or richer monitor is actually selected, create a separate just-in-time packet for that feature. Do not make the owner perform certificate trust or remote-power work merely because those sections exist.
What the agent may do#
TL;DR: Begin with observation and human-executed mutation, delegating only independently reviewed fixed operations whose targets, arguments, grants, audit, and revocation are enforced outside agent control.
Start read-only. Privileged or policy-changing mutation remains in the consolidated human packet until a specific enforcement mechanism has a documented implementation and independent security review. The “later operating grant” column describes a possible end state, not a component this guide supplies:
| Surface | Discovery grant | Later operating grant | Never delegated |
|---|---|---|---|
| Router/mesh | Read an owner-provided export or redacted status; avoid a broad cloud-admin credential. | None initially; later, a fixed configuration-backup action may be reasonable. | Firmware flash, factory reset, port-forward creation, admin-account changes. |
| Pi-hole | Read a locally generated, redacted status export. A Pi-hole application-password session is not a per-endpoint read-only role; its own configuration reference documents permissions that can still include list management and destructive API calls. | A separately enforced action may apply a validated record-set diff and reload DNS. | Raw household query history by default, open listening mode, DHCP cutover, account/grant changes. |
| Tailscale | Read device and connection status; validate staged policy. | Enroll a preapproved tagged machine or revoke its own expired test identity. | Policy administration, owner-role changes, recovery settings, self-expansion. |
| Host firewall | Read rules and listening sockets. | After explicitly asking the owner whether to use the timed fail-safe transaction, install one native-validated, owner-approved ruleset and verify both the retained path and actual timer outcome. | Disable firewall, widen management sources, change the installer grant, or let the LLM choose rollback after failure. |
| Private CA | Read health and public certificate inventory. | Request approved leaf names; deploy and reload named services. | Root/intermediate key access, provisioner or policy administration. |
| UPS/NUT | Read telemetry, events, and client state. | Reload a validated client configuration; normal root-owned shutdown daemon acts automatically. | Set forced shutdown ad hoc, change shutdown command, cut output. |
| PDU/KVM | Read outlet, power, and console state. | At most one approved graceful reboot or server outlet cycle behind interlocks. | Tier 0/1 outlet control, credentials, outlet mapping, firmware, self-grants. |
No general-purpose sudo is needed. On day one, the agent renders, validates, and journals a candidate; the human runs one narrow privileged packet. A later fixed action is privileged software: it needs caller authentication, fixed targets, canonical path and symlink handling, digest revalidation at execution, concurrency and replay limits, crash-safe state, expiry/revocation, audit, and its own update path. Functional happy-path tests alone do not establish that boundary.
Final local and remote access test#
TL;DR: Prove local control, remote-entry diversity, DNS independence, power endurance and ordered return, agent denial, and recoverable session state under representative failures.
Work profile: operational size
XL; quotamedium; human effortlarge; agent effortmedium; waitlarge; outageplanned WAN/DNS/network/power interruption; attended household disruption; no unapproved storage risk; clock durationunknownuntil target-specific evidence exists.
The chapter is complete only when all of these are observed:
| Failure introduced | Expected result |
|---|---|
| WAN cable disconnected | Household internet fails as expected; local Tier 0 access remains intact by direct IP. |
| Router/AP/DHCP and relevant switch unavailable | The keyboarded Mac reaches the server through the labeled direct cable, static non-routed addresses, and recorded key. |
| Private DNS stopped | Public browsing by name may fail if there is no redundant resolver; direct-IP recovery remains intact and the failure is obvious. |
| Mac mini VPN client stopped | The server or low-power VPN node remains reachable from cellular. |
| Mac mini rebooted | Screen Sharing, SSH, agent workspace, and overlay return without a laptop remaining open. |
| Brief utility outage | UPS carries the load; no noisy incident and no unnecessary shutdown. |
| Extended utility outage | In the provisional Phase 3 drill, the empty server stops cleanly first; networking and control persist; remaining systems shut down with measured margin. Repeat after storage and applications exist. |
| Utility restored | Network and DNS return before the empty server; unstable power does not cause a reboot loop. Later phases add storage and application ordering to this drill. |
| Agent requests an unimplemented privileged action | It can stage a candidate but cannot execute it; one consolidated human boundary remains. |
Store the evidence and date. Repeat the relevant drill after router replacement, Wi-Fi replacement, VPN-policy change, DNS/DHCP migration, or UPS battery replacement. PDU, KVM, CA, and monitoring sections add their own acceptance rows only when installed.
What may safely wait#
TL;DR: Defer VLANs, redundant DNS, alternative VPN control planes, public naming, private PKI, rack hardware, external storage, remote power, KVM, rich monitoring, and redundant utilities until explicit evidence justifies them.
These are upgrades, not missing prerequisites:
- Managed switching and VLANs: add when flat-LAN reachability creates a concrete policy or incident problem, or when Wi-Fi/switching is already being replaced.
- A second DNS appliance: add after both resolvers can share one tested record and policy source.
- Plain WireGuard or self-hosted coordination: add when control-plane independence justifies the public endpoint and operational work.
- A public domain and dynamic DNS: add for an intentionally public service or direct WireGuard endpoint, not for private management.
- A private CA: it can wait until authenticated private web services justify client trust installation, but it must precede normal use of passwords over private web interfaces.
- A short rack chassis: add when the current tower fails a space, serviceability, or organization requirement.
- An external SAS shelf: add only when drive growth or compute/storage separation justifies its depth, noise, cooling, and power.
- A switched PDU: add after orderly shutdown, outlet mapping, VPN-only administration, and fail-safe re-energization are proven.
- PiKVM or cellular out-of-band access: add when the expected cost of a physical visit exceeds the hardware and security burden.
- Prometheus and Alertmanager: add when the small external heartbeat and action-oriented alert set need aggregation, inhibition, and richer investigation.
- A second ISP, cellular router, generator, or whole-home battery: add only if Tier 1 availability during provider or prolonged utility failure is a stated requirement.
The stopping rule is simple: once Tier 0 and Tier 1 pass their drills, build the next household outcome. Do not keep “improving the network” because more elaborate network designs exist.