commit 982ddc0e8f4a2d599954c0ae0f158d5c56c9533d Author: dohertj2 Date: Wed Apr 29 09:00:06 2026 -0400 Initial commit: home network inventory and runbooks 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) |