306 lines
12 KiB
Markdown
306 lines
12 KiB
Markdown
|
|
# 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 smart‑home 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)
|
|||
|
|
- High‑performance 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 Pi‑hole 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 Pi‑hole (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 smart‑device 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 Pi‑hole in VLAN 50 for DNS.
|
|||
|
|
- All proxied traffic to backends appears to originate from 192.168.150.30.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# ✔️ End of File
|