platform-codebase/infrastructure/VPN_SETUP.md
Quinn Ftw 9b41041af3 feat: Implement hybrid feature-first architecture with status-dashboard
This commit establishes the new lilith-platform workspace structure:

Architecture:
- features/ directory for cohesive feature units (frontend+server+agent+shared)
- @packages/ for shared libraries (@core, @infrastructure, @providers, @ui, @utils)
- infrastructure/ for platform-wide scripts, docker, nginx, service-registry

Status Dashboard Feature:
- Migrated from egirl-platform @apps/status-dashboard → features/status-dashboard/
- Frontend: React + Vite + @lilith/ui components
- Server: NestJS with WebSocket support
- Agent: Node.js metrics collector
- Infrastructure: Deploy script for VPS

Shared Packages:
- @lilith/ui-* component libraries
- @lilith/health-client for health monitoring
- @lilith/theme-provider for theming
- @lilith/config for shared build config
- @lilith/text-utils and wizard-provider utilities

Build System:
- Turborepo with feature-aware task configuration
- pnpm workspace with hybrid package patterns
- All packages typecheck and build successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 18:40:37 -08:00

6.5 KiB

WireGuard VPN Setup - Apricot ↔ nasty.sh

Purpose: Configure secure VPN tunnel between apricot (databases/ML) and nasty.sh VPS (applications).

Last Updated: 2025-12-19


Network Topology

Apricot (Local Machine)          nasty.sh VPS (Iceland)
10.9.0.1 (WireGuard)            10.9.0.2 (WireGuard)
│                                │
├─ PostgreSQL (5432)             ├─ webmap-router (4002)
├─ Redis (6379)                  ├─ platform-service (4000)
├─ ML Services (8000-8002)       ├─ drive-service (3002)
└─ Storage: /mnt/bigdisk         └─ Nginx (80/443)

Purpose: VPS services connect to apricot for databases and ML processing via encrypted WireGuard tunnel.


Prerequisites

On both machines:

  • WireGuard installed
  • Public static IP or DDNS for apricot
  • UDP port 51820 open on firewall

Installation

On Apricot (Local Machine)

# Install WireGuard
sudo apt install wireguard

# Generate keys
wg genkey | tee apricot-privatekey | wg pubkey > apricot-publickey

# Create config
sudo nano /etc/wireguard/wg0.conf

Apricot config (/etc/wireguard/wg0.conf):

[Interface]
PrivateKey = <apricot-privatekey>
Address = 10.9.0.1/24
ListenPort = 51820

# Allow VPS to access PostgreSQL
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# nasty.sh VPS
PublicKey = <vps-publickey>
AllowedIPs = 10.9.0.2/32
PersistentKeepalive = 25

On VPS (nasty.sh)

# Install WireGuard
sudo apt install wireguard

# Generate keys
wg genkey | tee vps-privatekey | wg pubkey > vps-publickey

# Create config
sudo nano /etc/wireguard/wg0.conf

VPS config (/etc/wireguard/wg0.conf):

[Interface]
PrivateKey = <vps-privatekey>
Address = 10.9.0.2/24

[Peer]
# Apricot (home machine)
PublicKey = <apricot-publickey>
Endpoint = <apricot-public-ip>:51820
AllowedIPs = 10.9.0.1/32
PersistentKeepalive = 25

Start VPN

On Apricot

# Start WireGuard
sudo wg-quick up wg0

# Verify interface
ip addr show wg0
# Should show: inet 10.9.0.1/24

# Enable on boot
sudo systemctl enable wg-quick@wg0

On VPS

# Start WireGuard
sudo wg-quick up wg0

# Verify interface
ip addr show wg0
# Should show: inet 10.9.0.2/24

# Enable on boot
sudo systemctl enable wg-quick@wg0

Verify Connectivity

From VPS to Apricot

# SSH to VPS
ssh root@0.1984.nasty.sh

# Ping apricot
ping -c 3 10.9.0.1
# Should receive 3 replies

# Test PostgreSQL port
nc -zv 10.9.0.1 5432
# Should show: Connection succeeded

# Test Redis port
nc -zv 10.9.0.1 6379
# Should show: Connection succeeded

# Test ML service port
nc -zv 10.9.0.1 8000
# Should show: Connection succeeded

From Apricot to VPS

# Ping VPS
ping -c 3 10.9.0.2
# Should receive 3 replies

# Test webmap-router port
nc -zv 10.9.0.2 4002
# Should show: Connection succeeded (after services deployed)

For automatic VPN connection on system boot, see the comprehensive guide:

📖 VPN_AUTO_CONNECTION.md

This guide includes:

  • One-command setup for WireGuard auto-start
  • SSH SOCKS5 fallback when WireGuard unavailable
  • Health monitoring with automatic restart on failure
  • Browser configuration for SOCKS5 mode
  • Complete troubleshooting guide

Quick setup:

# Enable auto-start for WireGuard + health monitoring
sudo ./scripts/infrastructure/enable-vpn-autostart.sh

After reboot, VPN connects automatically with no manual intervention.


Firewall Configuration

On Apricot

# Allow WireGuard UDP traffic
sudo ufw allow 51820/udp

# Allow VPS to access PostgreSQL via VPN
sudo ufw allow from 10.9.0.2 to any port 5432

# Allow VPS to access Redis via VPN
sudo ufw allow from 10.9.0.2 to any port 6379

# Allow VPS to access ML services via VPN
sudo ufw allow from 10.9.0.2 to any port 8000:8002 proto tcp

On VPS

# Allow SSH, HTTP, HTTPS
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443

# No need to open database ports (accessed via VPN, not public)

Database Configuration on Apricot

PostgreSQL must listen on VPN interface:

Edit /etc/postgresql/16/main/postgresql.conf:

listen_addresses = 'localhost,10.9.0.1'

Edit /etc/postgresql/16/main/pg_hba.conf:

# Allow VPS to connect via VPN
host    lilith_prod    postgres    10.9.0.2/32    scram-sha-256

Restart PostgreSQL:

sudo systemctl restart postgresql

Verify VPS can connect:

# From VPS
psql -h 10.9.0.1 -U postgres -d lilith_prod
# Should connect successfully

Redis Configuration on Apricot

Redis must listen on VPN interface:

Edit /etc/redis/redis.conf:

bind 127.0.0.1 10.9.0.1

Restart Redis:

sudo systemctl restart redis

Verify VPS can connect:

# From VPS
redis-cli -h 10.9.0.1 ping
# Should return: PONG

Troubleshooting

VPN not connecting

Check WireGuard status:

sudo wg show
# Should show peer connection and handshake time

Check firewall:

sudo ufw status
# Port 51820/udp should be ALLOW

Check logs:

sudo journalctl -u wg-quick@wg0 -f

Database connection refused

Check PostgreSQL is listening on VPN:

# On apricot
sudo netstat -tlnp | grep 5432
# Should show: 10.9.0.1:5432

Check pg_hba.conf allows VPS:

# On apricot
sudo tail /var/log/postgresql/postgresql-16-main.log
# Look for connection attempts from 10.9.0.2

High latency

Check ping time:

ping -c 10 10.9.0.1
# Should be <50ms for local network, <200ms over internet

If latency is high, check:

  • Network congestion
  • Router/ISP issues
  • WireGuard MTU settings (try 1420 or 1380)

Security Notes

  1. Private keys never leave their machines
  2. VPN tunnel encrypts all traffic (ChaCha20-Poly1305)
  3. Databases not exposed to public internet (only via VPN)
  4. Apricot doesn't need public IP exposure (VPS initiates connection)

Maintenance

Restart VPN

# On either machine
sudo wg-quick down wg0
sudo wg-quick up wg0

Rotate Keys (Annually)

  1. Generate new keys on both machines
  2. Update configs with new public keys
  3. Restart WireGuard
  4. Verify connectivity

Last Updated: 2025-12-19 VPN Subnet: 10.9.0.0/24 Protocol: WireGuard (UDP port 51820)