Phantom-WG
Phantom-WG is a modular tool that lets you set up and manage a WireGuard VPN infrastructure on your own server. Beyond basic VPN management, it offers censorship-resistant connections, multi-layered encryption, and advanced privacy scenarios.
Phantom-WG Modern is the container-native implementation of this vision. All components run within Docker and are isolated from the host system:
- Userspace WireGuard — Container-scoped TUN device via Go FFI bridge. No kernel module required, does not touch the host's network namespace.
- nftables netlink FFI — Rust backend communicates directly with the kernel. No subprocess calls, firewall rules are managed programmatically.
- SQLite State Persistence — All state is stored in SQLite databases. A daemon restart after a crash is sufficient — kernel state is rebuilt from the DB.
- Dual-Stack IPv6 — Even without IPv6 on the host, an IPv6 subnet is assigned within the container and traffic is carried through the tunnel.
-
Container Isolation —
NET_ADMIN+NET_RAWis sufficient. WireGuard interfaces live within the container namespace. Configurations that weaken host security such asSYS_ADMIN,privileged, orhostnetwork mode are not used.
Topology
Three containers, managed via Docker Compose. Management traffic passes through TLS + JWT authentication, WireGuard traffic reaches the daemon directly.
|
Component
|
Role
|
|---|---|
| nginx | TLS termination, React SPA (static compiled files), reverse proxy configuration |
| auth-service | Comprehensive authentication system, API proxy to daemon over UDS |
| daemon | Userspace WireGuard (Go FFI), nftables firewall (Rust FFI), client and tunnel management, databases |
Key Features
Bridge Architecture
The daemon performs system-level operations through two native bridges. Python manages the business logic, bridges communicate directly with the kernel.
|
Bridge
|
Language
|
Responsibility
|
|---|---|---|
| wireguard-go-bridge | Go | Userspace WireGuard, TUN device, IPC state persistence |
| firewall-bridge | Rust | nftables rule groups, policy routing, preset system |
Multihop Exit Routing
You can define your exit tunnel to route traffic through an external WireGuard VPN server. IPv4 and IPv6 tunnels are supported simultaneously.
IPv6 Dual-Stack
IPv6 support across all layers — firewall rules, policy routing, masquerade, and multihop presets
operate with family: 10 (AF_INET6). IPv6 tunnel traffic can be carried from within
the container even without an IPv6 address on the host.
Crash Recovery
When the service starts, kernel state (nftables rules, routing policies) is rebuilt from SQLite state databases. No data loss after an unexpected shutdown.
Installation
Prerequisites: Docker Engine 20.10+, Docker Compose v2, bash.
Configuration
Access:
- Dashboard:
https://<server-ip> - WireGuard: UDP port
51820 - Admin password:
cat container-data/secrets/production/.admin_password
Access from VPN
To access the dashboard while connected to the VPN, use the nginx container's Docker network address:
Accessible via https://<IPv4> or https://[<IPv6>] through
the tunnel. You can also remove the ports: "443:443" line from
docker-compose.yml to make the dashboard accessible only through the VPN tunnel.
Management
A convenient tool is available at ./tools/prod.sh for management.
|
Command
|
Description
|
|---|---|
setup |
Full Setup |
setup --terazi-ipv4-subnet=SUBNET |
Setup with custom subnet (e.g. 10.9.0.0/24) |
up |
Start |
down |
Stop |
restart [service] |
Restart (All or Specific Service) |
build |
Build Images |
rebuild |
Build Images from Scratch (no-cache) |
update |
Update (git pull + restart) |
update --skip-compose |
Update (exclude docker-compose.yml) |
logs [service] |
Log Tracking (All or Specific Service) |
status |
Docker Compose Status |
show-versions |
Component Versions (Daemon, Vendor Packages) |
shell [service] |
Shell (default: daemon) |
exec <svc> <cmd> |
Execute Command |
hard-reset |
Delete All Data |
Setup
The setup command creates all required components during first-time installation:
-
Creates
.env.daemonand.env.auth-servicefiles from.exampletemplates. -
Generates WireGuard server key pair. (Curve25519 —
wg_private_key,wg_public_key) -
Auth-Service bootstrap cycle:
-
Generates Ed25519 signing key pair. (
auth_signing_key,auth_verify_key) - Creates auth database. (
auth.db— users, sessions, TOTP, audit log) - Creates admin account. (32-character random password encrypted with Argon2id hash)
-
Generates Ed25519 signing key pair. (
-
Generates self-signed TLS certificate for nginx. (
tls_cert,tls_key)
All of these operations take place within the container — no additional dependencies or tools need to be installed on the host.
Terazi requires a base subnet to create the IP pool. The default is 10.8.0.0/24 and
can be customized at setup with the --terazi-ipv4-subnet argument. This value is only
used when wallet.db is created — once the database exists, the subnet is stored there
and the argument is no longer needed. See the
Terazi documentation for details.
Updating
For package dependency changes that require container recompilation (Dockerfile, requirements.txt):