infrastructure/server_homeassistant.md

306 lines
12 KiB
Markdown
Raw Normal View History

2026-07-26 22:12:38 -04:00
# 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