Two parts, one private route.
Safeveil combines a static presentation and control interface in dist/ with a single-node WireGuard gateway and provisioning API in gateway/. WireGuard provides the encrypted tunnel. The Node.js control service creates and revokes peers while remaining bound to loopback behind an HTTPS reverse proxy.
Static pages explain the concept, select a location, and administer a deployed gateway.
A minimal authenticated API manages WireGuard peer records and produces standard client configurations.
You supply the Linux VPS, public IPv4 address, DNS, monitoring, backups, and operational controls.
Deploy to a clean VPS.
Use Debian 12 or Ubuntu 22.04/24.04 with a public IPv4 address. Before installation, create a DNS A record pointing to the server and allow 80/tcp, 443/tcp, and 51820/udp.
Required environment
export UNTRACE_DOMAIN="vpn.example.com"
export UNTRACE_ADMIN_EMAIL="admin@example.com"
export UNTRACE_ADMIN_TOKEN="$(openssl rand -base64 48)"
sudo --preserve-env=UNTRACE_DOMAIN,UNTRACE_ADMIN_EMAIL,UNTRACE_ADMIN_TOKEN \
bash gateway/bootstrap.sh
The installer configures WireGuard, the loopback control service, NGINX, TLS through Certbot, firewall-compatible ports, and the static website. Keep the generated administrator token in a password manager; never commit it or share it in screenshots or support messages.
Provision a WireGuard peer.
- Open https://vpn.example.com/console.html.
- Enter the gateway origin and the administrator token used during deployment.
- Create a uniquely named peer and download the generated .conf file.
- Import the configuration into an official WireGuard client for Windows, macOS, iOS, Android, or Linux.
The peer private key is returned once inside the downloaded configuration and is not stored in the peer database. If that file is lost, revoke the peer and create a replacement.
Add country gateways.
Deploy one VPS per country or region. Give each deployment a unique location ID, display name, domain, and WireGuard endpoint. Then edit dist/locations.json, set that location’s available value to true, and point controlUrl to its HTTPS origin.
export UNTRACE_LOCATION_ID="de"
export UNTRACE_LOCATION_NAME="Germany · Frankfurt"
export UNTRACE_WG_ENDPOINT="vpn-de.example.com:51820"
export UNTRACE_SITE_ORIGIN="https://safeveil.example.com"
Minimal control-plane API.
All responses use JSON. Administrative endpoints require Authorization: Bearer <token>. The public health endpoint does not require authorization.
| Method | Endpoint | Purpose | Auth |
|---|---|---|---|
| GET | /api/health | Service and configured-location health | Public |
| GET | /api/status | Interface, endpoint, location, and live peer state | Bearer |
| GET | /api/peers | List stored peer records | Bearer |
| POST | /api/peers | Create a peer and return its one-time client configuration | Bearer |
| DELETE | /api/peers/:id | Revoke and remove a peer | Bearer |
Create a peer
curl -X POST "https://vpn.example.com/api/peers" \
-H "Authorization: Bearer $UNTRACE_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Laptop","locationId":"de"}'
Gateway environment.
| Variable | Default | Meaning |
|---|---|---|
| UNTRACE_BIND | 127.0.0.1 | Control API bind address |
| UNTRACE_PORT | 8787 | Loopback control API port |
| UNTRACE_ADMIN_TOKEN | Required | Administrator bearer token, minimum 32 characters |
| UNTRACE_WG_INTERFACE | wg0 | Managed WireGuard interface |
| UNTRACE_WG_ENDPOINT | Required | Public WireGuard host and port |
| UNTRACE_WG_SUBNET_PREFIX | 10.70.0 | Private IPv4 prefix for peers |
| UNTRACE_DNS | 1.1.1.1, 1.0.0.1 | DNS servers written to clients |
| UNTRACE_ALLOWED_ORIGIN | Empty | Exact website origin allowed by CORS |
| UNTRACE_PEER_DB | /var/lib/untrace/peers.json | Persistent peer metadata path |
| UNTRACE_DRY_RUN | 0 | Use synthetic keys and avoid interface changes when set to 1 |
Observe and maintain.
sudo systemctl status wg-quick@wg0
sudo systemctl status untrace-control
sudo wg show wg0
sudo journalctl -u untrace-control --since today
Revoking a peer removes its public key from the live WireGuard interface and persistent peer database. On reboot, the control service restores only peers still recorded in that database.
Dry-run testing
UNTRACE_ADMIN_TOKEN="development-token-with-at-least-32-chars" \
UNTRACE_WG_ENDPOINT="localhost:51820" \
UNTRACE_PEER_DB="./work/peers.json" \
UNTRACE_DRY_RUN=1 \
node gateway/bin/untrace-api.mjs
node --test gateway/tests/api.test.mjs
Production requires more.
This repository is a deployment scaffold, not a security audit. Before serving untrusted users, add an identity provider, per-user authorization, secret rotation, durable audit logs, monitoring, encrypted backups, abuse controls, and an independent security review.
IPv4 traffic is forwarded through the gateway. The client configuration routes ::/0 into the tunnel as a fail-closed IPv6 route; this scaffold does not provide routed IPv6 internet access.
