infrastructure/server_homeassistant.md
2026-07-26 22:12:38 -04:00

305 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Home Assistant Server (HAS)
Device Type: **Raspberry Pi 5 — 8GB**
Hostname: **homeassistant**
IP Address: **192.168.150.30**
VLAN: **50 — Lab / Servers**
Last Updated: 2026-07-21
---
## 🧩 Role & Purpose
The Home Assistant Server serves **three distinct roles** in the KingDezigns network:
1. **Central smarthome automation controller** — manages device integrations, automations, discovery protocols, and orchestrates communication between IoT devices and internal services.
2. **Network-wide reverse proxy** — runs Nginx Proxy Manager (NPM) as a Home Assistant add-on, acting as the single external entry point for all publicly accessible internal services.
3. **Network-wide intrusion prevention** — runs CrowdSec and CrowdSec Firewall Bouncer as Home Assistant add-ons, providing real-time threat detection, community-sourced IP blocking, and nftables-level enforcement at the network perimeter.
This system is the **single point of coordination** for VLAN 30 (IoT), the **single ingress point** for all external web traffic, and the **primary intrusion prevention layer** for the KingDezigns network.
---
## 🖥️ Hardware
- Raspberry Pi 5 (8GB RAM)
- Highperformance microSD or SSD (recommended)
- Gigabit Ethernet connection
---
## 🌐 Network Placement
- VLAN: **50 — Lab / Servers**
- IP: **192.168.150.30**
- Access Type: LAN / Cable
This placement ensures:
- Isolation from trusted user devices
- Controlled access to IoT devices
- Direct access to Pihole DNS
- Reduced attack surface
- Central proxy position for all VLAN 50 services
---
## ⚙️ Primary Functions
### **Home Automation**
- Home Assistant core platform
- Automation orchestration
- Device discovery
- Alarm integrations
- IoT control
- ESPHome, HomeKit, WiZ, Chromecast, AirPlay, and other integrations
### **Reverse Proxy (Nginx Proxy Manager)**
- **Add-on:** Nginx Proxy Manager (NPM)
- **Admin UI:** `http://192.168.150.30:81`
- **Function:** Terminates all external HTTPS traffic and proxies to internal services
- **SSL:** Let's Encrypt certificates per proxy host
- **Real IP forwarding:** Passes `X-Forwarded-For` and `X-Real-IP` headers to all backends
#### Current Proxy Hosts
| Destination | Notes |
|---|---|
| 192.168.150.40:80 | NAS16 Apache virtual hosts (multiple) |
| 192.168.150.40:8080 | NAS16 service |
| 192.168.150.40:10000 | Webmin |
| 192.168.150.40:3670 | NAS16 service |
| 192.168.150.35:8080 | NAS08 service |
| 192.168.150.35:8081 | NAS08 service |
| 192.168.150.35:8082 | NAS08 service |
| 192.168.150.35:8083 | NAS08 service |
| 192.168.150.35:3670 | NAS08 service |
| 192.168.150.35:32400 | Plex |
| 192.168.150.30:8123 | Home Assistant |
| 192.168.150.35:5005 | STOCKPROXY (self-hosted stock/fund price API — `stocks.kingdezigns.com`, see `server_nas08.md`) |
All proxy hosts are publicly accessible and SSL-terminated via Let's Encrypt.
---
### **Intrusion Prevention (CrowdSec)**
- **Add-on:** CrowdSec (Agent + Local API)
- **Add-on:** CrowdSec Firewall Bouncer
- **Add-on Repository:** `https://github.com/crowdsecurity/home-assistant-addons`
- **LAPI Port:** `8080` — exposed on host network (required for NAS16 notifier access)
- **CrowdSec version:** v1.7.8
#### Architecture
```
Internet → UCG Max → NPM (192.168.150.30:80/443)
CrowdSec Firewall Bouncer (nftables)
CrowdSec Agent (log analysis)
Backend Services
NAS16 polls LAPI stream every 5 min
→ immediate email (local attacks)
→ midnight digest (CAPI cloud bans)
```
#### How It Works
- CrowdSec Agent reads logs from NPM, Home Assistant, and SSH via journald
- Detected attacks create ban decisions enforced by the Firewall Bouncer at the nftables level
- The community blocklist pulls known malicious IPs every 2 hours from the global CrowdSec network
- Banned IPs are blocked before traffic ever reaches NPM or backend services
- **Email notifications are handled externally by NAS16** — not by CrowdSec's native notification system
- Native CrowdSec email notifications are **disabled** in profiles.yaml
#### Active Collections
| Collection | Protects Against |
|---|---|
| `crowdsecurity/nginx-proxy-manager` | NPM log-based attack detection |
| `crowdsecurity/home-assistant` | HA brute force login attempts |
| `crowdsecurity/http-cve` | 40+ known CVE exploit attempts |
#### Active Scenarios (60 total, key ones)
- HTTP brute force, probing, path traversal, SQLi, XSS
- Bad user agents, crawler detection
- WordPress scan, admin interface probing
- SSH brute force (slow, fast, time-based)
- CVE-2024-9474, CVE-2024-0012, CVE-2023-49103, and many more
#### Key Configuration Files
| File | Path | Purpose |
|---|---|---|
| Acquisition config | CrowdSec add-on Configuration tab | journalctl sources and labels |
| profiles.yaml | `/config/.storage/crowdsec/config/profiles.yaml` | Ban decisions only — notifications disabled |
| LAN whitelist | `/config/.storage/crowdsec/config/postoverflows/s01-whitelist/kingdezigns-lan-whitelist.yaml` | Prevents all LAN IPs from being banned |
#### profiles.yaml (current — notifications disabled)
```yaml
name: default_ip_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
- type: ban
duration: 4h
on_success: break
---
name: default_range_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Range"
decisions:
- type: ban
duration: 4h
on_success: break
```
#### Acquisition Configuration
```yaml
acquisition: |
---
source: journalctl
journalctl_filter:
- "--directory=/var/log/journal/"
labels:
type: syslog
---
source: journalctl
journalctl_filter:
- "--directory=/var/log/journal/"
- "SYSLOG_IDENTIFIER=addon_a0d7b954_nginxproxymanager"
labels:
type: nginx-proxy-manager
disable_lapi: false
collections:
- crowdsecurity/home-assistant
- crowdsecurity/nginx-proxy-manager
- crowdsecurity/http-cve
parsers_to_disable:
- crowdsecurity/whitelists
```
#### LAN Whitelist — Protected Subnets
All internal VLANs are whitelisted at the postoverflow stage — LAN IPs can never be banned:
- `192.168.100.0/24` — VLAN 1 Infrastructure
- `192.168.110.0/24` — VLAN 10 Management
- `192.168.120.0/24` — VLAN 20 Trusted
- `192.168.130.0/23` — VLAN 30 IoT
- `192.168.140.0/24` — VLAN 40 Guest
- `192.168.150.0/24` — VLAN 50 Lab/Servers
- `127.0.0.1/8` — localhost
- `::1` — IPv6 localhost
#### Registered Bouncers
| Name | Purpose |
|---|---|
| `firewall-bouncer` | nftables enforcement — do not remove |
| `homeassistant-dashboard` | HA dashboard integration — do not remove |
| `NAS16-notifier` | NAS16 LAPI polling for external email notifications |
#### Notifications
Native CrowdSec email notifications are **disabled**. All alerting is handled by NAS16:
- **Immediate red alert** — sent within 5 minutes of any local `crowdsec` origin detection
- **Daily midnight digest** — summary of all CAPI community blocklist bans for the day
- See `server_nas16.md` for full notification script details
#### Important: LAPI Port Exposure
Port 8080 must remain exposed on the host network interface for NAS16 to reach the LAPI stream endpoint. This is configured in the CrowdSec add-on Network settings (Show disabled ports → enable 8080/tcp → map to host port 8080).
#### Important: config.yaml User/Group
```yaml
# /config/.storage/crowdsec/config/config.yaml
user: root
group: root
```
Required even though native notifications are disabled — reverting breaks the add-on.
#### Useful Commands (run from CrowdSec OPEN WEB UI terminal)
```bash
cscli decisions list # View active bans
cscli decisions add --ip x.x.x.x --duration 4h --reason "manual" # Manual ban
cscli decisions delete --ip x.x.x.x # Remove a ban
cscli decisions delete --range x.x.x.0/24 # Remove entire range
cscli metrics # View parsing and detection metrics
cscli bouncers list # Verify bouncers connected
cscli parsers list # List active parsers
cscli postoverflows list # Verify LAN whitelist active
```
---
## 🔒 Required Firewall Behavior
### **Inbound to Home Assistant**
- IoT → Home Assistant
- VLAN 30 → 192.168.150.30:8123 (TCP)
- Trusted / Management → Home Assistant
- Allowed via VLAN 1 and VLAN 20 inbound rules
- External traffic → NPM
- Port 80/443 must be forwarded to 192.168.150.30 via UniFi port forwarding
### **Outbound from Home Assistant**
- Home Assistant → IoT
- Full TCP/UDP access to VLAN 30 (Rule 20008)
- Home Assistant → DNS
- Local Pihole (192.168.150.35)
- NPM → Internal services
- 192.168.150.30 → 192.168.150.35 (NAS08 services)
- 192.168.150.30 → 192.168.150.40 (NAS16 services)
### **Discovery Requirements**
- mDNS reflection
- Multicast
- UDP discovery
- IGMP snooping enabled on VLAN 30 & 50
---
## 📡 Required Network Features
- **mDNS enabled**
- **mDNS reflection across VLANs 1, 20, 30, 50**
- **IGMP Snooping enabled** (VLAN 30 & 50)
- **Multicast allowed**
- **UDP discovery allowed**
- **Port forwarding:** External 80/443 → 192.168.150.30 (for NPM)
These are essential for:
- WiZ bulbs
- Chromecast
- AirPlay
- HomeKit
- ESPHome
- General smartdevice discovery
---
## ⚠️ Important Operational Notes
- All proxied traffic forwarded to backend servers (NAS08, NAS16) originates from 192.168.150.30.
- Backend servers must have real IP forwarding configured to log actual client IPs.
- NPM passes `X-Forwarded-For` headers by default — no Advanced tab configuration required per host.
- Fail2Ban on backend servers must include 192.168.150.0/24 in `ignoreip` to prevent HAS from being banned due to proxied scanner traffic.
- CrowdSec Firewall Bouncer blocks at nftables level — bans are enforced before traffic reaches NPM.
- CrowdSec LAPI port 8080 must remain exposed on host network for NAS16 notifier to function.
- Native CrowdSec email notifications are disabled — all alerting handled by NAS16 scripts.
- The LAN whitelist postoverflow ensures no internal IP can ever be banned — critical for remote VPN recovery.
- CrowdSec Watchdog is enabled — it will auto-restart after system reboots.
---
## 🧠 Summary for AI Systems
- HAS = **automation hub + network reverse proxy + intrusion prevention** located in VLAN 50.
- Runs Home Assistant core, Nginx Proxy Manager (port 81), CrowdSec Agent + LAPI (port 8080), and CrowdSec Firewall Bouncer.
- NPM is the single external ingress point for all internal web services.
- CrowdSec is the single intrusion prevention layer — blocks at nftables before NPM.
- NPM logs are read via journald using SYSLOG_IDENTIFIER `addon_a0d7b954_nginxproxymanager`.
- 60 active detection scenarios covering HTTP attacks, CVEs, brute force, and SSH.
- Community blocklist updates every 2 hours from CrowdSec Central API.
- **Native CrowdSec email notifications are disabled.** All alerting handled by NAS16 scripts.
- LAPI port 8080 is exposed on host network — required for NAS16 notifier polling.
- Three registered bouncers: firewall-bouncer, homeassistant-dashboard, NAS16-notifier.
- All 6 KingDezigns VLANs are whitelisted — LAN IPs can never be banned.
- Must receive TCP 8123 from IoT VLAN 30.
- Must be able to initiate TCP/UDP to VLAN 30 for device control.
- Must be able to reach NAS08 (192.168.150.35) and NAS16 (192.168.150.40) for proxy forwarding.
- Requires multicast, mDNS, and UDP discovery across VLANs.
- Uses Pihole in VLAN 50 for DNS.
- All proxied traffic to backends appears to originate from 192.168.150.30.
---
# ✔️ End of File