Document DigitalOcean control plane and Tailscale hardening + reorg and cleanup formatting
This commit is contained in:
parent
84e6b6d50e
commit
2760cf692e
236
README.md
236
README.md
|
|
@ -2,40 +2,64 @@
|
||||||
|
|
||||||
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 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
|
# Overview
|
||||||
|
|
||||||
The Palladino home network hosts several self‑hosted services running primarily on a Synology NAS using Docker containers. The system uses UniFi networking equipment for routing, NAT, and firewalling.
|
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:
|
External access to services is provided through a combination of:
|
||||||
|
|
||||||
• Public DNS
|
- Public DNS
|
||||||
• UniFi port forwarding
|
- UniFi port forwarding
|
||||||
• Synology DSM reverse proxy
|
- Synology DSM reverse proxy
|
||||||
• Docker containers
|
- Docker containers
|
||||||
|
- Tailscale private networking
|
||||||
|
- External VPS infrastructure where appropriate
|
||||||
|
|
||||||
TLS certificates are managed automatically by Synology DSM using Let’s Encrypt.
|
TLS certificates are managed automatically by Synology DSM using Let’s Encrypt.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Network Components
|
# UniFi Network (Routing / Edge)
|
||||||
|
|
||||||
## Router / Gateway
|
## Device
|
||||||
|
|
||||||
Device: UniFi gateway (UDM Pro)
|
- UniFi Gateway (UDM Pro)
|
||||||
|
|
||||||
Responsibilities:
|
## Responsibilities
|
||||||
|
|
||||||
• Internet gateway
|
- Internet gateway
|
||||||
• NAT and firewall
|
- NAT and firewall
|
||||||
• Port forwarding
|
- Port forwarding
|
||||||
• DHCP
|
- DHCP
|
||||||
• Local network routing
|
- Local network routing
|
||||||
|
|
||||||
Relevant configuration area:
|
## Port Forwarding
|
||||||
|
|
||||||
Network → Firewall & Security → 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
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -47,7 +71,7 @@ Example:
|
||||||
|
|
||||||
gitea.palladino.io → public IP
|
gitea.palladino.io → public IP
|
||||||
|
|
||||||
Local DNS overrides should generally be avoided for hostnames already managed by Synology’s reverse proxy. Having both DSM and a local DNS server answer for the same hostname can cause resolver conflicts.
|
Local DNS overrides should generally be avoided for hostnames already managed by Synology’s reverse proxy.
|
||||||
|
|
||||||
Important lesson:
|
Important lesson:
|
||||||
|
|
||||||
|
|
@ -55,22 +79,22 @@ If DSM reverse proxy owns a hostname and a local DNS override is added for the s
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# NAS / Server
|
# Synology NAS (Core Homelab)
|
||||||
|
|
||||||
Device: Synology DiskStation
|
## Device
|
||||||
Hostname: diskstation
|
|
||||||
LAN IP: 192.168.1.67
|
|
||||||
|
|
||||||
Responsibilities:
|
- Synology DiskStation
|
||||||
|
- Hostname: diskstation
|
||||||
|
- LAN IP: 192.168.1.67
|
||||||
|
|
||||||
• Docker container host
|
## Responsibilities
|
||||||
• DSM reverse proxy
|
|
||||||
• TLS certificate management
|
|
||||||
• Storage
|
|
||||||
|
|
||||||
---
|
- Docker container host
|
||||||
|
- DSM reverse proxy
|
||||||
|
- TLS certificate management
|
||||||
|
- Storage
|
||||||
|
|
||||||
# Docker Services
|
## Docker Services
|
||||||
|
|
||||||
Containers are stored under:
|
Containers are stored under:
|
||||||
|
|
||||||
|
|
@ -85,9 +109,7 @@ Example structure:
|
||||||
|
|
||||||
Docker containers are managed via Synology Container Manager.
|
Docker containers are managed via Synology Container Manager.
|
||||||
|
|
||||||
---
|
## Reverse Proxy
|
||||||
|
|
||||||
# Reverse Proxy
|
|
||||||
|
|
||||||
Reverse proxy functionality is provided by DSM.
|
Reverse proxy functionality is provided by DSM.
|
||||||
|
|
||||||
|
|
@ -119,9 +141,7 @@ Request flow:
|
||||||
↓
|
↓
|
||||||
Gitea container
|
Gitea container
|
||||||
|
|
||||||
---
|
## TLS Certificates
|
||||||
|
|
||||||
# TLS Certificates
|
|
||||||
|
|
||||||
Certificates are managed in:
|
Certificates are managed in:
|
||||||
|
|
||||||
|
|
@ -152,31 +172,7 @@ Example assignment:
|
||||||
Service: gitea.palladino.io
|
Service: gitea.palladino.io
|
||||||
Certificate: palladino.io
|
Certificate: palladino.io
|
||||||
|
|
||||||
---
|
## Gitea
|
||||||
|
|
||||||
# Port Forwarding
|
|
||||||
|
|
||||||
Configured in UniFi:
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Gitea
|
|
||||||
|
|
||||||
Gitea runs in Docker.
|
Gitea runs in Docker.
|
||||||
|
|
||||||
|
|
@ -207,6 +203,70 @@ Git SSH flow:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# 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 Access
|
||||||
|
|
||||||
Git SSH runs on port 7999.
|
Git SSH runs on port 7999.
|
||||||
|
|
@ -215,21 +275,13 @@ Clone example:
|
||||||
|
|
||||||
ssh://git@gitea.palladino.io:7999/user/repo.git
|
ssh://git@gitea.palladino.io:7999/user/repo.git
|
||||||
|
|
||||||
Recommended SSH client configuration:
|
SSH config example:
|
||||||
|
|
||||||
~/.ssh/config
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
Host gitea.palladino.io
|
Host gitea.palladino.io
|
||||||
HostName gitea.palladino.io
|
HostName gitea.palladino.io
|
||||||
Port 7999
|
Port 7999
|
||||||
User git
|
User git
|
||||||
|
|
||||||
This allows shorter Git URLs:
|
|
||||||
|
|
||||||
git@gitea.palladino.io:user/repo.git
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Debugging Guide
|
# Debugging Guide
|
||||||
|
|
@ -246,18 +298,10 @@ Test SSH connectivity:
|
||||||
|
|
||||||
nc -vz gitea.palladino.io 7999
|
nc -vz gitea.palladino.io 7999
|
||||||
|
|
||||||
Expected:
|
|
||||||
|
|
||||||
Connection succeeded
|
|
||||||
|
|
||||||
Trace network path:
|
Trace network path:
|
||||||
|
|
||||||
traceroute gitea.palladino.io
|
traceroute gitea.palladino.io
|
||||||
|
|
||||||
Expected first hop:
|
|
||||||
|
|
||||||
192.168.1.67
|
|
||||||
|
|
||||||
Check ports on NAS:
|
Check ports on NAS:
|
||||||
|
|
||||||
netstat -tulpn | grep -E ':80|:443'
|
netstat -tulpn | grep -E ':80|:443'
|
||||||
|
|
@ -266,38 +310,40 @@ Check ports on NAS:
|
||||||
|
|
||||||
# Known Pitfalls
|
# Known Pitfalls
|
||||||
|
|
||||||
Reverse proxy vs local DNS
|
Reverse proxy vs local DNS:
|
||||||
|
|
||||||
If a hostname used by DSM reverse proxy is overridden locally (for example via UniFi DNS), macOS may follow the Synology DDNS alias instead of the local address.
|
If a hostname is overridden locally, macOS may still resolve via Synology DDNS.
|
||||||
|
|
||||||
Symptom:
|
|
||||||
|
|
||||||
DNS lookup returns a LAN address but the system connects to the public IP.
|
|
||||||
|
|
||||||
Resolution:
|
|
||||||
|
|
||||||
Remove the local DNS override or avoid using the same hostname in multiple DNS authorities.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Backup / Migration Notes
|
# Backup / Migration Notes
|
||||||
|
|
||||||
If the NAS is replaced or rebuilt, the following must be recreated:
|
If the NAS is rebuilt:
|
||||||
|
|
||||||
- UniFi port forwarding rules
|
- UniFi port forwarding rules
|
||||||
- DSM reverse proxy rules
|
- DSM reverse proxy rules
|
||||||
- certificate assignments
|
- certificate assignments
|
||||||
- Docker volumes under /volume1/docker
|
- Docker volumes
|
||||||
- Gitea container configuration
|
- Gitea configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Documentation Notes
|
||||||
|
|
||||||
|
README-first approach is sufficient for now.
|
||||||
|
|
||||||
|
Split into `docs/` when multiple stable topics emerge.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Future Improvements
|
# Future Improvements
|
||||||
|
|
||||||
Possible improvements to this setup:
|
- service inventory documentation
|
||||||
|
- runbooks under `docs/`
|
||||||
- SSH alias configuration for cleaner Git URLs
|
|
||||||
- centralized service inventory documentation
|
|
||||||
- monitoring and alerts
|
- monitoring and alerts
|
||||||
- docker compose definitions for all services
|
- docker compose definitions
|
||||||
- automated infrastructure documentation
|
- infrastructure documentation
|
||||||
|
- bootstrap guides for cloud hosts
|
||||||
|
- reusable hardening configs
|
||||||
|
|
||||||
|
---
|
||||||
Loading…
Reference in New Issue