From 982ddc0e8f4a2d599954c0ae0f158d5c56c9533d Mon Sep 17 00:00:00 2001 From: dohertj2 Date: Wed, 29 Apr 2026 09:00:06 -0400 Subject: [PATCH] Initial commit: home network inventory and runbooks --- .gitignore | 1 + CLAUDE.md | 26 +++++++++ desktop.md | 92 +++++++++++++++++++++++++++++++ docker.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ esxi.md | 122 +++++++++++++++++++++++++++++++++++++++++ ha.md | 62 +++++++++++++++++++++ ignition.md | 71 ++++++++++++++++++++++++ migratezwave.md | 79 +++++++++++++++++++++++++++ plex.md | 66 ++++++++++++++++++++++ raspi_zwave.md | 55 +++++++++++++++++++ truenas.md | 93 +++++++++++++++++++++++++++++++ unifi.md | 111 +++++++++++++++++++++++++++++++++++++ veeam.md | 63 +++++++++++++++++++++ ww.md | 76 ++++++++++++++++++++++++++ ww_gpu.md | 122 +++++++++++++++++++++++++++++++++++++++++ 15 files changed, 1181 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 desktop.md create mode 100644 docker.md create mode 100644 esxi.md create mode 100644 ha.md create mode 100644 ignition.md create mode 100644 migratezwave.md create mode 100644 plex.md create mode 100644 raspi_zwave.md create mode 100644 truenas.md create mode 100644 unifi.md create mode 100644 veeam.md create mode 100644 ww.md create mode 100644 ww_gpu.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6b130c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.claude/settings.local.json diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..4bddb10 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,26 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Purpose + +**netfix** is a diagnostic/debugging toolkit for troubleshooting network connectivity between VMs running on an ESXi hypervisor host and an external client, connected through Unifi network switches. + +## Environment Context + +- **Hypervisor**: VMware ESXi +- **Network infrastructure**: Ubiquiti Unifi switches +- **Debugging scope**: VM-to-external-client connectivity issues across the ESXi virtual switch and physical Unifi switch layers + +## Components + +- [TrueNAS Server](truenas.md) — NAS at 10.100.0.25 (management) / 10.50.0.x (storage), serves SMB and NFS +- [ESXi Host](esxi.md) — HP server at 10.2.0.12, ESXi 8.0.3, 8 VMs (7 powered on), access via `govc` only (not SSH). **Read esxi.md for credentials and connection details.** +- [Docker Server](docker.md) — Debian 13 at 10.100.0.35, Docker host for 21 containers (arr stack, Traefik, Semaphore/Ansible). **This is the local machine.** +- [Plex Server](plex.md) — Debian 11 at 10.100.0.24, Plex Media Server 1.43, NFS media from TrueNAS +- [Home Assistant](ha.md) — HAOS at 10.100.0.40, HA 2026.2.2, 2,411 entities, smart home automation. API access only (no SSH). +- [Ignition Gateway](ignition.md) — Debian 11 at 10.100.0.90, Ignition 8.3.3 (Maker), SCADA/IIoT platform with PostgreSQL 13 +- [Veeam Server](veeam.md) — Windows Server 2025 at 10.100.0.30, Veeam B&R 12.3, backup server. **Read veeam.md for credentials and connection details.** +- [Desktop](desktop.md) — Windows PC, dual-homed on LAN_100 (10.100.0.49) and DATA_50 (10.50.0.49) +- [Wonderware Dev VM](ww.md) — Windows 10 ESXi VM at 10.100.0.48, OpenSSH (passwordless) +- [Unifi Network](unifi.md) — UDM Pro gateway + USW Pro Aggregation central switch, API access via key diff --git a/desktop.md b/desktop.md new file mode 100644 index 0000000..89d9483 --- /dev/null +++ b/desktop.md @@ -0,0 +1,92 @@ +# Desktop (Windows PC) + +## Access + +- **Hostname**: DESKTOP-1BEK7OR +- **OS**: Windows 10 (PowerShell 5.1.19041.6456) +- **Credentials**: dohertj2 / Sonamu89 +- **Remote access**: SSH (passwordless), WinRM (fallback) + +### Running Commands + +```bash +# SSH (preferred — passwordless, supports interactive commands) +ssh dohertj2@10.100.0.49 "ipconfig /all" +ssh dohertj2@10.100.0.49 "powershell -Command 'Get-NetAdapter | Format-Table -AutoSize'" +``` + +WinRM is disabled (service stopped, startup type Disabled). + +## Network Interfaces + +### LAN — Intel X550-T2 (ifIndex 49) +- **MAC**: A0-36-9F-29-93-68 +- **Speed**: 10 Gbps (auto-negotiation) +- **IP**: 10.100.0.49 (static) +- **Netmask**: 255.255.255.0 +- **Gateway**: 10.100.0.1 +- **DNS**: 10.100.0.1 +- **MTU**: 1500 +- **Jumbo**: Disabled +- **Network profile**: "DOHERTY" (Public) +- **IPv4 connectivity**: Internet +- **Switch port**: USW Pro Aggregation port 19 (VLAN 100) +- **Advanced**: Flow control Rx+Tx, RSS 8 queues, all checksum/LSO offloads enabled + +### DATA — Intel X550-T2 #2 (ifIndex 50) +- **MAC**: A0-36-9F-29-93-6A +- **Speed**: 10 Gbps (auto-negotiation) +- **IP**: 10.50.0.49 (static) +- **Netmask**: 255.255.255.0 +- **Gateway**: none +- **DNS**: none (IPv4) +- **MTU**: 9000 +- **Jumbo**: 9014 bytes +- **Network profile**: "Unidentified network" (Public) +- **IPv4 connectivity**: LocalNetwork +- **Switch port**: USW Pro Aggregation port 20 (VLAN 50) +- **Advanced**: Flow control Rx+Tx, RSS 8 queues, all checksum/LSO offloads enabled + +### Other Adapters + +| Adapter | Status | IP | Notes | +|---------|--------|-----|-------| +| Wi-Fi (Intel AC 9260) | Disconnected | — | — | +| Tailscale Tunnel | Up | 100.95.148.91 | VPN, MTU 1280 | +| VMnet8 (VMware NAT) | Up | 192.168.124.1 | MTU 1500 | +| Ethernet (Realtek GbE) | Disabled | — | Onboard, unused | +| Ethernet 3 (Cisco AnyConnect) | Not Present | — | — | +| Ethernet 4 (IVPN TAP) | Not Present | — | — | + +## Routing + +Default route via LAN adapter: + +| Destination | Next Hop | Metric | Interface | +|-------------|----------|--------|-----------| +| 0.0.0.0/0 | 10.100.0.1 | 256 | LAN | +| 10.100.0.0/24 | on-link | 256 | LAN | +| 10.50.0.0/24 | on-link | 256 | DATA | +| 192.168.124.0/24 | on-link | 256 | VMnet8 | +| 100.x.x.x/32 (various) | on-link | 0 | Tailscale | + +## Firewall + +**All profiles disabled** (Domain, Private, Public). + +## SMB + +### Client Configuration +- **Multichannel**: enabled +- **Large MTU**: enabled +- **Bandwidth throttling**: enabled + +### Drive Mappings + +| Drive | Remote Path | VLAN | Status | +|-------|------------|------|--------| +| V: | \\\\10.50.0.25\benchmark | DATA (50) | OK | +| W: | \\\\10.50.0.25\Other | DATA (50) | OK | +| Z: | \\\\10.50.0.25\share | DATA (50) | OK | + +Drives mapped to TrueNAS DATA VLAN IP (10.50.0.25) for jumbo frame performance. SMB multichannel enabled on both LAN and DATA NICs (RSS enabled on both). diff --git a/docker.md b/docker.md new file mode 100644 index 0000000..2316995 --- /dev/null +++ b/docker.md @@ -0,0 +1,142 @@ +# Docker Server + +## Access + +- **Hostname**: DOCKER +- **FQDN**: DOCKER.dohertylan.com +- **IP**: 10.100.0.35 (LAN_100) / 10.50.0.35 (DATA_50) / 10.200.0.35 (IOT_200) +- **OS**: Debian 13 (Trixie) 13.3, kernel 6.12.69+deb13-amd64 +- **SSH**: `ssh dohertj2@10.100.0.35` (passwordless) — this is the local machine for Claude Code +- **Docker**: 29.2.1 +- **Docker Compose**: v5.0.2 + +## Hardware (VM on ESXi) + +- **CPU**: 22 vCPUs (Intel Xeon E5-2697 v4 @ 2.30GHz) +- **RAM**: 32 GB +- **Disk**: /dev/sda1 999 GB ext4 (930 GB free) + +## Network + +| Interface | MAC | IP | MTU | Port Group | +|-----------|-----|-----|-----|------------| +| ens192 | 00:0c:29:cf:bb:bb | 10.100.0.35/24 | 1500 | LAN_100 | +| ens256 | 00:0c:29:cf:bb:c5 | 10.50.0.35/24 | 9000 | DATA_50 | +| ens161 | 00:0c:29:cf:bb:cf | 10.200.0.35/24 | 1500 | IOT_200 | + +- **Default gateway**: 10.100.0.1 (via ens192) +- **DNS**: 10.100.0.1 +- **Domain**: dohertylan.com + +### Docker Networks + +| Network | Driver | +|---------|--------| +| traefik | bridge | +| semaphore_default | bridge | + +## NFS Mounts (via TrueNAS DATA_50) + +All mounts use NFS 4.2 with `nconnect=8,_netdev,nofail,x-systemd.automount`. + +| Mount Point | NFS Export | +|-------------|-----------| +| /mnt/share | 10.50.0.25:/mnt/mypool/share | +| /mnt/other | 10.50.0.25:/mnt/mypool/Other | + +## Reverse Proxy (Traefik) + +Traefik handles HTTPS ingress on ports 80/443. All services below are accessed via `*.dohertylan.com` through Traefik, with Authelia providing SSO/2FA. + +Cloudflare Companion auto-updates DNS records. + +## Docker Containers + +All 21 containers running. Most are on the `traefik` network. + +### Infrastructure + +| Container | Image | URL | Port | Purpose | +|-----------|-------|-----|------|---------| +| traefik | traefik:latest | traefik.dohertylan.com | 80, 443 | Reverse proxy | +| authelia | authelia/authelia:latest | auth.dohertylan.com | 9091 | SSO / 2FA | +| cloudflare-companion | tiredofit/traefik-cloudflare-companion:latest | — | — | Auto DNS updates | +| portainer | portainer/portainer-ce:latest | portainer.dohertylan.com | 9000, 9443 | Docker management UI | +| homepage | ghcr.io/gethomepage/homepage:latest | home.dohertylan.com | 3000 | Dashboard | +| uptime-kuma | louislam/uptime-kuma:latest | uptime.dohertylan.com | 3001 | Uptime monitoring | + +### Media Management (Arr Stack) + +| Container | Image | URL | Port | Purpose | +|-----------|-------|-----|------|---------| +| sonarr | lscr.io/linuxserver/sonarr:latest | sonarr.dohertylan.com | 8989 | TV show management | +| radarr | lscr.io/linuxserver/radarr:latest | radarr.dohertylan.com | 7878 | Movie management | +| whisparr | ghcr.io/hotio/whisparr:v3 | whisp.dohertylan.com | 6969 | Adult content management | +| prowlarr | lscr.io/linuxserver/prowlarr:latest | prowlarr.dohertylan.com | 9696 | Indexer manager | +| seerr | ghcr.io/seerr-team/seerr:latest | requests.dohertylan.com | 5055 | Media request UI | +| profilarr | santiagosayshey/profilarr:latest | profilarr.dohertylan.com | 6868 | Quality profile sync | +| tautulli | ghcr.io/tautulli/tautulli:latest | tautulli.dohertylan.com | 8181 | Plex analytics | + +### Downloads + +| Container | Image | URL | Port | Purpose | +|-----------|-------|-----|------|---------| +| nzbget | nzbgetcom/nzbget:latest | nzb.dohertylan.com | 6789 | Usenet downloader | +| gluetun | qmcgaw/gluetun:latest | — | 6881 | VPN container | +| qbittorrent | linuxserver/qbittorrent:latest | — (via gluetun) | — | Torrent client (VPN) | + +### Utilities + +| Container | Image | URL | Port | Purpose | +|-----------|-------|-----|------|---------| +| microbin | danielszabo99/microbin:latest | bin.dohertylan.com | 8080 | Pastebin | +| ittools | corentinth/it-tools:latest | ittools.dohertylan.com | 80 | IT utilities | +| stash | stashapp/stash:latest | stash.dohertylan.com | 9999 | Media organizer | +| ilo-fan | ilo_fan-ilo-fan | fan.dohertylan.com | 8000 | iLO fan control | + +### Automation + +| Container | Image | URL | Port | Purpose | +|-----------|-------|-----|------|---------| +| semaphore | semaphoreui/semaphore:latest | http://10.100.0.35:3000 | 3000 | Ansible UI | + +### lmxopcua (carry `project=lmxopcua` label) + +Stacks under `/opt/otopcua-*/` migrated from the Wonderware dev VM (DESKTOP-6JL3KKO) on 2026-04-28. Discoverable via `docker ps --filter label=project=lmxopcua`. Brought up on demand by the developer from WW via `lmxopcua-fix.ps1` (in `~/bin/` on WW), which SSHes here and runs compose. + +| Container/Stack | Image | Port | Purpose | +|---|---|---|---| +| otopcua-mssql (always-on) | mcr.microsoft.com/mssql/server:2022-latest | 14330→1433 | Central config DB for OtOpcUa v2 | +| otopcua-pymodbus-* | otopcua-pymodbus:3.13.0 (local build) | 5020 | Modbus driver test fixture (5 profiles) | +| otopcua-ab-server-* | otopcua-ab-server:libplctag-release (local build) | 44818 | AB CIP driver test fixture (4 profiles) | +| otopcua-python-snap7-* | otopcua-python-snap7:1.0 (local build) | 1102 | S7 driver test fixture | +| otopcua-opc-plc | mcr.microsoft.com/iotedge/opc-plc:2.14.10 | 50000 | OPC UA reference simulator | + +## Semaphore / Ansible + +- **Semaphore UI**: http://10.100.0.35:3000 +- **Data**: `/opt/semaphore/data/database.sqlite` +- **Compose file**: `/opt/semaphore/docker-compose.yml` + +### Ansible Playbook + +- **Location**: `/home/dohertj2/playbook/` +- **Main playbook**: `/home/dohertj2/playbook/site.yml` +- **Roles**: `/home/dohertj2/playbook/roles/` +- **Import tasks**: `/home/dohertj2/playbook/import/` (radarr, sonarr, nzbget, prowlarr, docker-compose-arr) +- **iLO fan playbook**: `/home/dohertj2/playbook/ilo_fan/` + +## Docker Compose Locations + +All compose files are under `/opt//docker-compose.yml`: + +``` +/opt/traefik/ /opt/portainer/ /opt/homepage/ +/opt/sonarr/ /opt/radarr/ /opt/whisparr/ +/opt/prowlarr/ /opt/seerr/ /opt/profilarr/ +/opt/tautulli/ /opt/nzbget/ /opt/vpn_downloads/ +/opt/uptime_kuma/ /opt/stash/ /opt/utilities/ +/opt/semaphore/ /opt/ilo_fan/ +/opt/otopcua-mssql/ /opt/otopcua-modbus/ /opt/otopcua-abcip/ +/opt/otopcua-s7/ /opt/otopcua-opcuaclient/ +``` diff --git a/esxi.md b/esxi.md new file mode 100644 index 0000000..ce23692 --- /dev/null +++ b/esxi.md @@ -0,0 +1,122 @@ +# ESXi Host + +## Access + +- **IP**: 10.2.0.12 (VLAN 0 / DEFAULT, management) +- **Version**: VMware ESXi 8.0.3 build-24280767 (Update 3, Patch 35) +- **Credentials**: govc / Tn9.xKw-m4Vp (Administrator role) +- **API access via govc**: + ```bash + GOVC_URL=https://10.2.0.12/sdk GOVC_USERNAME=govc GOVC_PASSWORD='Tn9.xKw-m4Vp' GOVC_INSECURE=true govc + ``` +- **Do NOT use SSH** — ESXi keyboard-interactive auth is unreliable from this machine; use `govc` exclusively +- **Hardware**: HP, 2x Intel Xeon E5-2697 v4 (36 logical CPUs @ 2.3GHz), 256GB RAM +- **Boot time**: 2025-09-22 + +## Physical NICs + +| NIC | Driver | Speed | Link | MTU | MAC | Description | +|-----|--------|-------|------|-----|-----|-------------| +| vmnic0 | igbn | — | **Down** | 1500 | ec:b1:d7:82:3b:40 | Intel 1Gb 2-port 361i | +| vmnic2 | ixgben | — | **Down** (admin down) | 1500 | 48:df:37:07:a9:6c | Intel 82599 10GbE | +| vmnic3 | ixgben | 10 Gbps | Up | 1500 | 48:df:37:07:a9:6d | Intel 82599 10GbE | +| vmnic4 | nmlx5_core | 25 Gbps | Up | 1500 | b8:83:03:60:e4:e0 | Mellanox ConnectX-4 Lx | +| vmnic5 | nmlx5_core | 25 Gbps | Up | 9000 | b8:83:03:60:e4:e1 | Mellanox ConnectX-4 Lx | + +**Active uplinks**: vmnic3 (unused — no vSwitch), vmnic4 (vSwitch0), vmnic5 (jumboFrameSwitch) + +## vSwitches + +### vSwitch0 (vmnic4 — 25Gbps Mellanox, MTU 1500) + +Carries VLAN-tagged traffic for management, LAN, IoT, and guest networks. + +| Port Group | VLAN ID | Active Ports | Subnet | +|------------|---------|--------------|--------| +| DEFAULT_0 | 0 (untagged) | 1 | 10.2.0.0/24 (ESXi mgmt) | +| MGMT_1 | 0 (untagged) | 0 | — | +| GUEST_3 | 3 | 0 | — | +| LAN_100 | 100 | 7 | 10.100.0.0/24 | +| IOT_200 | 200 | 1 | 10.200.0.0/24 | + +### jumboFrameSwitch (vmnic5 — 25Gbps Mellanox, MTU 9000) + +Dedicated storage network with jumbo frames. Switch port 32 is configured as a trunk (`forward=all`, MGMT native) so VLAN 50 frames arrive tagged, matching the DATA_50 port group's VLAN ID. + +| Port Group | VLAN ID | Active Ports | Subnet | +|------------|---------|--------------|--------| +| DATA_50 | 50 | 4 | 10.50.0.0/24 | + +All port groups: promiscuous mode=No, forged transmits=No, MAC changes=No. + +## VMkernel Interface + +| Interface | IP | Netmask | Portgroup | MAC | Stack | +|-----------|-----|---------|-----------|-----|-------| +| vmk0 | 10.2.0.12 | 255.255.255.0 | DEFAULT_0 | 48:df:37:07:a9:6d | defaultTcpipStack | + +- **Default gateway**: 10.2.0.1 +- **DNS search**: localdomain (no DNS servers configured) + +## Virtual Machines + +### Powered On + +| VM | Guest OS | CPU | RAM | LAN_100 IP | DATA_50 IP | Other IPs | +|----|----------|-----|-----|-----------|-----------|-----------| +| TrueNAS | Debian 12 | 16 | 128GB | 10.100.0.25 | 10.50.0.26 | +secondary IPs on both | +| DOCKER | Debian 12 | 22 | 32GB | 10.100.0.35 | 10.50.0.35 | Docker bridges: 172.18.0.1, 172.19.0.1 | +| Veeam | Win Server 2025 | 8 | 8GB | 10.100.0.30 | 10.50.0.32 | — | +| HA | Oracle Linux 6 | 16 | 16GB | 10.100.0.40 | — | Docker bridge: 172.30.32.1 | +| Plex | Debian 11 | 8 | 8GB | 10.100.0.24 | 10.50.0.31 | — | +| Ignition | Debian 11 | 4 | 16GB | 10.100.0.90 | — | IOT_200 NIC connected but no IP | +| DevVM | Win 10 | 8 | 16GB | 10.100.0.47 | — | IOT_200: 10.200.0.47 | + +### Powered Off + +| VM | Guest OS | CPU | RAM | Port Groups | +|----|----------|-----|-----|-------------| +| DevServer | Win Server 2022 | 12 | 32GB | LAN_100 | + +## Per-VM Network Detail + +### TrueNAS +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 1 | 00:0c:29:bb:71:43 | LAN_100 | 10.100.0.25, .26, .27 | +| Adapter 2 | 00:0c:29:bb:71:4d | DATA_50 | 10.50.0.25, .26, .27, .28 | + +### DOCKER +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 1 | 00:0c:29:cf:bb:bb | LAN_100 | 10.100.0.35 | +| Adapter 2 | 00:0c:29:cf:bb:c5 | DATA_50 | 10.50.0.35 | + +### Veeam +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 1 | 00:0c:29:33:76:a5 | DATA_50 | 10.50.0.32 | +| Adapter 2 | 00:0c:29:33:76:af | LAN_100 | 10.100.0.30 | + +### HA (Home Assistant) +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 2 | 00:0c:29:f3:f3:5b | LAN_100 | 10.100.0.40 | + +### Plex +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 1 | 00:0c:29:4a:ef:3d | LAN_100 | 10.100.0.24 | +| Adapter 2 | 00:0c:29:4a:ef:47 | DATA_50 | 10.50.0.31 | + +### Ignition +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 1 | 00:0c:29:87:5f:f8 | LAN_100 | 10.100.0.90 | +| Adapter 2 | 00:0c:29:87:5f:02 | IOT_200 | (no IP, disconnected) | + +### DevVM +| NIC | MAC | Port Group | IPs | +|-----|-----|------------|-----| +| Adapter 1 | 00:0c:29:5c:f9:f7 | IOT_200 | 10.200.0.47 | +| Adapter 2 | 00:0c:29:5c:f9:01 | LAN_100 | 10.100.0.47 | diff --git a/ha.md b/ha.md new file mode 100644 index 0000000..a881fc9 --- /dev/null +++ b/ha.md @@ -0,0 +1,62 @@ +# Home Assistant + +## Access + +- **Hostname**: HA +- **IP**: 10.100.0.40 (LAN_100) +- **OS**: Home Assistant OS (reports as Oracle Linux 6 to ESXi) +- **Web UI**: http://10.100.0.40:8123 / https://ha.dohertylan.com +- **SSH**: Not available (Home Assistant OS — no direct shell access from this machine) +- **API Token**: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3MDU4MDcwNWNjOTI0MmE5YTg1OTJmMWRmMWY0YTk5NSIsImlhdCI6MTc3MTE4NzM0NCwiZXhwIjoyMDg2NTQ3MzQ0fQ.RXzwb_xu9TQyIE2QABRJP5nXtb6FDyHY7Phu3vFJecw` + +## Hardware (VM on ESXi) + +- **CPU**: 16 vCPUs (Intel Xeon E5-2697 v4 @ 2.30GHz) +- **RAM**: 16 GB (12.5 GB host usage, ~1.1 GB guest active) +- **Disk**: 128 GB (AHCI/SATA, datastore NVME_1) +- **Boot time**: 2026-02-17 + +## Network + +| NIC | Type | MAC | Port Group | IP | +|-----|------|-----|------------|-----| +| ethernet-1 | vmxnet3 | 00:0c:29:f3:f3:5b | LAN_100 | 10.100.0.40/24 | + +- Single NIC (LAN_100 only, no DATA_50) + +## Home Assistant + +- **Version**: 2026.2.2 +- **State**: RUNNING +- **Location**: Syracuse, IN (41.41, -85.72) +- **Time zone**: America/New_York +- **Units**: Imperial (US) + +### Scale + +- **2,411 entities** across 76 service domains +- Top entity types: sensor (746), number (285), switch (277), button (228), binary_sensor (219), select (157), device_tracker (110), light (97) + +### Key Integrations + +| Category | Integrations | +|----------|-------------| +| **Z-Wave / Zigbee / Matter** | zwave_js, matter | +| **MQTT / ESPHome / Tasmota** | mqtt, esphome, tasmota | +| **WiFi Devices** | shelly, yolink, ac_infinity, flair, midea_dehumidifier_lan, govee_ble | +| **Appliances** | ge_home, roborock | +| **Media** | sonos, apple_tv, cast, harmony, webostv | +| **Network / Monitoring** | unifi, truenas, iotawatt, brother, ipp | +| **Protocols** | homekit, homekit_controller, modbus, bthome, ibeacon, oralb | +| **Voice / AI** | alexa, google_assistant, anthropic, openai_conversation, wyoming | +| **Other** | hacs, cloud, go2rtc, droplet, isy994 | + +### Automations + +- 23 automations configured + +## Notes + +- Home Assistant OS manages its own Docker containers internally — the Docker bridge (172.30.32.1) shown in ESXi docs is internal to HAOS +- govc guest operations don't work (HAOS doesn't use standard Linux auth) +- Backed up by Veeam via "Backup VMs" job diff --git a/ignition.md b/ignition.md new file mode 100644 index 0000000..ee6a7d5 --- /dev/null +++ b/ignition.md @@ -0,0 +1,71 @@ +# Ignition Gateway Server + +## Access + +- **Hostname**: Ignition +- **IP**: 10.100.0.90 (LAN_100) +- **OS**: Debian 11 (Bullseye), kernel 5.10.0-26-amd64 +- **SSH**: `ssh dohertj2@10.100.0.90` (passwordless) +- **Web UI**: http://10.100.0.90:8088 +- **HTTPS UI**: https://10.100.0.90:8043 +- **Designer Launcher**: via gateway web UI + +## Hardware (VM on ESXi) + +- **CPU**: 4 vCPUs (Intel Xeon E5-2697 v4 @ 2.30GHz) +- **RAM**: 16 GB +- **Disk**: 512 GB (PVSCSI, datastore NVME_1) +- **Boot time**: 2026-02-17 + +## Network + +| NIC | Type | MAC | Port Group | IP | MTU | +|-----|------|-----|------------|-----|-----| +| ethernet-0 (ens192) | vmxnet3 | 00:0c:29:87:5f:f8 | LAN_100 | 10.100.0.90/24 | 1500 | +| ethernet-1 | vmxnet3 | 00:0c:29:87:5f:02 | IOT_200 | (no IP, disconnected) | — | + +- **Default gateway**: 10.100.0.1 (via LAN_100) + +## Ignition Platform + +- **Product**: Ignition by Inductive Automation +- **Version**: 8.3.3 +- **Edition**: Maker +- **Java Runtime**: 17.0.17 +- **State**: RUNNING +- **Redundancy**: Independent (Active, Good) + +## MQTT Engine + +- **Module**: MQTT Engine (Cirrus Link) +- **Broker**: Home Assistant Mosquitto at `tcp://10.100.0.40:1883` +- **Credentials**: username `ignition` (HA local-only user) +- **Client ID**: `ignition-gateway` +- **Namespace**: `homeassistant/sensor/#` (root folder: `Home Assistant`) + +### Tags + +| Tag Path | Source Topic | Value | +|----------|-------------|-------| +| `[MQTT Engine]/Home Assistant/.../PrefilterFlowRate/state` | `homeassistant/sensor/droplet_prefilter_flow_rate/state` | gal/min | +| `[MQTT Engine]/Home Assistant/.../PrefilterDailyUsage/state` | `homeassistant/sensor/droplet_daily_water_usage/state` | gal | +| `[MQTT Engine]/Home Assistant/.../PrefilterMonthlyUsage/state` | `homeassistant/sensor/droplet_monthly_water_usage/state` | gal | + +## Database + +- **PostgreSQL 13** running locally (localhost:5432) +- User: dohertj2, database: postgres + +## Key Services + +| Service | Port | Protocol | +|---------|------|----------| +| Ignition Gateway (HTTP) | 8088 | HTTP | +| Ignition Gateway (HTTPS) | 8043 | HTTPS | +| PostgreSQL | 5432 | TCP (local) | +| SSH | 22 | TCP | + +## Notes + +- IOT_200 NIC is connected at the VM level but has no IP configured in the guest — intended for future IoT device communication +- Ignition Maker edition is free for non-commercial use, limited to 1 project diff --git a/migratezwave.md b/migratezwave.md new file mode 100644 index 0000000..af6cfc0 --- /dev/null +++ b/migratezwave.md @@ -0,0 +1,79 @@ +# Migrate Z-Wave JS from Raspberry Pi to Home Assistant + +## Context + +Z-Wave JS UI currently runs on a Raspberry Pi (10.200.0.190) as a Docker container, connecting to the Z-Net G8 controller at `tcp://10.200.0.106:2001`. Home Assistant then connects to the Raspi's websocket on port 3000. This adds an unnecessary hop and dependency on the Raspi. Since the Z-Net G8 is network-based, HA can connect to it directly. + +**Current**: HA → ws:3000 → Raspi (Z-Wave JS UI Docker) → tcp:2001 → Z-Net G8 +**Target**: HA → Z-Wave JS add-on (local) → tcp:2001 → Z-Net G8 + +## Current State + +- **219 Z-Wave entities** in HA +- **~23 Z-Wave nodes** with custom names (DownstairsBathroomFan, GarageSensor1, etc.) +- **Security keys** (S0, S2 Auth/Unauth/Access Control, LR) configured in Z-Wave JS UI +- Device pairings stored in Z-Net G8 NVM (persist regardless of software change) +- Raspi also runs: zigbee2mqtt, portainer_agent, ouroboros (these stay on the Raspi) + +## Recommended Approach: Z-Wave JS UI Add-on on HAOS + +Install the **Z-Wave JS UI community add-on** on HAOS rather than the official Z-Wave JS add-on. Reasons: +- Same software as current setup → minimal risk +- Keeps the full web UI for network management +- HomeSeer docs specifically recommend Z-Wave JS UI for Z-Net controllers +- Security keys and node names can be migrated directly + +## Steps + +### 1. Backup current Z-Wave JS UI on Raspi +- Create NVM backup from the Z-Wave JS UI web interface (http://10.200.0.190:8091) +- Copy the store directory from the Raspi container: `sudo docker exec zwavejs2mqtt tar czf /tmp/zwave-store-backup.tar.gz /usr/src/app/store/` +- Copy backup locally: `scp dohertj2@10.200.0.190:/tmp/zwave-store-backup.tar.gz ./` +- Save the settings.json (contains security keys and TCP port config) + +### 2. Stop Z-Wave JS UI on Raspi +- `ssh dohertj2@10.200.0.190 "sudo docker stop zwavejs2mqtt"` +- This releases the TCP connection to the Z-Net G8 (only one client can hold it) + +### 3. Install Z-Wave JS UI add-on on HAOS +- Via HA web UI: Settings → Add-ons → Add-on Store → search "Z-Wave JS UI" (community add-on) +- OR via API if possible: add the community add-on repository and install + +### 4. Configure the add-on +- Set serial port to `tcp://10.200.0.106:2001` +- Enter the existing security keys: + - S2_Unauthenticated: `015BD790CCDB08172CBD12754C73E4D3` + - S2_AccessControl: `B3F99B99EE958BFAE813A84FD3586E2A` + - S0_Legacy: `FBF63F5E6515286C3AB8CC9E5F275B46` + - S2_Authenticated: `67E9ECD830733A1E1BEB22DC0EAA2739` + - S2_Authenticated_LR: `2176EE246C67320A42F2C0A23932E9B5` + - S2_AccessControl_LR: `E534F94FCD0BE8B42F056F2F3548002E` +- Start the add-on + +### 5. Reconfigure HA Z-Wave JS integration +- Remove the current zwave_js integration (pointing to ws://10.200.0.190:3000) +- Re-add it pointing to the local add-on's websocket (ws://localhost:3000 or the add-on's internal URL) +- Verify all 219 entities are rediscovered with correct names/device assignments + +### 6. Verify +- Check all Z-Wave nodes are online in the Z-Wave JS UI add-on +- Confirm entity count matches (~219) +- Test a few devices (turn a light on/off, check a sensor reading) +- Verify automations that use Z-Wave devices still work + +### 7. Cleanup +- Remove the zwavejs2mqtt container from the Raspi: `sudo docker rm zwavejs2mqtt` +- Update `raspi_zwave.md` to reflect new architecture + +## Risk Mitigation + +- **Rollback**: If anything goes wrong, stop the HA add-on, restart the Raspi container, and re-point the integration back +- **Entity IDs**: Removing and re-adding the integration may change entity IDs. HA should re-discover them with the same unique IDs from Z-Wave JS, but automations/dashboards may need updating if not +- **Cross-VLAN**: HA (10.100.0.40, VLAN 100) must be able to reach Z-Net G8 (10.200.0.106, VLAN 200) on TCP port 2001 — confirmed allowed + +## Verification + +1. Entity count: `curl -s http://10.100.0.40:8123/api/template -d '{"template":"{{ integration_entities(\"zwave_js\") | list | length }}"}' ` should return ~219 +2. Z-Wave JS UI web interface accessible from HA add-on +3. Test device control via HA +4. Check HA logs for Z-Wave errors diff --git a/plex.md b/plex.md new file mode 100644 index 0000000..ecbfd8d --- /dev/null +++ b/plex.md @@ -0,0 +1,66 @@ +# Plex Media Server + +## Access + +- **Hostname**: plex +- **FQDN**: plex.lan.dohertylan.com +- **IP**: 10.100.0.24 (LAN_100) / 10.50.0.31 (DATA_50) +- **OS**: Debian 11 (Bullseye), kernel 5.10.0-11-amd64 +- **SSH**: `ssh dohertj2@10.100.0.24` (passwordless) +- **Web UI**: http://10.100.0.24:32400/web + +## Hardware (VM on ESXi) + +- **CPU**: 8 vCPUs (Intel Xeon E5-2697 v4 @ 2.30GHz) +- **RAM**: 7.8 GB +- **Disk**: /dev/sda1 125 GB ext4 (80 GB free) + +## Network + +| Interface | MAC | IP | MTU | Port Group | +|-----------|-----|-----|-----|------------| +| ens192 | 00:0c:29:4a:ef:3d | 10.100.0.24/24 | 1500 | LAN_100 | +| ens224 | 00:0c:29:4a:ef:47 | 10.50.0.31/24 | 9000 | DATA_50 | + +- **Default gateway**: 10.100.0.1 (via ens192) +- **DNS**: 10.100.0.1 +- **Domain**: lan.dohertylan.com + +## Plex Media Server + +- **Version**: 1.43.0.10492-121068a07 +- **Service**: `plexmediaserver.service` — enabled, active (running) +- **Run user**: plex +- **Data dir**: `/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/` + +## Auto Updates + +Plex is updated automatically via the **official Plex apt repository** and Debian's built-in `apt-daily-upgrade.timer`. + +- **Repo**: `deb [signed-by=/etc/apt/keyrings/plexmediaserver.v2.gpg] https://repo.plex.tv/deb/ public main` +- **Sources list**: `/etc/apt/sources.list.d/plexmediaserver.list` +- **GPG key**: `/etc/apt/keyrings/plexmediaserver.v2.gpg` (PlexSign.v2.key) +- **Update mechanism**: `apt-daily.timer` fetches package lists, `apt-daily-upgrade.timer` installs upgrades (both run daily via systemd) + +Previously used the third-party [plexupdate](https://github.com/mrworf/plexupdate) script (`/opt/plexupdate/plexupdate.sh` via `/etc/cron.daily/plexupdate`), which downloaded `.deb` files directly from plex.tv. This was removed on 2026-03-13 in favor of the official apt repo after Plex announced deprecation of the old update method. + +## NFS Media Mounts (via TrueNAS DATA_50 network) + +All mounts use NFS 4.2 with `nconnect=4,async,_netdev,nofail,x-systemd.automount`. + +| Mount Point | NFS Export | +|-------------|-----------| +| /mnt/nfs/Movies | truenas-nfs:/mnt/mypool/share/Media/Movies | +| /mnt/nfs/TV | truenas-nfs:/mnt/mypool/share/Media/TV | +| /mnt/nfs/Anime | truenas-nfs:/mnt/mypool/share/Media/Anime | + +`truenas-nfs` resolves via `/etc/hosts` to multiple TrueNAS DATA_50 IPs (10.50.0.25–28) for NFS multipathing. + +## Host Aliases (/etc/hosts) + +| IP | Hostname | +|----|----------| +| 10.50.0.25 | nfs1, truenas-nfs | +| 10.50.0.26 | nfs2, truenas-nfs | +| 10.50.0.27 | nfs3, truenas-nfs | +| 10.50.0.28 | nfs4, truenas-nfs | diff --git a/raspi_zwave.md b/raspi_zwave.md new file mode 100644 index 0000000..902a54f --- /dev/null +++ b/raspi_zwave.md @@ -0,0 +1,55 @@ +# Z-Wave Infrastructure + +## Architecture + +``` +HA (10.100.0.40) --ws:3000--> Raspberry Pi (10.200.0.190) --tcp:2001--> Z-Net G8 (10.200.0.106) + (Z-Wave JS UI) (Z-Wave radio controller) +``` + +## Z-Net G8 (Z-Wave Controller) + +- **Hostname**: Z-Net-G8 +- **IP**: 10.200.0.106 (IOT_200, VLAN 200) +- **MAC**: 02:53:ec:d0:de:dd +- **Manufacturer**: HomeSeer Technologies +- **Role**: Z-Wave radio controller (Node 1), serial-over-TCP on port 2001 + +## Raspberry Pi (Z-Wave JS UI Host) + +- **Hostname**: zwave +- **IP**: 10.200.0.190 (IOT_200, VLAN 200) +- **MAC**: e4:5f:01:02:3c:26 +- **Hardware**: Raspberry Pi (Raspberry Pi Trading Ltd) +- **SSH**: `ssh dohertj2@10.200.0.190` (passwordless) +- **Web UI**: http://10.200.0.190:8091 +- **Z-Wave JS websocket**: ws://10.200.0.190:3000 + +### Docker Containers + +| Container | Image | Ports | +|-----------|-------|-------| +| zwavejs2mqtt | zwavejs/zwave-js-ui:latest | 3000 (websocket), 8091 (web UI) | +| zigbee2mqtt | koenkk/zigbee2mqtt:latest | — | +| portainer_agent | portainer/agent:2.21.5 | 9001 | +| ouroboros | pyouroboros/ouroboros | — | + +### Z-Wave JS Config + +- **Serial port**: `tcp://10.200.0.106:2001` (Z-Net G8 over network) +- **Z-Wave region**: 1 (US) +- **Server port**: 3000 (websocket for HA) +- **Status**: ready + +## Home Assistant Integration + +- **Integration**: zwave_js +- **Connects to**: ws://10.200.0.190:3000 +- **Node 1**: HomeSeer Z-Wave Shield with External Antenna (Z-Net G8) + +## Notes + +- Both devices sit on the IoT VLAN (10.200.0.0/24) +- HA connects cross-VLAN (LAN_100 -> IOT_200) to the Raspi websocket +- The Raspi also runs Zigbee2MQTT (separate Zigbee network) +- Tracked by Unifi as device_tracker.zwave (Raspi) and device_tracker.z_net_g8 (controller) diff --git a/truenas.md b/truenas.md new file mode 100644 index 0000000..58a8f3f --- /dev/null +++ b/truenas.md @@ -0,0 +1,93 @@ +# TrueNAS Server + +## Access + +- **Hostname**: nas.dohertylan.com +- **Version**: TrueNAS 25.04.2.6 (Electric Eel / Linux-based) +- **SSH**: `ssh truenas_admin@10.100.0.25` (passwordless) +- **Web UI**: https://10.100.0.25 (ports 80/443 listening) +- **Domain**: dohertylan.com +- **DNS**: 10.100.0.1 + +## Network Interfaces + +### ens224 — Management / General (10.100.0.0/24) +- **MTU**: 1500 +- **IPs**: 10.100.0.25, .26, .27 +- **Default gateway**: 10.100.0.1 +- **Services**: SMB (445/139), WS-Discovery (5357), SSH (22), HTTP/S (80/443) +- **No NFS on this interface** — NFS (2049) does not bind to 10.100.0.x addresses + +### ens256 — Storage / High-speed (10.50.0.0/24) +- **MTU**: 9000 (jumbo frames) +- **IPs**: 10.50.0.25, .26, .27, .28 +- **Services**: SMB (445/139), NFS (2049) +- **No default route** — this is a dedicated storage network + +## ZFS Pools + +| Pool | Size | Used | Free | Health | +|------|------|------|------|--------| +| mypool | 175T | 83.5T | 91.2T | **DEGRADED** | +| SSD_Pool | 2.91T | 3.01G | 2.90T | ONLINE | +| boot-pool | 15G | 11.6G | 3.40G | ONLINE | + +**Note**: `mypool` is in DEGRADED state. + +### Key Datasets + +| Dataset | Mountpoint | Used | +|---------|------------|------| +| mypool | /mnt/mypool | 60.7T (33.5T direct) | +| mypool/veeam | /mnt/mypool/veeam | 26.5T | +| SSD_Pool/benchmark | /mnt/SSD_Pool/benchmark | 3.00G | + +`/mnt/mypool/share` and `/mnt/mypool/Other` are directories within the `mypool` dataset (not child datasets). + +## SMB Shares + +- **Workgroup**: DOHERTYLAN +- **NetBIOS name**: NAS +- **Multichannel**: enabled +- **Bind interfaces**: all IPs on both subnets + loopback +- **NTLMv1**: disabled (`ntlm auth = False`) +- **Guest**: disabled on all shares (`guest ok = False`) + +| Share | Path | Notes | +|-------|------|-------| +| share | /mnt/mypool/share | Oplocks disabled, performance-tuned (aio 16K, max_xmit 64K) | +| Other | /mnt/mypool/Other | "Other files", POSIX locking off | +| benchmark | /mnt/SSD_Pool/benchmark | On SSD pool, io_uring sqpoll enabled, aio 16K | + +### SMB Users + +| User | UID | Full Name | +|------|-----|-----------| +| dohertj2 | 1000 | Joseph Doherty | +| homero | 3001 | Home RO | + +## NFS Exports + +| Export | Allowed Clients | Squash | anonuid/gid | +|--------|----------------|--------|-------------| +| /mnt/mypool/share | * (all) | all_squash | 1000/0 | +| /mnt/mypool/Other | * (all) | all_squash | 1000/0 | +| /mnt/SSD_Pool/benchmark | * (all) | all_squash | 1000/1000 | +| /mnt/mypool/veeam | 10.50.0.0/24 only | root (anonuid=0) | 0/— | + +All exports use `sec=sys` (AUTH_SYS, no Kerberos). + +**Important**: NFS (port 2049) only listens on 10.50.0.x addresses. NFS is not reachable via the 10.100.0.0/24 network. + +## Filesystem ACLs + +| Path | Owner | Group | Permissions | +|------|-------|-------|-------------| +| /mnt/mypool/share | dohertj2 | root | 755 | +| /mnt/mypool/Other | dohertj2 | dohertj2 | 755 | +| /mnt/SSD_Pool/benchmark | dohertj2 | dohertj2 | 777 | +| /mnt/mypool/veeam | root | root | 755 | + +## Firewall + +No firewall rules — iptables INPUT/OUTPUT/FORWARD all ACCEPT. No nftables rules. diff --git a/unifi.md b/unifi.md new file mode 100644 index 0000000..9057cb8 --- /dev/null +++ b/unifi.md @@ -0,0 +1,111 @@ +# Unifi Network + +## Access + +- **Controller**: UDM Pro at 10.100.0.1 (Network Application v10.1.85) +- **API key**: oGFBSgxySOPPiwHj82F314h1T2RHY6OO +- **Site ID**: 88f7af54-98f8-306a-a1c7-c9349722b1f6 (Default) +- **API reference**: https://beez.ly/unifi-apis/network-10.1.85.json + +### API Usage + +```bash +# v1 integration API +curl -sk -H "X-API-KEY: oGFBSgxySOPPiwHj82F314h1T2RHY6OO" \ + 'https://10.100.0.1/proxy/network/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/' + +# Legacy stat API (more detailed port/device data) +curl -sk -H "X-API-KEY: oGFBSgxySOPPiwHj82F314h1T2RHY6OO" \ + 'https://10.100.0.1/proxy/network/api/s/default/' +``` + +Key legacy endpoints: `stat/device` (full port tables), `rest/networkconf` (network/VLAN definitions). + +## Networks / VLANs + +| Name | VLAN ID | Subnet | Gateway | DHCP | Purpose | +|------|---------|--------|---------|------|---------| +| MGMT | untagged | 10.2.0.0/24 | 10.2.0.1 | Yes | Management (all Unifi devices) | +| LAN | 100 | 10.100.0.0/24 | 10.100.0.1 | Yes | Primary VM/client network | +| DATA | 50 | 10.50.0.0/24 | 10.50.0.1 | No | Storage / jumbo frame network | +| IOT | 200 | 10.200.0.0/24 | 10.200.0.1 | Yes | IoT devices | +| GUEST | 3 | 10.3.0.0/24 | 10.3.0.1 | Yes | Guest network | +| Inter-VLAN | 4040 | 10.255.253.0/24 | 10.255.253.1 | No | Inter-VLAN routing | + +**Note**: DATA network is managed as a switch-only network on the USW Pro Aggregation (not routed through the UDM Pro gateway). + +## Devices + +### Switches + +| Name | Model | IP | State | Firmware | Ports | +|------|-------|----|-------|----------|-------| +| UDM_Pro | UDM Pro | 67.144.61.115 (WAN) | ONLINE | 5.0.12 | 11 (GE + 2x SFP+) | +| USW Pro Aggregation | USW Pro Aggregation | 10.2.0.173 | ONLINE | 7.2.123 | 28x SFP+ + 4x SFP28 | +| USW Pro Max 16 PoE | USW Pro Max 16 PoE | 10.2.0.108 | ONLINE | 7.2.123 | 12x GE + 4x 2.5GE + 2x SFP+ | +| JoesDeskSwitch | USW Pro XG 8 PoE | 10.2.0.231 | ONLINE | 7.2.123 | 8x 10GE + 2x SFP+ | +| GarageSwitch | USW Flex 2.5G 8 PoE | 10.2.0.238 | ONLINE | 2.1.8 | 8x 2.5GE + 1x 10GE + 1x SFP+ | +| LightCtrlPanelSwitch | USW Flex 2.5G 8 | 10.2.0.63 | ONLINE | 2.1.8 | 8x 2.5GE + 1x 10GE + 1x SFP+ | +| FamilyRoomSwitch | USW Flex 2.5G 8 | 10.2.0.69 | **OFFLINE** | 2.1.8 | 8x 2.5GE + 1x 10GE + 1x SFP+ | + +### Access Points + +| Name | Model | IP | State | +|------|-------|----|-------| +| FamilyRoomAP | U7-Pro-Wall | 10.2.0.89 | ONLINE | +| LivRm-U7-Pro-Wall | U7-Pro-Wall | 10.2.0.109 | ONLINE | +| GarageAP | U7-Pro-Wall | 10.2.0.102 | ONLINE | +| JoesRm-U7-Pro-Wall | U7-Pro-Wall | 10.2.0.107 | **OFFLINE** | +| U7 Pro XGS | U7 Pro XGS | 10.2.0.170 | ONLINE | + +## USW Pro Aggregation — Port Map + +This is the central switch connecting the ESXi host, desktop, and other switches. + +### Key Ports (ESXi + Desktop) + +| Port | Speed | Connector | Native VLAN | Forward | Connected To | SFP | +|------|-------|-----------|-------------|---------|-------------|-----| +| **19** | 10 Gbps | SFP+ | LAN (100) | customize | Desktop LAN NIC (10.100.0.49) | SFP-10G-T | +| **20** | 10 Gbps | SFP+ | DATA (50) | customize | Desktop DATA NIC (10.50.0.49) | UF-RJ45-10G | +| **31** | 25 Gbps | SFP28 | MGMT (untagged) | all (trunk) | ESXi vmnic4 → vSwitch0 | DAC-SFP28-3M | +| **32** | 25 Gbps | SFP28 | MGMT (untagged) | all (trunk) | ESXi vmnic5 → jumboFrameSwitch | DAC-SFP28-3M | + +- **Port 31** is a trunk carrying all VLANs (MGMT native + tagged LAN/100, IOT/200, GUEST/3, DATA/50) to ESXi vSwitch0 +- **Port 32** is a trunk carrying all VLANs (MGMT native + tagged DATA/50, LAN/100, etc.) to the ESXi jumbo frame switch — changed from `customize/native=DATA` to `all` to fix VLAN 50 tag mismatch with ESXi +- **Port 19** carries LAN (VLAN 100) to the desktop +- **Port 20** carries DATA (VLAN 50) to the desktop + +### Uplink / Infrastructure Ports + +| Port | Speed | State | Connected To | SFP | +|------|-------|-------|-------------|-----| +| 28 | 10 Gbps | UP | UDM Pro (uplink) | DAC-SFP10-0.5M | +| 27 | 10 Gbps | UP | Downstream switch (55 MACs) | DAC-SFP10-0.5M | + +### Other Active Ports + +| Port | Speed | State | Native VLAN | MACs | SFP | +|------|-------|-------|-------------|------|-----| +| 1 | 1 Gbps | UP | — | 4 | SFP1G-SX-85 | +| 2 | 10 Gbps | UP | — | 9 | SFP-10G-LR | +| 3 | 1 Gbps | UP | MGMT | 19 | 10GBASE-SR | +| 6 | 10 Gbps | UP | MGMT | 1 | QT-BIDI-SFP+-LR | +| 8 | 10 Gbps | UP | — | 0 | QT-BIDI-SFP+-LR (LAG member) | +| 9 | 10 Gbps | UP | MGMT | 0 | SFP-H10GB-CU3M | +| 11 | 10 Gbps | UP | MGMT | 0 | SFP-H10GB-CU3M | + +Ports 4-5, 7, 10, 12-18, 21-26, 29-30: down / unused. + +## Network Config IDs + +Reference for mapping legacy API `native_networkconf_id` values: + +| ID | Network | +|----|---------| +| 6796b2c822a9fa6cefe4f113 | MGMT (untagged) | +| 6796b4d3b07ab40dd44e3136 | LAN (VLAN 100) | +| 699440642ebebe33f1163116 | DATA (VLAN 50) | +| 6796b58bb07ab40dd44e3151 | IOT (VLAN 200) | +| 6796b5aeb07ab40dd44e3158 | GUEST (VLAN 3) | +| 699440642ebebe33f1163119 | Inter-VLAN (4040) | diff --git a/veeam.md b/veeam.md new file mode 100644 index 0000000..d89580b --- /dev/null +++ b/veeam.md @@ -0,0 +1,63 @@ +# Veeam Backup Server + +## Access + +- **Hostname**: VEEAM +- **IP**: 10.100.0.30 (LAN_100) / 10.50.0.32 (DATA_50) +- **OS**: Windows Server 2025 Standard (Build 26100), 64-bit +- **Credentials**: dohertj2 / Sonamu8901! +- **SSH**: `ssh dohertj2@10.100.0.30` (passwordless, key in `C:\ProgramData\ssh\administrators_authorized_keys`) +- **For PowerShell**: `ssh dohertj2@10.100.0.30 "powershell -Command '...'"` + +## Hardware (VM on ESXi) + +- **CPU**: 2x Intel Xeon E5-2697 v4 @ 2.30GHz (8 vCPUs) +- **RAM**: 8 GB +- **Disk**: C: 127.2 GB NTFS (59.3 GB free) + +## Network + +| Adapter | Description | MAC | IP | Subnet | Speed | +|---------|-------------|-----|-----|--------|-------| +| LAN_100 | vmxnet3 Ethernet Adapter #2 | 00-0C-29-33-76-AF | 10.100.0.30/24 | LAN_100 | 25 Gbps | +| DATA_50 | vmxnet3 Ethernet Adapter | 00-0C-29-33-76-A5 | 10.50.0.32/24 | DATA_50 | 25 Gbps | + +- **Default gateway**: 10.100.0.1 (via LAN_100) +- **DNS**: 10.100.0.1 + +## Veeam Backup & Replication + +- **Version**: 12.3.0.310 +- **Install path**: `C:\Program Files\Veeam\Backup and Replication\Backup\` +- **All 24 Veeam services running** + +### Managed Infrastructure + +| Server | Type | +|--------|------| +| Veeam (local) | Windows Server | +| 10.2.0.10 | ESXi (old server, kept for reference) | +| 10.2.0.12 | ESXi | + +### Backup Repositories + +| Name | Path | Type | Total (TB) | Free (TB) | +|------|------|------|-----------|----------| +| NAS_NFS | nfs41://10.2.0.25:/mnt/mypool/veeam | NFS | 65.6 | 63.7 | +| NAS | nfs41://10.50.0.25:/mnt/mypool/veeam | NFS | 93.1 | 69.7 | + +### Backup Jobs + +| Job | Type | Scheduled | Last Result | Next Run | +|-----|------|-----------|-------------|----------| +| Backup VMs | Backup | Yes | Success | 2/20/2026 3:00 AM | +| Backup workstation | Endpoint Agent | Yes | Success | 2/17/2026 10:00 PM | +| Backup Joes Macbook | Endpoint Agent | Yes | Warning | 4/3/2025 10:00 PM | + +**Backup VMs** includes: Plex, Ignition, HA, DOCKER + +### SMB Mappings + +| Drive | Remote Path | Status | +|-------|-------------|--------| +| Z: | \\\\10.100.0.25\Share | Unavailable | diff --git a/ww.md b/ww.md new file mode 100644 index 0000000..9fe28d0 --- /dev/null +++ b/ww.md @@ -0,0 +1,76 @@ +# Wonderware Dev VM + +## Access + +- **Hostname**: DESKTOP-6JL3KKO +- **IP**: 10.100.0.48 (VLAN 100 / LAN_100) +- **OS**: Windows 10 Enterprise (10.0.19045) +- **Shell**: PowerShell 7.6.1 (pwsh) +- **Credentials**: dohertj2 / Sonamu89 (local Administrator) +- **Remote access**: SSH (passwordless, key in `C:\ProgramData\ssh\administrators_authorized_keys`) +- **Platform**: ESXi VM (vmxnet3 vNIC) + +### Running Commands + +```bash +ssh dohertj2@10.100.0.48 "hostname" +ssh dohertj2@10.100.0.48 "powershell -Command 'Get-NetAdapter | Format-Table -AutoSize'" +``` + +Default remote shell is pwsh 7.6.1. SCP/SFTP work normally. + +**Historical note (2026-04-28):** the OpenSSH server originally shipped with `DefaultShellCommandOption` registry value set to the literal string `"-NoLogo -Command"` (single broken argument), which made every non-interactive `ssh host ` and SCP/SFTP fail. Fixed by setting it to `-Command`: + +```powershell +New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name DefaultShellCommandOption -Value '-Command' -PropertyType String -Force +Restart-Service sshd +``` + +## Network Interface + +### Ethernet0 — vmxnet3 (ifIndex 6) +- **MAC**: 00-0C-29-F0-09-6C +- **Speed**: 10 Gbps +- **IP**: 10.100.0.48 (static) +- **MTU**: 1500 +- **Gateway**: 10.100.0.1 +- **DNS**: 10.100.0.1 + +Single vNIC, untagged on VLAN 100. + +## Display Adapters / GPU + +The VM has an NVIDIA Quadro P1000 attached via PCI passthrough — full setup, attach procedure, and rollback are in [ww_gpu.md](ww_gpu.md). Adapter state inside Windows: + +| Adapter | Status | Why | +|---|---|---| +| NVIDIA Quadro P1000 (`PCI\VEN_10DE&DEV_1CB1`) | **Active**, 2560×1440 | The intended display; drives DWM and serves NVENC for Parsec | +| VMware SVGA 3D (`PCI\VEN_15AD&DEV_0405`) | **Disabled** (PnP-disabled 2026-04-29) | Removing the second adapter is what got Parsec/DXGI to bind to the Quadro instead of falling back to MS Basic Render Driver. Re-enable with `Enable-PnpDevice -InstanceId "PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00\3&61AAA01&0&78" -Confirm:$false` | +| Parsec Virtual Display Adapter (`ROOT\DISPLAY\0000`) | Installed, offline (Availability=8) | Parsec ships this and `host_virtual_monitors=1` is set in `C:\ProgramData\Parsec\config.json`, but it stays offline because the Quadro is already serving as the active display. Harmless; leave installed | + +### Side effects + +- **vSphere VM Console window shows nothing** — the Quadro doesn't render to ESXi's virtual framebuffer, and VMware SVGA (which did) is disabled. Use SSH / Parsec / RDP instead. If you need vSphere console access (e.g., to recover a black-screen Parsec failure), re-enable VMware SVGA via SSH first. +- **NVENC session count is 1 max** for typical workloads on the Quadro P1000. Parsec already holds the slot; OBS or another encoder using NVENC simultaneously won't get a session. + +### Remote desktop options + +| Path | Encoder | Notes | +|---|---|---| +| **Parsec** | NVENC (Quadro hardware H.264) | The intended remote-desktop path. Verified `encoder = nvidia / codec = h264` in `C:\ProgramData\Parsec\log.txt` | +| RDP | Software (CPU AVC444) | Works, but Windows 10 client OS doesn't honor `AVCHWEncodePreferred` server-side, so NVENC stays idle for RDP. The three RDP GPU policies (`bEnumerateHWBeforeSW`, `AVC444ModePreferred`, `AVCHWEncodePreferred`) are all set under `HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services` — `bEnumerateHWBeforeSW` is the only one that has visible effect on this OS (DWM uses the Quadro). The other two are no-ops on Win10 client SKUs but harmless | +| SSH | n/a | Always works; preferred for automation | + +## Docker / WSL2 (removed) + +As of 2026-04-28 this VM no longer runs Docker workloads. Docker Desktop, the `docker-desktop` WSL2 distro, and the VirtualMachinePlatform/WSL Windows features have been removed so a GPU can be re-attached via ESXi passthrough (Hyper-V/WSL2 was blocking it). A reboot is required to finalize the feature disable. + +The `lmxopcua` project's Docker workloads now live on the docker host (10.100.0.35); see [docker.md](docker.md). The developer drives them from this VM via `~/bin/lmxopcua-fix.ps1`, which SSHes into the docker host. A standalone Docker CLI (no daemon) is at `~/bin/docker.exe` for ad-hoc remote operations against the docker host. + +## lmxopcua Project + +- **Path**: `C:\Users\dohertj2\Desktop\lmxopcua` +- **Local services**: GLAuth (NSSM service, `C:\publish\glauth\`, port 3893), Galaxy / MXAccess, the OtOpcUa server itself (`opc.tcp://localhost:4840`) +- **Remote services**: SQL Server config DB at `10.100.0.35,14330` and all driver test fixtures via `lmxopcua-fix.ps1` +- **Helper**: `~/bin/lmxopcua-fix.ps1` — `up`/`down`/`logs`/`ls`/`sync` against `/opt/otopcua-/` on the docker host +- **Identifying label** on remote containers: `project=lmxopcua` diff --git a/ww_gpu.md b/ww_gpu.md new file mode 100644 index 0000000..17bdd92 --- /dev/null +++ b/ww_gpu.md @@ -0,0 +1,122 @@ +# WW VM — GPU Passthrough + +NVIDIA Quadro P1000 PCI passthrough to `WW_DEV_VM` (10.100.0.48). **Executed 2026-04-28.** GPU is live in Windows: `nvidia-smi` reports driver 582.41 / CUDA 13.0, 4 GiB VRAM, status WDDM, no Code 43. + +## Final state + +| Item | Value | +|---|---| +| Quadro P1000 driver in guest | 582.41 / CUDA 13.0 (already installed; took the device on first boot) | +| Guest PCI bus address | `00000000:23:00.0` | +| Audio function | High Definition Audio Controller present, status OK | +| ESXi `graphicsInfo.graphicsType` | `direct` (was already set before this task) | +| ESXi `pciPassthruInfo` for `87:00.0` / `87:00.1` | `passthruEnabled=true, passthruActive=true` (flipped on without host reboot) | +| VM `nestedHVEnabled` | `false` | +| VM `memoryHotAddEnabled` | `false` | +| VM memory reservation | 32768 MB / 32768 MB (locked) | +| Other VMs touched during the change | None — host stayed up | + +## What `graphicsType: direct` actually means (lesson learned) + +`graphicsInfo.graphicsType: direct` and `pciPassthruInfo.passthruEnabled` are **two parallel mechanisms**. Both must be set for direct GPU passthrough: + +1. `graphicsType: direct` — graphics subsystem says "this card is a passthrough device, not vSGA/vGPU". Set in vSphere UI: Host → Configure → Hardware → Graphics. +2. `pciPassthruInfo.passthruEnabled` — generic per-PCI-device passthrough flag. Set via `host.esxcli hardware pci pcipassthru set -e=true`. Without this, the device doesn't appear in `device.pci.ls -vm `, so VMs can't claim it. + +The "no host reboot needed" benefit only kicks in when `graphicsType: direct` is **already** in effect — the runtime activation flag (`-a=true` on the esxcli call) succeeds because the device isn't actively serving as a host graphics device. If `graphicsType` is still `shared` (default), flipping `pcipassthru` requires a host reboot for the activation to land. + +## Procedure (the one that worked) + +### 1. Finish inside-VM teardown — already done before this task + +WSL2 + VirtualMachinePlatform Windows features were disabled during the Docker→DOCKER migration. The reboot to finalize that disable also serves as the "shut down before passthrough" step. + +```powershell +ssh dohertj2@10.100.0.48 'Get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform,Microsoft-Windows-Subsystem-Linux | Select-Object FeatureName,State' +# Expect: both Disabled +``` + +### 2. Shut down the VM (graceful) + +```bash +export GOVC_URL=https://10.2.0.12/sdk GOVC_USERNAME=govc GOVC_PASSWORD='Tn9.xKw-m4Vp' GOVC_INSECURE=true +govc vm.power -s=true WW_DEV_VM +until govc vm.info WW_DEV_VM | grep -q "Power state: poweredOff"; do sleep 5; done +``` + +### 3. Flip the VM hardware flags (VM must be off) + +```bash +govc vm.change -vm WW_DEV_VM -nested-hv-enabled=false +govc vm.change -vm WW_DEV_VM -memory-hot-add-enabled=false + +govc vm.info -json=true WW_DEV_VM | python3 -c "import json,sys;v=json.load(sys.stdin)['virtualMachines'][0]['config'];print('nestedHV:',v.get('nestedHVEnabled'));print('memHotAdd:',v.get('memoryHotAddEnabled'))" +# Expect: nestedHV: False, memHotAdd: False +``` + +### 4. Enable `pcipassthru` for both Quadro PCI functions + +`graphicsType: direct` was already set, so `-a=true` activates the flag immediately — no host reboot. (Note: `govc gpu.vm.add` is for **vGPU profiles**, not direct PCI passthrough, and fails on this card with "no vGPU profiles available". Use `device.pci.add` instead.) + +```bash +govc host.esxcli hardware pci pcipassthru set -d=0000:87:00.0 -e=true -a=true +govc host.esxcli hardware pci pcipassthru set -d=0000:87:00.1 -e=true -a=true + +# Confirm both are active +govc host.info -json=true | python3 -c " +import json,sys +d=json.load(sys.stdin) +for p in d['hostSystems'][0]['config'].get('pciPassthruInfo', []): + if '87:00' in p.get('id',''): print(p) +" +# Expect: passthruEnabled=True, passthruActive=True for both + +# Confirm the Quadro now shows up as available for VMs +govc device.pci.ls -vm WW_DEV_VM | grep -i nvidia +# Expect: 0000:87:00.0 and 0000:87:00.1 listed +``` + +A harmless quirk: the second `pcipassthru set` command may emit `Device owner is already configured to passthru` if the audio function was previously partially configured. Check the post-state with `pciPassthruInfo` — both should be `passthruActive=True`. + +### 5. Attach the GPU + audio to the VM + +```bash +govc device.pci.add -vm WW_DEV_VM 0000:87:00.0 +govc device.pci.add -vm WW_DEV_VM 0000:87:00.1 + +# Verify two VirtualPCIPassthrough devices exist +govc device.info -vm WW_DEV_VM 'pcipassthrough-*' +``` + +### 6. Power on, verify + +```bash +govc vm.power -on=true WW_DEV_VM +until ssh -o ConnectTimeout=3 -o BatchMode=yes dohertj2@10.100.0.48 'hostname' 2>/dev/null; do sleep 5; done + +# Confirm the GPU is detected and the driver bound +ssh dohertj2@10.100.0.48 'Get-PnpDevice -Class Display | Where-Object FriendlyName -match "Quadro" | Select-Object FriendlyName,Status' + +# Confirm CUDA / driver runtime +ssh dohertj2@10.100.0.48 'nvidia-smi' +``` + +## Notes for future operators + +1. **`gpu.vm.add` vs `device.pci.add`**: govc's `gpu.vm.add` is for vGPU profiles (data-center cards like A40 with NVIDIA vGPU licensing). For consumer Quadro cards in direct passthrough mode, use `device.pci.add`. `gpu.host.profile.ls` returns "no vGPU profiles available" on a host whose only NVIDIA card is a non-vGPU Quadro. +2. **Audio function `87:00.1`** must be attached to the same VM as `87:00.0` — they share an IOMMU group via parent bridge `0000:80:03.0` and ESXi rejects splitting them. +3. **No host reboot was needed** because `graphicsType: direct` was already in effect from earlier vSphere UI work. If you ever swap GPUs, set `graphicsType: direct` first (vSphere UI: Host → Configure → Hardware → Graphics → Edit → Direct) and reboot the host once; from then on, per-VM attach/detach is a runtime operation. +4. **Driver was pre-installed**: the previous Windows install already had NVIDIA driver 582.41, so the GPU appeared with status OK on first boot. A fresh Windows install would need the driver from https://www.nvidia.com/Download/index.aspx (Quadro P1000). +5. **Rollback**: `govc device.pci.remove -vm WW_DEV_VM pcipassthrough-13000 pcipassthrough-13001` → re-enable `nestedHVEnabled` / `memoryHotAddEnabled` → power VM on. Host PCI flags can stay enabled; they don't hurt. + +## Inventory + +| Field | Value | +|---|---| +| Model | NVIDIA Quadro P1000 (GP107GL) | +| GPU PCI ID (host) | `0000:87:00.0` (vendor `0x10de`, device `0x1cb1`) | +| Audio PCI ID (host) | `0000:87:00.1` (vendor `0x10de`, device `0x0fb9`) | +| Subsystem | Dell (`0x1028:0x11bc`) | +| Parent bridge | `0000:80:03.0` | +| VRAM | 4 GiB | +| Driver in guest | 582.41 (Windows 10 WDDM) |