Files
nixos-servers/docs/plans/remote-access.md
Torjus Håkestad af8e385b6e
Some checks failed
Run nix flake check / flake-check (push) Failing after 21m7s
Periodic flake update / flake-update (push) Successful in 2m16s
docs: finalize remote access plan with WireGuard gateway design
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:31:52 +01:00

131 lines
5.7 KiB
Markdown

# Remote Access to Homelab Services
## Status: Planning
## Goal
Enable personal remote access to selected homelab services from outside the internal network, without exposing anything directly to the internet.
## Current State
- All services are only accessible from the internal 10.69.13.x network
- http-proxy has a WireGuard tunnel (`wg0`, `10.69.222.0/24`) to a VPS (`docker2.t-juice.club`) on an OpenStack cluster
- VPS runs Traefik which proxies selected services (including Jellyfin) back through the tunnel to http-proxy's Caddy
- No other services are directly exposed to the public internet
## Decision: WireGuard Gateway
After evaluating WireGuard gateway vs Headscale (self-hosted Tailscale), the **WireGuard gateway** approach was chosen:
- Only 2 client devices (laptop + phone), so Headscale's device management UX isn't needed
- Split DNS works fine on Linux laptop via systemd-resolved; all-or-nothing DNS on phone is acceptable for occasional use
- Simpler infrastructure - no control server to maintain
- Builds on existing WireGuard experience and setup
## Architecture
```
┌─────────────────────────────────┐
│ VPS (OpenStack) │
Laptop/Phone ──→ │ WireGuard endpoint │
(WireGuard) │ Client peers: laptop, phone │
│ Routes 10.69.13.0/24 via tunnel│
└──────────┬──────────────────────┘
│ WireGuard tunnel
┌─────────────────────────────────┐
│ extgw01 (gateway + bastion) │
│ - WireGuard tunnel to VPS │
│ - Firewall (allowlist only) │
│ - SSH + 2FA (full access) │
└──────────┬──────────────────────┘
│ allowed traffic only
┌─────────────────────────────────┐
│ Internal network 10.69.13.0/24 │
│ - monitoring01:3000 (Grafana) │
│ - jelly01:8096 (Jellyfin) │
│ - *-jail hosts (arr stack) │
└─────────────────────────────────┘
```
### Existing path (unchanged)
The current public access path stays as-is:
```
Internet → VPS (Traefik) → WireGuard → http-proxy (Caddy) → internal services
```
This handles public Jellyfin access and any other publicly-exposed services.
### New path (personal VPN)
A separate WireGuard tunnel for personal remote access with restricted firewall rules:
```
Laptop/Phone → VPS (WireGuard peers) → tunnel → extgw01 (firewall) → allowed services
```
### Access tiers
1. **VPN (default)**: Laptop/phone connect to VPS WireGuard endpoint, traffic routed through extgw01 firewall. Only whitelisted services are reachable.
2. **SSH + 2FA (escalated)**: SSH into extgw01 for full network access when needed.
## New Host: extgw01
A NixOS host on the internal network acting as both WireGuard gateway and SSH bastion.
### Responsibilities
- **WireGuard tunnel** to the VPS for client traffic
- **Firewall** with allowlist controlling which internal services are reachable through the VPN
- **SSH bastion** with 2FA for full network access when needed
- **DNS**: Clients get split DNS config (laptop via systemd-resolved routing domain, phone uses internal DNS for all queries)
### Firewall allowlist (initial)
| Service | Destination | Port |
|------------|------------------------------|-------|
| Grafana | monitoring01.home.2rjus.net | 3000 |
| Jellyfin | jelly01.home.2rjus.net | 8096 |
| Sonarr | sonarr-jail.home.2rjus.net | 8989 |
| Radarr | radarr-jail.home.2rjus.net | 7878 |
| NZBget | nzbget-jail.home.2rjus.net | 6789 |
### SSH 2FA options (to be decided)
- **Kanidm**: Already deployed on kanidm01, supports RADIUS/OAuth2 for PAM integration
- **SSH certificates via OpenBao**: Fits existing Vault infrastructure, short-lived certs
- **TOTP via PAM**: Simplest fallback, Google Authenticator / similar
## VPS Configuration
The VPS needs a new WireGuard interface (separate from the existing http-proxy tunnel):
- WireGuard endpoint listening on a public UDP port
- 2 peers: laptop, phone
- Routes client traffic through tunnel to extgw01
- Minimal config - just routing, no firewall policy (that lives on extgw01)
## Implementation Steps
1. **Create extgw01 host configuration** in this repo
- VM provisioned via OpenTofu (same as other hosts)
- WireGuard interface for VPS tunnel
- nftables/iptables firewall with service allowlist
- IP forwarding enabled
2. **Configure VPS WireGuard** for client peers
- New WireGuard interface with laptop + phone peers
- Routing for 10.69.13.0/24 through extgw01 tunnel
3. **Set up client configs**
- Laptop: WireGuard config + systemd-resolved split DNS for `home.2rjus.net`
- Phone: WireGuard app config with DNS pointing at internal nameservers
4. **Set up SSH 2FA** on extgw01
- Evaluate Kanidm integration vs OpenBao SSH certs vs TOTP
5. **Test and verify**
- VPN access to allowed services only
- Firewall blocks everything else
- SSH + 2FA grants full access
- Existing public access path unaffected