349 lines
6.2 KiB
Markdown
349 lines
6.2 KiB
Markdown
# Palladino Homelab / Local Network Architecture
|
||
|
||
This repository documents the structure and configuration of the Palladino home network and homelab environment. The goal is to provide a clear reference for how services are deployed, exposed, and maintained so that the system can be debugged, rebuilt, or migrated in the future.
|
||
|
||
This repository also documents lightweight cloud infrastructure that supports the homelab, including externally hosted control-plane services that connect back into the home network over private overlay networking.
|
||
|
||
---
|
||
|
||
# Overview
|
||
|
||
The Palladino home network consists of three primary components:
|
||
|
||
- UniFi networking infrastructure (routing, firewall, port forwarding)
|
||
- Synology NAS (core homelab services)
|
||
- DigitalOcean Droplet (cloud control plane / automation gateway)
|
||
|
||
External access to services is provided through a combination of:
|
||
|
||
- Public DNS
|
||
- UniFi port forwarding
|
||
- Synology DSM reverse proxy
|
||
- Docker containers
|
||
- Tailscale private networking
|
||
- External VPS infrastructure where appropriate
|
||
|
||
TLS certificates are managed automatically by Synology DSM using Let’s Encrypt.
|
||
|
||
---
|
||
|
||
# UniFi Network (Routing / Edge)
|
||
|
||
## Device
|
||
|
||
- UniFi Gateway (UDM Pro)
|
||
|
||
## Responsibilities
|
||
|
||
- Internet gateway
|
||
- NAT and firewall
|
||
- Port forwarding
|
||
- DHCP
|
||
- Local network routing
|
||
|
||
## Port Forwarding
|
||
|
||
Configured in:
|
||
|
||
Network → Firewall → Port Forwarding
|
||
|
||
Current forwards:
|
||
|
||
- 443 → Synology (DSM reverse proxy)
|
||
- 80 → Synology (HTTP redirect)
|
||
- 7999 → Synology (Gitea SSH)
|
||
|
||
Example rule:
|
||
|
||
- Name: Gitea SSH
|
||
- Protocol: TCP
|
||
- Destination Port: 7999
|
||
- Forward IP: 192.168.1.67
|
||
- Forward Port: 7999
|
||
|
||
---
|
||
|
||
# DNS
|
||
|
||
Public DNS is the primary source of truth for service hostnames.
|
||
|
||
Example:
|
||
|
||
gitea.palladino.io → public IP
|
||
|
||
Local DNS overrides should generally be avoided for hostnames already managed by Synology’s reverse proxy.
|
||
|
||
Important lesson:
|
||
|
||
If DSM reverse proxy owns a hostname and a local DNS override is added for the same hostname, macOS may follow the Synology DDNS alias instead of the local IP.
|
||
|
||
---
|
||
|
||
# Synology NAS (Core Homelab)
|
||
|
||
## Device
|
||
|
||
- Synology DiskStation
|
||
- Hostname: diskstation
|
||
- LAN IP: 192.168.1.67
|
||
|
||
## Responsibilities
|
||
|
||
- Docker container host
|
||
- DSM reverse proxy
|
||
- TLS certificate management
|
||
- Storage
|
||
|
||
## Docker Services
|
||
|
||
Containers are stored under:
|
||
|
||
/volume1/docker/
|
||
|
||
Example structure:
|
||
|
||
/volume1/docker
|
||
/gitea
|
||
/gitea-old
|
||
/homeassistant
|
||
|
||
Docker containers are managed via Synology Container Manager.
|
||
|
||
## Reverse Proxy
|
||
|
||
Reverse proxy functionality is provided by DSM.
|
||
|
||
Location:
|
||
|
||
DSM → Control Panel → Login Portal → Advanced → Reverse Proxy
|
||
|
||
Example rule (Gitea):
|
||
|
||
Source
|
||
|
||
Protocol: HTTPS
|
||
Hostname: gitea.palladino.io
|
||
Port: 443
|
||
|
||
Destination
|
||
|
||
Protocol: HTTP
|
||
Hostname: localhost
|
||
Port: 3001
|
||
|
||
Request flow:
|
||
|
||
https://gitea.palladino.io
|
||
↓
|
||
Synology reverse proxy
|
||
↓
|
||
localhost:3001
|
||
↓
|
||
Gitea container
|
||
|
||
## TLS Certificates
|
||
|
||
Certificates are managed in:
|
||
|
||
DSM → Control Panel → Security → Certificate
|
||
|
||
Primary certificate:
|
||
|
||
palladino.io
|
||
|
||
Subject Alternative Names include:
|
||
|
||
palladino.io
|
||
gitea.palladino.io
|
||
plex.palladino.io
|
||
paperless.palladino.io
|
||
dsm.palladino.io
|
||
|
||
Important operational detail:
|
||
|
||
Certificates must be explicitly assigned to services.
|
||
|
||
Location:
|
||
|
||
Security → Certificates → Configure
|
||
|
||
Example assignment:
|
||
|
||
Service: gitea.palladino.io
|
||
Certificate: palladino.io
|
||
|
||
## Gitea
|
||
|
||
Gitea runs in Docker.
|
||
|
||
Container ports:
|
||
|
||
22 → 7999 (SSH)
|
||
3000 → 3001 (Web UI)
|
||
|
||
Web UI flow:
|
||
|
||
https://gitea.palladino.io
|
||
↓
|
||
reverse proxy
|
||
↓
|
||
localhost:3001
|
||
↓
|
||
Gitea container
|
||
|
||
Git SSH flow:
|
||
|
||
git@gitea.palladino.io:7999
|
||
↓
|
||
UniFi port forward
|
||
↓
|
||
NAS
|
||
↓
|
||
Docker port mapping
|
||
|
||
---
|
||
|
||
# Cloud Control Plane (DigitalOcean)
|
||
|
||
## Droplet
|
||
|
||
- Hostname: openclaw
|
||
- OS: Ubuntu 24.04
|
||
- Plan: 1 vCPU / 2 GB RAM / 50 GB SSD
|
||
- Region: NYC1
|
||
|
||
## Purpose
|
||
|
||
- lightweight always-on VPS
|
||
- host for OpenClaw gateway
|
||
- private administration over Tailscale only
|
||
- separation from NAS trust boundary
|
||
|
||
## Access Model
|
||
|
||
Administrative access is via SSH over Tailscale.
|
||
|
||
- root SSH login disabled
|
||
- non-root sudo user
|
||
- key-based authentication only
|
||
- SSH bound to Tailscale interface
|
||
- public SSH blocked (sshd + firewall)
|
||
|
||
Expected behavior:
|
||
|
||
- SSH over Tailscale succeeds
|
||
- SSH to public IP times out
|
||
|
||
---
|
||
|
||
# Tailscale (Private Network)
|
||
|
||
## Connected Devices
|
||
|
||
- MacBook Pro
|
||
- Mac mini
|
||
- DigitalOcean Droplet (openclaw)
|
||
|
||
## Role
|
||
|
||
- private SSH access to Droplet
|
||
- secure connectivity between cloud and local devices
|
||
- avoids exposing admin services publicly
|
||
|
||
## Enforcement
|
||
|
||
1. sshd listens only on Tailscale IP
|
||
2. UFW allows inbound on `tailscale0` only
|
||
|
||
## Ubuntu / systemd Note
|
||
|
||
After changing `ListenAddress`, socket activation must be reloaded:
|
||
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl restart ssh.socket
|
||
sudo systemctl restart ssh
|
||
|
||
Otherwise SSH may still bind to 0.0.0.0.
|
||
|
||
---
|
||
|
||
# Git SSH Access
|
||
|
||
Git SSH runs on port 7999.
|
||
|
||
Clone example:
|
||
|
||
ssh://git@gitea.palladino.io:7999/user/repo.git
|
||
|
||
SSH config example:
|
||
|
||
Host gitea.palladino.io
|
||
HostName gitea.palladino.io
|
||
Port 7999
|
||
User git
|
||
|
||
---
|
||
|
||
# Debugging Guide
|
||
|
||
Check DNS resolution:
|
||
|
||
dig gitea.palladino.io
|
||
|
||
Check system resolver (macOS):
|
||
|
||
dscacheutil -q host -a name gitea.palladino.io
|
||
|
||
Test SSH connectivity:
|
||
|
||
nc -vz gitea.palladino.io 7999
|
||
|
||
Trace network path:
|
||
|
||
traceroute gitea.palladino.io
|
||
|
||
Check ports on NAS:
|
||
|
||
netstat -tulpn | grep -E ':80|:443'
|
||
|
||
---
|
||
|
||
# Known Pitfalls
|
||
|
||
Reverse proxy vs local DNS:
|
||
|
||
If a hostname is overridden locally, macOS may still resolve via Synology DDNS.
|
||
|
||
---
|
||
|
||
# Backup / Migration Notes
|
||
|
||
If the NAS is rebuilt:
|
||
|
||
- UniFi port forwarding rules
|
||
- DSM reverse proxy rules
|
||
- certificate assignments
|
||
- Docker volumes
|
||
- Gitea configuration
|
||
|
||
---
|
||
|
||
# Documentation Notes
|
||
|
||
README-first approach is sufficient for now.
|
||
|
||
Split into `docs/` when multiple stable topics emerge.
|
||
|
||
---
|
||
|
||
# Future Improvements
|
||
|
||
- service inventory documentation
|
||
- runbooks under `docs/`
|
||
- monitoring and alerts
|
||
- docker compose definitions
|
||
- infrastructure documentation
|
||
- bootstrap guides for cloud hosts
|
||
- reusable hardening configs
|
||
|
||
--- |