homelab: sync post-migration repo and n8n runtime audit
Some checks failed
secret-guardrails / artifact-secret-scan (push) Has been cancelled
secret-guardrails / gitleaks (push) Has been cancelled

This commit is contained in:
Fizzlepoof
2026-05-22 23:04:33 +00:00
parent d62a391cbf
commit bec21292de
28 changed files with 6291 additions and 430 deletions

View File

@@ -0,0 +1,76 @@
{
"custom_policies": [
{
"_id": "6963d6bb1131084f05461b71",
"action": "ALLOW",
"connection_state_type": "ALL",
"connection_states": [],
"create_allow_respond": true,
"description": "",
"destination": {
"match_opposite_ports": false,
"matching_target": "ANY",
"port_matching_type": "ANY",
"zone_id": "6963d5a91131084f05461a0d"
},
"enabled": true,
"icmp_typename": "ANY",
"icmp_v6_typename": "ANY",
"index": 10000,
"ip_version": "BOTH",
"logging": false,
"match_ip_sec": false,
"match_opposite_protocol": false,
"name": "Allow Internal to Untrusted",
"predefined": false,
"protocol": "all",
"schedule": {
"mode": "ALWAYS"
},
"source": {
"match_opposite_ports": false,
"matching_target": "ANY",
"port_matching_type": "ANY",
"zone_id": "6963d42a1131084f054618df"
}
},
{
"_id": "6a10cbca0ab9980e4eac4553",
"action": "BLOCK",
"connection_state_type": "ALL",
"connection_states": [],
"create_allow_respond": false,
"description": "",
"destination": {
"match_opposite_ports": false,
"matching_target": "ANY",
"port_matching_type": "ANY",
"zone_id": "6963d5a91131084f05461a0d"
},
"enabled": false,
"icmp_typename": "ANY",
"icmp_v6_typename": "ANY",
"index": 10001,
"ip_version": "BOTH",
"logging": false,
"match_ip_sec": false,
"match_opposite_protocol": false,
"name": "DORIS-TEMP",
"predefined": false,
"protocol": "all",
"schedule": {
"date": "2026-05-22",
"mode": "ONE_TIME_ONLY",
"time_range_end": "12:00",
"time_range_start": "09:00"
},
"source": {
"match_opposite_ports": false,
"matching_target": "ANY",
"port_matching_type": "ANY",
"zone_id": "6963d42a1131084f054618df"
}
}
],
"policy_count": 109
}

View File

@@ -0,0 +1,153 @@
[
{
"_id": "6a10c5fe0ab9980e4eac37be",
"external_id": "535d893d-90ef-45ac-8d84-fc0b9d711b22",
"group_members": [
"10.5.0.0/24"
],
"group_type": "address-group",
"name": "NET-MGMT",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5fe0ab9980e4eac37c1",
"external_id": "146a4b9d-86c7-4d15-afef-2ea02374e9be",
"group_members": [
"10.5.1.0/24"
],
"group_type": "address-group",
"name": "NET-TRUSTED",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5fe0ab9980e4eac37c4",
"external_id": "81e1423a-74ce-43cf-9b42-33f641452ac7",
"group_members": [
"10.5.30.0/24"
],
"group_type": "address-group",
"name": "NET-SERVERS",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5fe0ab9980e4eac37c7",
"external_id": "e5a36792-c65d-434b-9fef-5259bee6e653",
"group_members": [
"10.5.10.0/24"
],
"group_type": "address-group",
"name": "NET-IOT",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5fe0ab9980e4eac37ca",
"external_id": "49c1cd44-998e-4c36-bfc4-42eeb5ce9a11",
"group_members": [
"10.5.90.0/24"
],
"group_type": "address-group",
"name": "NET-GUEST",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37cd",
"external_id": "e933b5f7-ecc0-4e93-a9e7-3924f507e0bf",
"group_members": [
"10.5.20.0/24"
],
"group_type": "address-group",
"name": "NET-CAMERAS",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37cf",
"external_id": "6a05ad73-6fda-4a3d-b1bf-c4eb6ffffee3",
"group_members": [
"192.168.1.0/24"
],
"group_type": "address-group",
"name": "NET-LEGACY-CIA",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37d3",
"external_id": "2fac4800-7ec2-48d1-8ecb-c3c357330c1e",
"group_members": [
"53"
],
"group_type": "port-group",
"name": "PORT-DNS",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37d6",
"external_id": "3ac9f355-c4c4-4121-b437-47f2ebd72c49",
"group_members": [
"67-68"
],
"group_type": "port-group",
"name": "PORT-DHCP",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37d9",
"external_id": "e361fb19-a9b8-4d14-b117-18356ad79c9b",
"group_members": [
"123"
],
"group_type": "port-group",
"name": "PORT-NTP",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37dc",
"external_id": "4ae091e5-0139-4e10-9e88-6b0abe950538",
"group_members": [
"80",
"443",
"8443",
"9443"
],
"group_type": "port-group",
"name": "PORT-WEB-ADMIN",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37df",
"external_id": "db376d79-c9aa-4f3a-b040-a6a76c195733",
"group_members": [
"22"
],
"group_type": "port-group",
"name": "PORT-SSH",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c5ff0ab9980e4eac37e2",
"external_id": "0af620e5-ef70-41a2-bc57-d9fed44c4bcb",
"group_members": [
"5353"
],
"group_type": "port-group",
"name": "PORT-MDNS",
"site_id": "6963c5321131084f05460911"
},
{
"_id": "6a10c6580ab9980e4eac3914",
"external_id": "3f903463-6305-4c09-ba0c-85b729268a99",
"group_members": [
"10.5.0.0/24",
"10.5.1.0/24",
"10.5.10.0/24",
"10.5.20.0/24",
"10.5.30.0/24",
"10.5.90.0/24",
"192.168.1.0/24",
"192.168.2.0/24",
"192.168.3.0/24"
],
"group_type": "address-group",
"name": "NET-RFC1918-ALL",
"site_id": "6963c5321131084f05460911"
}
]

View File

@@ -0,0 +1,91 @@
# Network Migration Remaining Checklist
Current intent: only safe, low-drama follow-up work remains. The easy-value client cleanup already completed should not be re-run.
## Already completed
- Servers network/profile exists in UniFi
- Protect WiFi Chime `upstairs landing` moved from Management -> Camera
- Protect WiFi Chime `Living Room` moved from Management -> Camera
- `LG_Smart_Laundry2_open` moved from Trusted -> IoT
- `MyQ-29B` moved from Old IoT -> IoT
- `LG_Smart_Dryer2_open` moved from Old IoT -> IoT
- `Samsung-FamilyHub` moved from Old IoT -> IoT
- `Main-Floor` ecobee moved from Old IoT -> IoT
- `Upstairs` ecobee moved from Old IoT -> IoT
- These 8 client moves were verified live from UniFi `stat/sta`
- Firewall object/group scaffolding exists
- Basic custom outbound policy scaffolding exists (`Allow Internal to Untrusted`)
## Safe to do now
1. Documentation cleanup
- treat older pre-move docs as historical snapshots, not live next-step instructions
- use this file as the current remaining-work reference
2. Finalize remaining task list
- keep Google/cast pilot explicitly deferred until John is on the laptop
- keep unknown Legacy CIA devices explicitly quarantine-first
- keep Intellirocks-in-Trusted explicitly flagged for later identification/move decision
3. Non-disruptive firewall planning cleanup
- compare staged firewall objects/policies against desired rule order
- produce a precise missing-rules gap list before any live rule apply
## Still pending before the migration is truly finished
### A. Google/cast validation batch
Do later, with user present on laptop:
- pilot one Google/cast-class device only
- validate Plex playback
- validate Plex discovery/casting
- validate Dispatcharr once relevant
- if ugly, revert that one device and defer the rest
Likely candidates still needing that treatment:
- `dc:e5:5b:8f:57:d2` (Google client currently in Trusted)
- `Google-Home-Mini`
- `3c:8d:20:f3:92:36`
- `90:ca:fa:b6:7f:6e`
### B. Remaining Trusted-lane cleanup
- `d4:ad:fc:f2:df:d2` likely does not belong in Trusted
- decide: identify better, move to IoT, or quarantine later
### C. Legacy CIA quarantine closeout
Leave quarantined unless identified better:
- `5c:61:99:41:73:40`
- `60:74:f4:54:fd:ec`
- `60:74:f4:7b:6a:11`
- `c0:f5:35:20:5d:94`
- `d4:ad:fc:60:90:6a`
- `d4:ad:fc:ea:7f:65`
### D. Real firewall enforcement
Still needed if the design is to be truly enforced rather than just staged:
- stateful baseline rules
- management shield
- explicit Trusted admin -> Management allows
- Trusted -> Servers allow
- Guest internet-only enforcement
- IoT narrow internal access only
- Camera narrow internal access only
- Legacy CIA quarantine-only posture
- broad deny structure for restricted lanes
Important distinction:
- groups/objects exist
- at least one custom outbound policy exists
- the full inter-VLAN segmentation matrix is not yet fully enforced
### E. Final cleanup
- SSID simplification once Google/cast behavior is understood
- final validation sweep
- confirm no temporary panic exceptions remain
- document any intentionally deferred weird devices
## Suggested execution order from here
1. Produce firewall gap list
2. Wait for laptop session
3. Run one-device Google/cast pilot
4. Decide on Trusted Intellirocks device
5. Finish firewall enforcement carefully
6. Do final SSID simplification and closeout

View File

@@ -0,0 +1,102 @@
# UniFi Client Cleanup Shortlist
Live basis:
- Captured from PD with `python3 automation/bin/unifi_network.py --raw`
- Capture time: 2026-05-22 21:45:20 UTC
- Scope: active clients only
## What looks correct already
- Servers lane: `PlausibleDeniability`, `Serenity`, `Nomad`
- Camera lane: `front-doorbell`
- Trusted human/operator lane: `Rocinante`, `FlyingDutchman`, `Pixel-7`, `Pixel-9-Pro-XL`, `Valkyrie`, `steamdeck`
- Trusted tooling/device that is probably intentional: `MeshMonitor (MT)`
## Immediate cleanup candidates
### 1. Move out of Trusted first
These are the clearest remaining misclassifications, and the smart-appliance targets are now approved for `IoT`.
- `LG_Smart_Laundry2_open` (`10.5.1.184`, `60:ab:14:5f:b4:ba`)
- Current lane: `Trusted`
- Approved target: `IoT`
- Identification confidence: high
- Why: named LG appliance endpoint and sibling to `LG_Smart_Dryer2_open`; does not belong in the human/operator lane.
- `dc:e5:5b:8f:57:d2` (`10.5.1.132`, Google)
- Current lane: `Trusted`
- Likely identity: Google cast/speaker/display-class client
- Likely target: `IoT`, but late-batch after discovery validation
- Why:
- Google vendor fingerprint
- same family as the three Google clients still on `Old IoT`
- consumer Wi-Fi client on the compat Trusted SSID, not a human endpoint
- heavy traffic pattern is consistent with a media/cast-style household device
- Caution: treat like the other Google/cast discovery-sensitive devices. Do not broaden policy just to appease casting.
- `d4:ad:fc:f2:df:d2` (`10.5.1.154`, Shenzhen Intellirocks Tech)
- Current lane: `Trusted`
- Likely identity: sibling to the two unnamed Intellirocks devices already on `Old IoT`; likely smart-home / embedded device class
- Likely target: `IoT` or quarantine later if still unidentified
- Why: vendor-family clustering strongly suggests it belongs with the other low-trust embedded devices, not with human/operator endpoints.
- Caution: identify before moving if possible; if unknown, do not promote it by leaving it in Trusted.
## Management offenders
These are now identified and should not remain on Management.
- `58:d6:1f:54:e5:6d` (`10.5.0.123`, hostname `espressif`)
- Identified as: UniFi Protect WiFi Chime
- Friendly name from controller fingerprint: `upstairs landing`
- Best-fit target lane: `Camera` / security
- `58:d6:1f:54:e5:af` (`10.5.0.189`, hostname `espressif`)
- Identified as: UniFi Protect WiFi Chime
- Friendly name from controller fingerprint: `Living Room`
- Best-fit target lane: `Camera` / security
Notes:
- Both are Wi-Fi clients on `UniFi Wireless`.
- UniFi fingerprint metadata reports `product_line=unifi-protect` and `product_model=Protect WiFi Chime`.
- This means they are not mystery ESP junk anymore; they are known Protect accessories that should be treated like camera/security estate, not management-plane clients.
## Old IoT move-now set
These still look like the cleanest deliberate moves from `CIA Via` into `IoT`.
1. `MyQ-29B` (`192.168.1.130`)
2. `LG_Smart_Dryer2_open` (`192.168.1.186`)
3. `Samsung-FamilyHub` (`192.168.1.149`)
4. `Main-Floor` ecobee (`192.168.1.102`)
5. `Upstairs` ecobee (`192.168.1.131`)
## Old IoT move-later / discovery-sensitive
These are probably IoT-class eventually, but not the first things to touch if the goal is a calm cleanup.
- `Google-Home-Mini` (`192.168.1.185`)
- `3c:8d:20:f3:92:36` (`192.168.1.192`, Google)
- `90:ca:fa:b6:7f:6e` (`192.168.1.129`, Google)
## Old IoT quarantine-first leftovers
Leave these in legacy quarantine unless/until they are identified better.
- `5c:61:99:41:73:40` (`192.168.1.172`)
- `60:74:f4:54:fd:ec` (`192.168.1.136`)
- `60:74:f4:7b:6a:11` (`192.168.1.117`)
- `c0:f5:35:20:5d:94` (`192.168.1.183`)
- `d4:ad:fc:60:90:6a` (`192.168.1.100`)
- `d4:ad:fc:ea:7f:65` (`192.168.1.101`)
## Recommended next move order
If doing a low-drama cleanup pass, use this order:
1. Move `LG_Smart_Laundry2_open` out of `Trusted` into `IoT`
2. Re-home the two identified Protect chimes out of `Management` into `Camera` / security
3. Migrate the approved Old IoT move-now set into `IoT`, one app-validated batch at a time
4. Leave Google/cast-class gear for later unless everything else is stable
5. Keep unknown leftovers quarantined; do not “clean them up” by granting `Trusted`
## Bottom line
The clearest remaining lane problems are now:
- one approved LG appliance still sitting in `Trusted`
- one likely Google cast/display-class client in `Trusted`
- one likely Intellirocks smart-home client in `Trusted`
- two now-identified Protect chimes still sitting in `Management`
- the approved appliance/thermostat/MyQ devices still lingering in `Old IoT`

View File

@@ -0,0 +1,28 @@
# UniFi Client Rehome Results
Executed from PD against the live UniFi controller using per-client virtual network overrides plus targeted `kick-sta` reconnects.
## Requested changes completed
### Trusted -> IoT
- `LG_Smart_Laundry2_open` (`60:ab:14:5f:b4:ba`) -> `IoT` -> `10.5.10.141`
### Management -> Camera
- Protect WiFi Chime `upstairs landing` (`58:d6:1f:54:e5:6d`) -> `Camera` -> `10.5.20.191`
- Protect WiFi Chime `Living Room` (`58:d6:1f:54:e5:af`) -> `Camera` -> `10.5.20.8`
### Old IoT -> IoT
- `MyQ-29B` (`0c:95:05:0b:76:65`) -> `IoT` -> `10.5.10.88`
- `LG_Smart_Dryer2_open` (`60:ab:14:94:e4:aa`) -> `IoT` -> `10.5.10.11`
- `Samsung-FamilyHub` (`fc:03:9f:e5:64:50`) -> `IoT` -> `10.5.10.117`
- `Main-Floor` ecobee (`44:61:32:1d:ee:8f`) -> `IoT` -> `10.5.10.160`
- `Upstairs` ecobee (`44:61:32:3f:0b:4c`) -> `IoT` -> `10.5.10.64`
## Validation result
All 8 targeted clients were re-read live from `stat/sta` and matched their intended target lanes.
## Notes
- Rehome mechanism used: `PUT /rest/user/<id>` with `network_id`, `virtual_network_override_enabled=true`, and `virtual_network_override_id=<target_network_id>`
- Reconnect mechanism used: `POST /cmd/stamgr` with `cmd=kick-sta`
- `LG_Smart_Laundry2_open` had a temporary probe note during discovery; it was cleared during the live apply
- Some clients still show their original SSID names in UniFi telemetry even after landing on the target virtual network override; the authoritative validation point for this pass was the live `network` / `network_id` state

View File

@@ -0,0 +1,218 @@
# UniFi Firewall Gap List
Purpose: compare the intended segmentation design against the current staged UniFi firewall artifacts without making any live traffic changes.
Evidence used:
- Desired design: `home/doris-dashboard/docs/network-firewall-rule-order.md`
- Current groups baseline: `home/doris-dashboard/docs/baselines/unifi-firewallgroup-baseline-2026-05-22-post-stage.json`
- Current custom policy baseline: `home/doris-dashboard/docs/baselines/unifi-firewall-policies-custom-2026-05-22-post-ui-probe.json`
## Executive summary
Current state is scaffolding, not finished enforcement.
What exists now:
- network/address groups for the major lanes
- a handful of port groups
- one enabled custom outbound-style policy: `Allow Internal to Untrusted`
- one disabled temp policy: `DORIS-TEMP`
What does not yet exist in the captured custom-policy baseline:
- the actual inter-VLAN segmentation matrix
- the management shield
- the quarantine posture for Legacy CIA
- the lane-specific allow/deny structure described in the design doc
So the honest answer is:
- groups/objects: mostly present
- real custom segmentation policy: largely still missing
## 1. Present in the current staged baseline
### Network groups present
- `NET-MGMT`
- `NET-TRUSTED`
- `NET-SERVERS`
- `NET-IOT`
- `NET-GUEST`
- `NET-CAMERAS`
- `NET-LEGACY-CIA`
- `NET-RFC1918-ALL`
### Port groups present
- `PORT-DNS`
- `PORT-DHCP`
- `PORT-NTP`
- `PORT-WEB-ADMIN`
- `PORT-SSH`
- `PORT-MDNS`
### Custom policies present
1. `Allow Internal to Untrusted`
- enabled
- effectively basic internal -> internet/outside allowance scaffolding
2. `DORIS-TEMP`
- disabled
- temporary/non-production artifact, not part of the final design
## 2. Missing object inventory compared to the design
The rule-order design expects these host/device groups, but they do not appear in the captured firewall-group baseline:
- `HOST-ADMIN-TRUSTED`
- `HOST-CORE-SERVICES`
- `HOST-PROTECT-SERVICES`
- `HOST-DNS`
- `HOST-NTP`
- `HOST-IOT-HELPERS`
- `HOST-CAMERA-HELPERS`
- `HOST-LEGACY-EXCEPTIONS`
The design also mentions port groups not seen in the captured baseline:
- `PORT-PROTECT`
- `PORT-CAST`
Impact:
- exact narrow allow rules for management, Protect, helper traffic, and Google/cast exceptions cannot be cleanly expressed yet using the intended group model
## 3. Missing rule sections compared to the design
### Section A: Core state handling
Missing or not evidenced in the captured custom-policy baseline:
- `ALLOW Established/Related`
- `DROP Invalid`
### Section B: Management protection
Missing or not evidenced:
- `ALLOW Trusted Admin -> Management Admin Surfaces`
- `ALLOW Trusted Admin -> Gateway Infra Utilities`
- `DROP IoT -> Management`
- `DROP Cameras -> Management`
- `DROP Guest -> Management`
- `DROP Legacy CIA -> Management`
- `DROP Any Internal -> Management`
Meaning:
- the intended management shield is not yet represented in the captured custom-policy set
### Section C: Trusted human lane
Missing or not evidenced:
- `ALLOW Trusted -> Servers Approved Access`
- `ALLOW Trusted -> Cameras Admin/Viewer Access`
- `ALLOW Trusted -> IoT Control Exceptions`
Meaning:
- the designs explicit human/operator access model is not yet staged in a visible way
### Section D: Server/helper traffic
Missing or not evidenced:
- `ALLOW Servers -> IoT Approved Helpers`
- `ALLOW Cameras -> Protect Services`
- `ALLOW IoT -> Approved Server Helpers`
- `ALLOW Legacy CIA -> Approved One-Off Exception`
Meaning:
- no captured evidence yet of the narrow internal service exceptions the design wants
### Section E: DNS/NTP baseline for restricted lanes
Missing or not evidenced:
- `ALLOW IoT -> DNS`
- `ALLOW Cameras -> DNS`
- `ALLOW Legacy CIA -> DNS`
- `ALLOW IoT -> NTP`
- `ALLOW Cameras -> NTP`
- `ALLOW Legacy CIA -> NTP`
Meaning:
- the restricted-lane minimum-function posture is not yet fully expressed in custom rules
### Section F: Internet access for constrained lanes
Partially present at best:
- there is one broad custom policy, `Allow Internal to Untrusted`
Still missing as lane-specific explicit policy:
- `ALLOW Guest -> Internet`
- `ALLOW IoT -> Internet`
- `ALLOW Cameras -> Internet Updates`
- `ALLOW Legacy CIA -> Internet`
Meaning:
- outbound access is only evidenced in a broad/global way, not in the lane-specific shape called for by the design
### Section G: Broad internal denies for restricted lanes
Missing or not evidenced:
- `DROP Guest -> RFC1918/Internal`
- `DROP IoT -> Trusted`
- `DROP IoT -> Servers`
- `DROP IoT -> Cameras`
- `DROP Cameras -> Trusted`
- `DROP Cameras -> Servers`
- `DROP Cameras -> IoT`
- `DROP Legacy CIA -> Trusted`
- `DROP Legacy CIA -> Servers`
- `DROP Legacy CIA -> Cameras`
- `DROP Legacy CIA -> IoT`
Meaning:
- the core segmentation barriers between the restricted lanes and the rest of the network are not yet evidenced in the captured policy set
### Section H: Optional discovery exceptions
Correctly absent for now:
- no evidence of broad Google/cast discovery exception rules
- this is good; the design explicitly says these should only appear after real failure testing
## 4. Practical interpretation
If the captured baselines are still current, then the environment appears to be in this state:
1. The naming/object foundation is mostly there.
2. The network has at least one custom outbound-style policy.
3. The actual inter-VLAN enforcement plan is still largely unimplemented.
4. The current state is safer than random ad-hoc rules, but it is not yet the finished segmentation design.
## 5. Safe next implementation order
Before any live firewall apply, the safest order is:
1. Create the missing host groups
- `HOST-ADMIN-TRUSTED`
- `HOST-DNS`
- `HOST-NTP`
- `HOST-PROTECT-SERVICES`
- helper/exception groups as needed
2. Add the minimum safe rule skeleton first
- `ALLOW Established/Related`
- `DROP Invalid`
- management shield block set
- explicit Trusted admin -> Management allows
- Trusted -> Servers allow
3. Add the restricted-lane minimum-function rules
- DNS
- NTP
- outbound internet as appropriate
4. Add the broad internal deny matrix for Guest / IoT / Camera / Legacy CIA
5. Only after that, consider narrow discovery exceptions if the Google/cast pilot proves they are actually needed
## 6. What is safe to say right now
Accurate phrasing:
- firewall scaffolding exists
- the object/group layer is mostly staged
- a basic outbound custom policy exists
- the full inter-VLAN segmentation matrix is not yet fully implemented
Inaccurate phrasing to avoid:
- “the firewall is done”
- “inter-VLAN isolation is fully in place”
- “Legacy CIA is already fully quarantined by policy”
## 7. Recommended next operator action
Next safe action, still non-disruptive:
- define the missing host groups and map real devices/services into them on paper or in staging notes first
Next live-action phase after that:
- apply the minimum safe rule skeleton in a rollback-friendly order, validating management reachability after each step

View File

@@ -0,0 +1,249 @@
# UniFi Firewall Host-Group Membership Proposal
Purpose: propose concrete membership for the missing host/device groups referenced by the firewall design, using current repo documentation and the recent UniFi cleanup state. This is a planning artifact only; it does not apply live network changes.
Evidence used:
- `docs/architecture/SERVICES_DIRECTORY.md`
- `docs/architecture/NETWORKING_MODEL.md`
- `docs/servers/PLAUSIBLEDENABILITY.md`
- `docs/servers/SERENITY.md`
- `docs/servers/ROCINANTE.md`
- `pihole/README.md`
- `home/doris-dashboard/docs/unifi-client-cleanup-shortlist-2026-05-22.md`
- memory note: UniFi is `10.5.0.1`; PD is `10.5.30.6`; Serenity Pi-hole HA VIP is `10.5.30.53/24`
## Executive summary
These groups should be split into three confidence bands:
- High confidence: safe to define now from documented inventory
- Medium confidence: likely right, but validate in UniFi/UI before live enforcement
- Low confidence / leave empty for now: do not guess; create the group but keep it empty until a real dependent flow proves it is needed
## 1. Proposed group membership
### HOST-ADMIN-TRUSTED
Purpose:
- devices allowed to initiate management/admin traffic into the Management lane
Proposed members:
- Rocinante trusted endpoint/client
- John primary phone: `Pixel-9-Pro-XL`
- Optional: `Pixel-7` if you really want phone-based admin
Do NOT include by default:
- `FlyingDutchman`
- `steamdeck`
- `Valkyrie`
- random laptops/TVs/tablets just because they are on Trusted
Confidence:
- Medium
Reasoning:
- the cleanup shortlist says these human/operator devices are intentionally on Trusted
- Rocinante is the explicit operator station in the cutover docs
- the firewall design says this group should be small and deliberate
Implementation note:
- if UniFi requires IPs instead of clean client objects for this group, resolve the current IP/MACs from live client state before creating the actual group
### HOST-CORE-SERVICES
Purpose:
- core homelab service hosts on the Servers lane
Proposed members:
- PlausibleDeniability / PD -> `10.5.30.6`
- Serenity -> `10.5.30.5`
- N.O.M.A.D. -> `10.5.30.7`
- Rocinante -> `10.5.30.112`
Confidence:
- High
Reasoning:
- all four are documented infrastructure hosts
- these are the obvious server endpoints repeatedly referenced across the repo
### HOST-PROTECT-SERVICES
Purpose:
- target for camera/security devices that need to talk to the Protect/NVR side
Proposed members:
- UDM Pro / UniFi gateway-controller -> `10.5.0.1`
Confidence:
- Medium
Reasoning:
- the docs clearly identify `10.5.0.1` as the UDM Pro / controller
- the chimes and doorbell are UniFi Protect accessories
- no separate UNVR/NVR host is documented anywhere obvious in the repo inventory
Caution:
- verify in UniFi before hard enforcement whether Protect is actually hosted on the UDM Pro in this environment or whether there is another Protect endpoint not yet documented
### HOST-DNS
Purpose:
- approved DNS resolvers for restricted lanes
Proposed members:
- Pi-hole HA VIP -> `10.5.30.53`
- Optional explicit backing nodes if you want belt-and-suspenders:
- PD Pi-hole primary -> `10.5.30.6`
- NOMAD Pi-hole replica admin host -> `10.5.30.7`
Recommended practical membership:
- start with just `10.5.30.53`
Confidence:
- High for VIP
- Medium for adding the backing hosts directly
Reasoning:
- the repo explicitly calls `10.5.30.53` the VIP for client DNS
- using the VIP keeps the policy clean and decoupled from backend failover details
### HOST-NTP
Purpose:
- approved NTP targets for restricted lanes
Proposed members:
- leave empty for now if clients are intended to use public NTP directly
Alternative if you insist on local NTP later:
- add the actual documented local NTP server only after verifying one exists and is intended for clients
Confidence:
- Low / intentionally unresolved
Reasoning:
- the firewall design explicitly says this can be omitted if public NTP is used
- the repo docs do not currently provide a clear dedicated client-facing LAN NTP service
- the Pi-hole docs explicitly note Pi-hole NTP is disabled on PD because host `chronyd` owns UDP 123, but that alone is not enough proof that PD should become the universal client NTP target
Recommendation:
- for first-pass enforcement, model NTP as outbound internet allowed where needed rather than pretending a local NTP service is definitely part of the design
### HOST-IOT-HELPERS
Purpose:
- specific server-side helpers that IoT devices are allowed to contact
Proposed members for first pass:
- Home Assistant on PD -> `10.5.30.6` service port `8123`
- Kima Hub on PD -> `10.5.30.6` service port `3333`
Possible later additions only if proven necessary:
- any MQTT broker actually used by IoT devices
- any local appliance helper/integration endpoint that demonstrably breaks without local access
Confidence:
- Medium
Reasoning:
- Home Assistant and Kima Hub are the only clearly documented smart-home/helper services in the repo inventory
- these are plausible “approved server helpers” for IoT
- do not add Plex, Tautulli, or general app hosts here by default just because they exist
Caution:
- no explicit MQTT broker is clearly documented in the current inventory as a central IoT dependency; do not invent one into this group
### HOST-CAMERA-HELPERS
Purpose:
- server-side helpers cameras/security devices are allowed to contact beyond pure internet access
Proposed members:
- same initial target as HOST-PROTECT-SERVICES:
- UDM Pro / Protect endpoint -> `10.5.0.1`
Confidence:
- Medium
Reasoning:
- until a separate Protect/NVR host is documented, the safest concrete starting point is the documented UniFi gateway/controller
### HOST-LEGACY-EXCEPTIONS
Purpose:
- explicit ugly one-off quarantine exceptions for legacy devices
Proposed members:
- none initially; create the group empty
Confidence:
- High for “empty by default”
Reasoning:
- the design explicitly treats Legacy CIA as hospice, not production
- there is no documented exception that has already earned inclusion
- empty is safer than pretending one-offs are already justified
## 2. Port-group follow-up proposal
The firewall gap list noted two useful missing port groups.
### PORT-PROTECT
Proposed status:
- define later, only after verifying the actual required Protect ports for chime/doorbell traffic in this environment
Confidence:
- Low now
Reasoning:
- the repo docs do not yet give a trusted exact Protect port list for this design
- better to leave broad camera policy undone than to guess wrong and strand security devices
### PORT-CAST
Proposed status:
- do not define yet
Confidence:
- High for deferral
Reasoning:
- the design explicitly says cast/discovery rules should only appear after real failure testing
- wait for the Google/cast pilot
## 3. Suggested first-pass implementation set
If you want the cleanest minimal live enforcement pass later, the least-controversial groups to create/use first are:
1. `HOST-CORE-SERVICES`
- `10.5.30.5`
- `10.5.30.6`
- `10.5.30.7`
- `10.5.30.112`
2. `HOST-DNS`
- `10.5.30.53`
3. `HOST-ADMIN-TRUSTED`
- only the one or two devices John truly admins from
4. `HOST-PROTECT-SERVICES`
- `10.5.0.1` pending verification
5. `HOST-IOT-HELPERS`
- `10.5.30.6` only, if using Home Assistant / Kima Hub as the first-pass helper target
And leave these empty until proven:
- `HOST-NTP`
- `HOST-CAMERA-HELPERS` if different from Protect
- `HOST-LEGACY-EXCEPTIONS`
## 4. Validation questions before live rule apply
Before turning these into real enforced firewall objects, verify:
1. Which exact Trusted client(s) should truly admin Management?
2. Is Protect actually on the UDM Pro at `10.5.0.1`, or is there a separate undocumented host?
3. Do IoT devices need Home Assistant and/or Kima Hub locally right now, or can they live on cloud-only plus DNS/internet first?
4. Is there a real client-facing local NTP service, or should NTP just be allowed outbound?
5. Are there any Legacy CIA one-off exceptions that have actually earned existence? If not, keep that group empty.
## 5. Blunt recommendation
If we want a safe first real enforcement pass later:
- definitely create/use `HOST-CORE-SERVICES`, `HOST-DNS`, and a very small `HOST-ADMIN-TRUSTED`
- probably create `HOST-PROTECT-SERVICES` as `10.5.0.1` after one verification step
- treat `HOST-NTP`, `PORT-PROTECT`, and `PORT-CAST` as intentionally unresolved until verified
- keep `HOST-LEGACY-EXCEPTIONS` empty unless a specific ugly legacy device proves it needs one