You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
WireGuard VPN management daemon + control panel API written in Go, with a Vue 3 frontend.
Architecture
cmd/vpn-core/main.go → entrypoint (WireGuard + Control API)
internal/
api/ → chi router, CORS, rate limiting middleware
respond/ → shared JSON response helpers (JsonOK, JsonError, SafeError)
core/ → WireGuard core HTTP handlers + X-Core-Token middleware
control/ → Control API handlers, OAuth, core-client, background jobs, WebSocket hub
auth/ → JWT/JWKS validation (Authentik), JIT user provisioning
config/ → environment-based configuration
crypto/ → Curve25519 keypair generation
db/ → PostgreSQL connection pool (pgx) + migrations
ippool/ → automatic IP allocation in 10.8.0.0/16
models/ → data models (User, VPNServer, Peer, AuditLog)
repo/ → repository pattern for DB access
wg/ → WireGuard manager (wgctrl + netlink)
migrations/ → PostgreSQL schema migrations
midori-vpn-control/ → Vue 3 + TypeScript frontend (panel de control)
Components
VPN Core API
Low-level WireGuard peer management. Protected by shared secret (X-Core-Token).
Control API
User-facing API for managing VPN connections, servers and audit logs. Protected by JWT tokens from Authentik. Enabled automatically when DATABASE_URL and AUTHENTIK_CLIENT_ID are set.
Control Frontend (midori-vpn-control/)
Vue 3 + TypeScript SPA with OAuth2/OIDC login flow (PKCE) against accounts.astian.org. Features automatic token refresh and state validation.
Requirements
Docker (recommended) — builds and runs everything in containers
Or: Go 1.22+, Node.js 20+, PostgreSQL 16+, Redis 7+, Linux with WireGuard
Quick Start (Docker)
cp .env.default .env
# Edit .env — set VPN_CORE_TOKEN, WG_ENDPOINT, AUTHENTIK_CLIENT_ID# Development (builds from source, includes PostgreSQL + Redis)
docker compose -f docker-compose-dev.yml up --build
# Production (pre-built image)
docker compose up
Environment Variables
Application
Variable
Default
Description
APP_ENV
production
production hides internal errors, development shows them
Core (WireGuard)
Variable
Default
Description
VPN_CORE_PORT
8080
HTTP API listen port
VPN_CORE_TOKEN
(empty)
Shared secret for X-Core-Token header
WG_INTERFACE
wg0
WireGuard interface name
WG_PORT
51820
WireGuard UDP listen port
WG_SUBNET
10.8.0.0/16
IP pool subnet
WG_CONFIG_DIR
/etc/wireguard
Config persistence directory
WG_ENDPOINT
(empty)
Public IP/hostname for peer configs
Control API (optional — enables user management)
Variable
Default
Description
DATABASE_URL
(empty)
PostgreSQL connection string
REDIS_URL
redis://localhost:6379/0
Redis connection string
AUTHENTIK_ISSUER
(empty)
OIDC issuer URL
AUTHENTIK_CLIENT_ID
(empty)
Authentik OAuth2 client ID
AUTHENTIK_JWKS_URL
(auto from issuer)
JWKS endpoint URL
Security & Limits
Variable
Default
Description
CORS_ALLOWED_ORIGINS
https://*.astian.org,...
Comma-separated allowed origins
RATE_LIMIT_RPS
20
Requests per second per IP (0 = disabled)
RATE_LIMIT_BURST
40
Burst size for rate limiter
MAX_DEVICES_PER_USER
5
Max active VPN connections per user (0 = unlimited)
CORE_TLS_SKIP_VERIFY
false
Skip TLS verification for core-to-core comms
CORE_ALLOW_INSECURE_HTTP
false
Allow HTTP (no TLS) for core-to-core comms in local/testing
API Endpoints
Availability notes:
Core API and GET /health are always available.
Auth, Control API, Admin API, and WebSocket are available only when both DATABASE_URL and AUTHENTIK_CLIENT_ID are configured.