VirtuaMesh Documentation
A zero-trust identity-based networking platform built on the WireGuard protocol. Replace legacy VPNs and securely connect remote teams, multi-cloud environments, and IoT devices.
What is VirtuaMesh? It pulls devices "located around the world, behind NAT firewalls" into a virtual LAN, letting them reach each other as if they were under the same router — with WireGuard end-to-end encryption the entire way.
What problems does it solve? ① Remote access to your home NAS / cameras / smart home; ② Building an intranet across branch offices in different regions; ③ Remote work access to corporate internal systems; ④ Bridging IoT devices across network segments; ⑤ Building secure tunnels between servers.
Who is it for? From home users who know nothing about networking to senior developers who need API, ACL, subnet routing, and Kubernetes integration — this page has dedicated sections for each.
🌱 5-Minute Beginner Tutorial
This tutorial is for: Anyone who has never touched VPN / servers / the command line. The whole process only requires a browser — no commands to type.
What exactly is it?
Imagine: your phone is on 4G, your home PC is on residential broadband, and your work PC is on the corporate network. These three devices normally can't see each other — but through VirtuaMesh, they get "pulled" into a virtual internal network. You can access your home NAS from your work PC, or connect to your home smart camera from your phone.
You don't need to understand public IPs, port forwarding, or firewalls. VirtuaMesh handles all of it automatically.
What do you need to prepare?
- One internet-connected computer (Windows / Mac / Linux all work) for logging into the admin console
- Two or more devices that need to reach each other (phones, computers, NAS all fine)
- One server with public internet access (a cloud VPS or your home NAS) to host the server and DERP relay — all services are self-hosted and depend on no public relays
3 steps to get it done
Step 1: Log in to the admin console (2 minutes)
Open https://your-server-address/manager/ in a browser and sign in with the admin account. After the first deployment, the default admin account is admin@virtuamesh.com; see the deployment docs for the password.
Step 2: Add each device to the network (1 minute per device)
In the admin console, click "Add Device" and the system will generate a 6-digit invite code. Then:
- Search for
VirtuaMeshin the app store and install - Open the app and enter the invite code
- Allow adding the VPN configuration
- Wait for admin approval (new nodes default to "Pending" state)
- Once approved, the app shows "Connected"
- Download the client from the admin console
- Double-click to install (Windows / Mac)
- Launch it and enter the invite code
- Wait for admin approval (client shows "Connecting...")
- Once approved, the tray icon turns green = connected
Step 3: Test the connection
All joined devices are now on the same virtual network. You can:
- View all online devices in the admin console; each has a name (e.g. "My Phone", "Home NAS")
- See other devices' shared folders directly from your computer's "Network"
- Connect to your NAS with an SSH tool:
ssh admin@my-nas.virtuamesh.com - Access the NAS web UI at
http://my-nas.virtuamesh.com:5000in a browser
1. Device isn't online → open a browser and try a normal website
2. Invite code is wrong → regenerate one in the admin console
3. Firewall is blocking → temporarily disable antivirus and system firewall and try again
Still not working? Check the FAQ or run
virtuamesh test-connection to test connectivity.
What to learn next?
You've completed basic networking! Below are advanced use cases — learn as needed:
my-nas.virtuamesh.com📖 Concept Cheat Sheet (must-read for beginners)
Run into a term you don't understand? Look it up here. Every concept comes with a real-life analogy.
100.64.0.5. Fixed — doesn't change when you switch Wi-Fi.my-nas) instead of IP.🧩 Architecture Deep Dive
Understanding how VirtuaMesh works internally is essential for troubleshooting.
Overall Architecture
Connection Establishment Flow (5 steps)
-
Node registration
After startup, the node registers with the control plane, submitting its public key and authentication info.
-
Get peer list
The control plane returns information about all peer nodes this node can access (public key, virtual IP, endpoint).
-
NAT traversal attempt
Nodes pair up and attempt to establish P2P direct connections via STUN hole-punching. 80% of home networks succeed.
-
P2P established or DERP fallback
If P2P succeeds, they communicate directly; if it fails, they automatically fall back to DERP relay for encrypted data — the connection still works.
-
Continuous keepalive
Nodes send heartbeats to the control plane via a long-lived gRPC stream (server default suggestion: 30s, adjustable in client
config.yaml), keeping NAT mappings alive. The server marks a node offline if no heartbeat arrives withinHeartbeatTimeout(30s).
Key Design Principles
| Principle | Meaning | Benefit |
|---|---|---|
| End-to-end encryption | WireGuard ChaCha20; nodes encrypt/decrypt directly | Server can't see business data — zero knowledge |
| No central data path | Data flow doesn't pass through the control plane | Control plane cannot become a bottleneck |
| Auto traversal | STUN + candidate path negotiation | Zero config, zero port forwarding |
| Keys never persisted | Node private keys live only on the local machine | Server compromise doesn't affect communication security |
Multi-Transport Protocol
VirtuaMesh supports multiple transport protocols with automatic fallback when UDP is rate-limited or NAT traversal fails:
- WireGuard UDP (default) — Standard WireGuard UDP transport, lowest latency, preferred
- WireGuard over TCP — Automatically enabled when UDP is QoS-throttled or with symmetric NAT
- WebSocket Transport — Tunnel WireGuard packets over WebSocket for strict firewalls/proxies
- KCP over UDP — Reliable UDP transport for high packet loss networks
- DERP Relay — Fallback relay with self-hosted DERP server support
- TURN Relay — Standard TURN relay support
Transports auto-switch by priority: UDP → TCP → WebSocket → DERP → TURN, no manual configuration needed.
Data Compression
Built-in packet compression (Deflate algorithm) automatically compresses IP packets larger than 256 bytes before encryption, reducing bandwidth usage by 30-70%. Transparent to users, no configuration required.
Self-hosted DERP Server
Add custom DERP servers in the configuration file to prioritize over official DERP servers:
"natTraversal": {
"customDerpServers": [
{
"host": "derp.example.com",
"port": 443,
"verifyTls": true,
"regionName": "Self-hosted US-East",
"enabled": true,
"stunPort": 3478
}
]
}
🏠 Full Walkthrough: Remote Access to a Home NAS
Scenario: You're on a business trip in a hotel and want to access photos and files on your home NAS. The home NAS is Synology/QNAP; your computer is on the company or hotel Wi-Fi.
What you need
- One always-on device as the server (the home NAS itself, a Raspberry Pi, or an old PC all work)
- Services on the NAS you want to use (e.g. Synology Photos, Jellyfin, SMB file sharing)
Step-by-step
# Download docker-compose.prod.yml and config
mkdir -p ~/virtuamesh && cd ~/virtuamesh
# See the Server Deployment section for the config file
docker compose -f docker-compose.prod.yml up -dhttps://your-domain or http://NAS-LAN-IP:58080home-nas → copy the generated invite codevirtuamesh register --server https://your-domain --network-code your-invite-codehome-nas status in "Node List" changes to "Online" ✓virtuamesh register --server https://your-public-domain --network-code invite-code(Note: external clients need the NAS public address or domain)• Open
http://home-nas.virtuamesh.com:5000 in a browser for the Synology web UI• Type
\\home-nas.virtuamesh.com in File Explorer's address bar to see shared folders• Copy files directly over SMB — speed depends on your upload bandwidth
• In Synology Photos / DS File, "Add NAS" with server address
home-nas.virtuamesh.com• Works on 4G / Wi-Fi, instant LAN-like experience
⚡ 5-Minute Developer Track
Already comfortable with Docker, Linux, and the command line? Here's the 5-minute fast track, all via CLI.
Step 1: One-click server deployment
# Get the deployment script and config (see the Server Deployment section)
mkdir -p ~/virtuamesh && cd ~/virtuamesh
# Edit .env to fill in domain and keys
docker compose -f docker-compose.prod.yml up -d
Step 2: Install the client
# macOS
curl -fsSL https://control.virtuamesh.com/install/macos.sh | sh
# Linux
curl -fsSL https://control.virtuamesh.com/install/linux.sh | sh
# Windows (PowerShell)
iwr -useb https://control.virtuamesh.com/install/windows.ps1 | iex
Step 3: Join the network
virtuamesh init
virtuamesh register --server https://your-server.com --network-code <invite-code>
virtuamesh up
virtuamesh status
virtuamesh test-connection --target-ip <peer-virtual-ip>
Step 4: Access via MagicDNS
curl http://api-service.virtuamesh.com/health
ssh deploy@build-runner.virtuamesh.com
Step 5: Advanced config (optional)
# Enable subnet routing (expose the office network to the virtual network)
virtuamesh subnet advertise 192.168.1.0/24
# Enable exit node (route all traffic through this node)
virtuamesh exit-node enable
virtuamesh client as a build node in GitHub Actions / GitLab CI, letting build machines directly access internal services. Steps: register with a service-account token via virtuamesh register, see the Quick Reference section for register command details.
🔌 API Reference
The VirtuaMesh control plane provides a complete RESTful API. All APIs use JWT Bearer Token auth; base URL is https://your-server.com/api/v1.
Authentication
curl -H "Authorization: Bearer <JWT_TOKEN>" https://your-server.com/api/v1/nodes
How to obtain a JWT:
# 1. Log in with email/password to get a short-lived access_token + long-lived refresh_token
curl -X POST https://your-server.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"your-password"}'
# 2. Exchange refresh_token for a new access_token
curl -X POST https://your-server.com/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token":"..."}'
Node Management
Users & Permissions
DNS Management
Request & Response Example
POST /api/v1/nodes
Content-Type: application/json
Authorization: Bearer eyJhbGc...
{
"name": "build-runner-1",
"tags": ["ci", "linux"],
"acl_groups": ["developers", "ci-agents"]
}
# 201 Created
{
"id": "node_a1b2c3d4",
"name": "build-runner-1",
"hostname": "build-runner-1",
"virtual_ip": "100.64.0.42",
"auth_key": "tskey-auth-k7PqLm3vR9wX2zE8nF4hJ6tY1uA0oI5sD3cVbN9xMqW",
"created_at": "2026-06-07T08:23:11Z",
"tags": ["ci", "linux"],
"acl_groups": ["developers", "ci-agents"]
}
Retry-After and X-RateLimit-Remaining headers. Override via RateLimiting:ClientLimitPerMinute.
DERP WebSocket Bidirectional Channel
Bidirectional WebSocket channel between the client and the DERP relay server (for relaying WireGuard packets when NAT traversal fails), carried by the WireGuard-over-WebSocket protocol. There is no JSON event subscription on the business layer:
// Client connects to DERP relay via WireGuard over WebSocket
// (handled internally by the virtuamesh client process, no business code needed)
const ws = new WebSocket('wss://your-server.com/derp');
🚀 Performance Tuning
VirtuaMesh's default config handles most scenarios, but if you're chasing peak performance or hitting bandwidth issues, refer to the tuning options below.
1. MTU tuning
Default MTU 1420 fits most networks. If your network path has no PPPoE/VPN nesting, you can bump it to 1500 for higher throughput:
network:
mtu: 1500 # Only when the link has no nested VPN
If you traverse multiple NAT levels or complex networks, drop to 1280 instead:
network:
mtu: 1280 # Extreme network conditions
2. Enable kernel mode
On Linux, kernel mode gives a 2-5x throughput boost:
sudo apt install wireguard-tools
# Config file
network:
wireguard_mode: "kernel"
3. Deploy multi-region DERP
Latency between nodes and DERP should stay under 50ms. Globally distributed teams should deploy one DERP per major region:
# derp-asia.yaml
{
"DerpServer": {
"Enabled": true,
"Port": 443,
"Hostname": "derp-asia.your-domain.com",
"Region": "ap-east"
}
}
# derp-eu.yaml
{
"DerpServer": {
"Enabled": true,
"Port": 443,
"Hostname": "derp-eu.your-domain.com",
"Region": "eu-west"
}
}
Then list all DERP domains in the client config — VirtuaMesh will auto-pick the closest:
derp:
servers:
- url: "https://derp-asia.your-domain.com"
region: "ap-east"
- url: "https://derp-eu.your-domain.com"
region: "eu-west"
- url: "https://derp-na.your-domain.com"
region: "us-east"
4. Persistent connection keepalive
Maintain long-lived connections between nodes to avoid re-hole-punching on every request:
network:
keepalive: 25 # Send a keepalive packet every 25 seconds (seconds)
Shorter intervals mean faster connection setup but more traffic. 25s is fine for home networks; 15s is better behind enterprise NAT.
5. Enable multi-core processing
The server uses a single core for encryption by default. Servers with more CPUs can enable multi-core:
# docker-compose.prod.yml
services:
api:
environment:
- ASPNETCORE_THREADPOOL_MINTHREADS=Environment.ProcessorCount
- ASPNETCORE_THREADPOOL_MAXTHREADS=512
Performance monitoring
View real-time performance data:
# Node performance
virtuamesh status --verbose
# Traffic stats
virtuamesh traffic
virtuamesh top
# DERP relay load
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
https://your-server.com/api/v1/derp-servers/healthy
- 2 nodes P2P same city: 800-950 Mbps (limited by WireGuard encryption performance)
- Cross-province P2P: 200-500 Mbps
- Cross-ocean DERP relay: 80-150 Mbps (depends on DERP egress bandwidth)
- Single CPU core handles ~1 Gbps encrypt/decrypt (with AES-NI acceleration)
🔐 Security Best Practices
5 things everyone should do
-
Enable strong passwords / 2FA
Admin console accounts must enable two-factor authentication. Setting path: Account Settings → Security → Enable TOTP 2FA.
-
Use sub-accounts, don't share accounts
Give each family or team member their own account; you can revoke permissions individually if issues arise.
-
Rotate Auth Keys regularly
In the admin console → Node Management, regenerate the invite code, then use
virtuamesh register --forceto re-register the node and rotate credentials. -
Enable audit logs
Audit logs are enabled by default; view them in Admin Console → Audit Logs.
-
Restrict admin console IP access
Use an Nginx reverse proxy to allow only corporate IP ranges to access the
/manager/path:location /manager/ { allow 203.0.113.0/24; # Corporate IP range deny all; }
ACL: Fine-grained access control
ACL (Access Control List) decides which nodes can access which, and on which ports.
Basic syntax
acls:
- action: accept
src:
- "group:developers"
dst:
- "group:production:*"
ports:
- "443"
- "22"
- action: deny
src:
- "group:guests"
dst:
- "group:production"
Common rule examples
View and validate ACL rules
# List all rules (with hit stats)
virtuamesh acl list
# View a single rule's details
virtuamesh acl show <rule-id>
Advanced security topics
Key rotation strategy
# Auto-rotation: server config
key_rotation:
enabled: true
interval: 7d # Rotate every 7 days
grace_period: 24h # Old key grace period
notify_before: 1h # Notify 1 hour in advance
WireGuard cipher selection
The default ChaCha20-Poly1305 is secure enough. If you have hardware acceleration, you can pick AES-256-GCM:
network:
crypto:
algorithm: "chacha20-poly1305" # or "aes-256-gcm" (requires AES-NI support)
Audit log format
# Default JSON Lines format, can feed into ELK / Loki
{
"timestamp": "2026-06-07T10:23:45Z",
"event": "node.online",
"node_id": "node_a1b2c3",
"src_ip": "100.64.0.42",
"user_agent": "virtuamesh/1.2.3"
}
Compliance & data residency
Enterprise edition supports:
- Designated DERP regions (data stays in-country)
- Private deployment of the server
- SOC 2 / ISO 27001 audit logs
- SSO integration (SAML / OIDC)
🚀 Command Quick Reference
One-page quick reference. Ctrl+F to search as needed.
Client lifecycle
virtuamesh init # Initialize local config
virtuamesh register --server <url> --network-code <code> # Join network
virtuamesh up # Start connection
virtuamesh down # Disconnect
virtuamesh status # Show status
virtuamesh service install # Install system service (auto-start on boot)
virtuamesh service start # Start background service
virtuamesh service stop # Stop background service
virtuamesh service restart # Restart service
Diagnostics
virtuamesh status --verbose # Verbose status
virtuamesh test-connection --target-ip <ip> # Test connectivity
virtuamesh test-connection --all # Test all peers
virtuamesh top # Real-time network monitor
virtuamesh logs follow # Live logs
virtuamesh logs show --level debug # Debug logs
Network & ACL
virtuamesh peers # All peers
virtuamesh subnet advertise 192.168.1.0/24 # Expose subnet
virtuamesh subnet list # List subnets
virtuamesh subnet unadvertise 192.168.1.0/24 # Unexpose subnet
virtuamesh exit-node enable # Enable exit node
virtuamesh exit-node disable
virtuamesh acl list # List ACL rules
virtuamesh acl show <rule-id> # View rule details
DNS
virtuamesh dns resolve <name> # Resolve
virtuamesh dns resolve --verbose <name> # Verbose resolve
virtuamesh dns stats # DNS stats
virtuamesh dns cache clear # Clear cache
virtuamesh dns register --hostname X --network-id <guid> --node-id <guid>
virtuamesh dns list --network-id <guid>
virtuamesh dns unregister --network-id <guid> --node-id <guid>
What is VirtuaMesh
VirtuaMesh is a zero-trust identity-based networking platform built on the WireGuard protocol. It establishes a secure virtual mesh network between devices via encrypted peer-to-peer connections. All traffic is encrypted with WireGuard's ChaCha20-Poly1305, ensuring only devices in the same network can communicate with each other.
VirtuaMesh creates a peer-to-peer mesh network rather than the traditional centralized VPN architecture. This means devices communicate directly whenever possible (P2P), avoiding the latency and single-point-of-failure issues of a central gateway in legacy VPNs. When P2P isn't available, DERP relay servers automatically take over to keep connections always available.
Core Advantages
Differences from legacy VPN
| Feature | Legacy VPN | VirtuaMesh |
|---|---|---|
| Network architecture | Centralized gateway | Distributed P2P mesh |
| Encryption | Tunnel encryption (gateway can decrypt) | End-to-end encryption (zero knowledge) |
| Connection mode | All traffic through the center | Direct device-to-device + DERP fallback |
| NAT traversal | Requires port forwarding | Automatic traversal |
| Single point of failure | Gateway down = whole network down | No central node, highly available |
| Access control | Network-layer based | Identity-based (zero trust) |
Quick Start
Set up a VirtuaMesh virtual network in just a few simple steps. No deep networking knowledge required — done in minutes.
-
Deploy the control plane
One-click server start with Docker Compose, including the API server, MySQL database, Redis cache, and DERP relay.
cd /path/to/VirtuaMesh/Server docker-compose -f docker-compose.prod.yml up -d -
Install the client
Install the VirtuaMesh client on each device that needs to join the network.
# Windows iwr -useb https://control.virtuamesh.com/install/windows.ps1 | iex # macOS curl -fsSL https://control.virtuamesh.com/install/macos.sh | sh # Linux curl -fsSL https://control.virtuamesh.com/install/linux.sh | sh -
Register the node
Register the client with the control plane to get node credentials and a virtual IP.
virtuamesh register --server https://your-server.com --network-code <CODE> -
Start the connection
Start the WireGuard tunnel and connect to the virtual network.
virtuamesh up -
Verify the connection
Check node status and connectivity.
virtuamesh status virtuamesh test-connection --target-ip <peer-virtual-ip>
Server Deployment
Requirements
| Item | Minimum | Recommended |
|---|---|---|
| OS | Ubuntu 20.04+ / Debian 11+ | Ubuntu 22.04 LTS |
| CPU | 2 cores | 4 cores+ |
| Memory | 4 GB | 8 GB+ |
| Disk | 20 GB SSD | 50 GB+ SSD |
| Docker | 20.10+ | Latest stable |
| Docker Compose | 2.0+ | Latest stable |
Deployment Steps
-
Install Docker
curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER -
Configure environment variables
Copy
.env.exampleto.envand fill in the required config:MYSQL_ROOT_PASSWORD=your_strong_root_password MYSQL_PASSWORD=your_strong_mysql_password REDIS_PASSWORD=your_strong_redis_password JWT_KEY=YourSuperSecretKeyHereMakeItLongEnough32Chars! DOMAIN_NAME=your-domain.com -
Configure the firewall
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 3478/udp sudo ufw enable -
Start the services
docker-compose -f docker-compose.prod.yml up -d
config/nginx/ directory in the project for example configs.
Method 2: systemd + Self-Contained Publish (No Docker)
Use this when you want to run VirtuaMesh as a native system service to avoid container overhead, or when the deployment environment doesn't support Docker. Underlying dependencies: .NET 10 runtime + SQLite. No MySQL/Redis required (you can still point to an external Redis for distributed cache if needed):
-
Prepare Linux environment
You need the .NET 10 SDK on the build machine (only for building; the published artifact is a self-contained executable so the target server does NOT need .NET installed):
# Ubuntu 22.04: install .NET 10 SDK wget https://dot.net/v1/dotnet-install.sh -O /tmp/dotnet-install.sh chmod +x /tmp/dotnet-install.sh sudo /tmp/dotnet-install.sh --channel 10.0 --install-dir /usr/share/dotnet sudo ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet dotnet --version # should print 10.x.x -
Build a self-contained Linux publish
git clone https://github.com/virtuamesh/virtuamesh.git cd virtuamesh/Server dotnet publish src/VirtuaMesh.Api -c Release \ -r linux-x64 --self-contained true \ -o ./publish/linux-x64 -
Upload to the server and extract
REMOTE_DIR=/data/virtuamesh/server ssh user@server "sudo mkdir -p $REMOTE_DIR && sudo chown \$USER:\$USER $REMOTE_DIR" scp -r ./publish/linux-x64/* user@server:$REMOTE_DIR/ ssh user@server "chmod +x $REMOTE_DIR/VirtuaMesh.Api" -
Generate the secrets file
The project uses
/etc/virtuamesh/secrets.envto inject the JWT and DERP registration secrets (avoiding hardcoding in config files). Run the project's bundled key-rotation script:sudo mkdir -p /etc/virtuamesh sudo bash scripts/rotate-secrets.sh # generates VIRTUAMESH_JWT_KEY, etc. sudo chmod 600 /etc/virtuamesh/secrets.env -
Place the production config
sudo cp scripts/appsettings.Production.example.json $REMOTE_DIR/appsettings.Production.json sudo vim $REMOTE_DIR/appsettings.Production.json # adjust Database/StunServer/P2P nodes -
Initialize the SQLite database
SQLite is recommended for single-node deployments (zero dependencies, zero ops). For MySQL cluster mode see
docker-compose.prod.ymlfor the connection-string format:scp scripts/database-init-sqlite.sql user@server:/tmp/ ssh user@server "cd $REMOTE_DIR && sqlite3 virtuamesh.db < /tmp/database-init-sqlite.sql" -
Install the systemd unit
sudo cp scripts/virtuamesh-api.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable virtuamesh-api sudo systemctl start virtuamesh-api sudo systemctl status virtuamesh-api # should show active (running) -
Configure firewall and log rotation
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 53478/udp # STUN (differs from Docker deploy: default 53478) # journald retains logs by default; for long-term archival see scripts/ logrotate configs
| Dimension | Docker deploy | systemd deploy |
|---|---|---|
| Startup speed | Medium (image pull + container orchestration) | Fast (direct process) |
| Resource overhead | +1 container abstraction layer (~100MB RAM) | Minimal |
| Upgrade / rollback | Switch image tag | Manual file replace + service restart |
| Default ports | 443 / 3478 | 58443(HTTPS) / 53478(STUN) |
| Database | MySQL + Redis (containers) | SQLite (local file, external Redis optional) |
| Best for | Beginners, "one-click" experience seekers | Ops veterans, internal production environments |
Method 3: Kubernetes Deployment (Production-Grade HA)
Use this for multi-replica HA, cross-node failover, and auto-scaling (HPA). The project ships a complete Server/k8s/ Kustomize-managed YAML manifest set including API / DERP / Redis / Ingress / HPA / NetworkPolicy:
-
Prerequisites
- Kubernetes 1.24+ cluster (any distribution: EKS / AKS / GKE / self-hosted)
- kubectl + kustomize installed
- A StorageClass configured (for Redis persistence)
- Nginx Ingress Controller (or equivalent) deployed
-
Build and push images
# Build and push docker build -t registry.example.com/virtuamesh/api:1.0.0 -f src/VirtuaMesh.Api/Dockerfile . docker build -t registry.example.com/virtuamesh/derp:1.0.0 -f src/VirtuaMesh.DerpServer/Dockerfile . docker push registry.example.com/virtuamesh/api:1.0.0 docker push registry.example.com/virtuamesh/derp:1.0.0 -
Configure secrets and domain
# 1) Edit secret.yaml to fill in VIRTUAMESH_JWT_KEY etc. # (recommend sealed-secrets or external-secrets for production) vim k8s/secret.yaml # 2) Edit ingress.yaml and change the host to your domain vim k8s/ingress.yaml # 3) If you need a different image tag, edit kustomization.yaml sed -i 's|latest|1.0.0|g' k8s/kustomization.yaml -
One-shot deploy
kubectl apply -k k8s/ # Verify kubectl -n virtuamesh get pods kubectl -n virtuamesh get svc kubectl -n virtuamesh get ingress -
Check auto-scaling status
kubectl -n virtuamesh get hpa # NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS # virtuamesh-api Deployment/virtuamesh-api 45%/70% 2 10 3
- Zero-downtime rolling updates:
maxUnavailable: 0+maxSurge: 1with readinessProbe for smooth releases - NetworkPolicy: by default only allows Ingress Controller → API and API → Redis traffic; all other cross-pod traffic is DROP (open up as needed)
- HPA strategy: CPU threshold 70%, min 2 / max 10 replicas — load-test before tuning in production
- Multi control plane: for cross-cluster DR, set
MULTI_REGISTRY_ENABLED=trueso this cluster's DERP registers with both primary and backup control planes
Method 4: Windows MSI Installer (GUI Deploy)
Use this for Windows Server users who want a zero-config install (includes EULA + VC++ runtime + automatic Windows service registration). The project uses the WiX 3.14 toolchain:
-
Download the MSI
From GitHub Releases or
https://control.virtuamesh.com/download/, downloadvirtuamesh-server-windows-x64.msi(self-contained .NET 10 runtime, ~80MB). -
Double-click to install
Fill in the wizard:
- Install path (default
C:\Program Files\VirtuaMesh\Server) - Data directory (default
C:\ProgramData\VirtuaMesh) - HTTPS certificate (.pfx path + password)
- Listen port (default 58443)
- Install path (default
-
Service auto-starts
The MSI automatically registers a Windows service named
VirtuaMesh.Apiand configures restart-on-failure after 3 attempts (viasc failure).# Verify service status sc query VirtuaMesh.Api # View logs Get-EventLog -LogName Application -Source VirtuaMesh.Api -Newest 50
DERP Relay Configuration
DERP (Detoured Encrypted Relay Protocol) is VirtuaMesh's relay server protocol. When two nodes can't establish a P2P direct connection (e.g. both are behind symmetric NAT), the DERP server relays encrypted traffic to keep the connection available.
Port reference
| Port | Protocol | Use |
|---|---|---|
| 443 | TCP | DERP relay server (HTTPS) |
| 3478 | UDP | STUN server (NAT traversal probe) |
Configuration Example
{
"DerpServer": {
"Enabled": true,
"Port": 443,
"StunPort": 3478,
"Hostname": "derp.your-region.com",
"UseHttps": true,
"MaxConnections": 1000,
"Region": "ap-east"
}
}
Standalone DERP Relay Deployment (Cross-Region Latency)
DERP relay is a stateless service (no database / JWT / STUN config needed) and can be deployed independently in different geographic regions, registering with the primary control plane via MultiRegistry. The project ships a virtuamesh-derp.service systemd unit + virtuamesh-derp-deploy.sh deploy script:
-
Build and package
dotnet publish src/VirtuaMesh.DerpServer -c Release \ -r linux-x64 --self-contained true \ -o ./publish/derp-linux-x64 cd ./publish/derp-linux-x64 zip -r /tmp/VirtuaMesh-DerpServer-Linux.zip . -
Upload to the target region's server
scp /tmp/VirtuaMesh-DerpServer-Linux.zip user@derp-ap-east:/tmp/ scp scripts/virtuamesh-derp.service user@derp-ap-east:/tmp/ scp scripts/derp-appsettings.Production.json user@derp-ap-east:/tmp/ -
Deploy on the target server
mkdir -p /data/virtuamesh/derp cd /data/virtuamesh/derp unzip /tmp/VirtuaMesh-DerpServer-Linux.zip cp /tmp/derp-appsettings.Production.json ./appsettings.Production.json # Edit ControlPlaneUrl to point to your primary control plane vim appsettings.Production.json chmod +x VirtuaMesh.DerpServer sudo cp /tmp/virtuamesh-derp.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now virtuamesh-derp sudo systemctl status virtuamesh-derp -
Verify registration
Once deployed, DERP auto-registers with the primary control plane via
POST /api/derp-servers. You should see the new node in Admin Console → DERP Relays, statusHealthy.
If DERP and the main API are on the same machine and share the certificate directory, add After=virtuamesh-api.service to the DERP systemd unit to avoid a race condition where DERP starts before the main API and can't find the cert. For production, prefer separate deployments (different machines / AZs) for cleaner failure-domain isolation.
Client Usage
These three commands have a strict serial dependency and must run in this exact order. Skipping or reordering any of them will fail:
init— generate the local config file and WireGuard key pair (must run first; running register without init fails because the config file doesn't exist)register— register the node with the control plane using the invite code, receive a virtual IP and tunnel config (must run after init)up— bring up the WireGuard interface and establish the connection (must run after register, otherwise you'll see "Control plane server URL not configured" or "Virtual IP not found")
Common error scenarios:
$ virtuamesh register --server https://control.virtuamesh.com --network-code ABC123
Error: Configuration file does not exist. Please run `virtuamesh init` first.
$ virtuamesh up
Error: Control plane server URL not configured. Please run the register command first.
Re-initialization: use init --force to wipe old config; use register --force to force re-registration (e.g. when rotating keys).
Install the client
| Platform | Install command |
|---|---|
| Windows | iwr -useb https://control.virtuamesh.com/install/windows.ps1 | iex |
| macOS | curl -fsSL https://control.virtuamesh.com/install/macos.sh | sh |
| Linux | curl -fsSL https://control.virtuamesh.com/install/linux.sh | sh |
Basic Usage Flow
-
Initialize config
Generate the default config file and WireGuard key pair.
virtuamesh init -
Register with the control plane
Register the node using the token provided by the admin.
virtuamesh register --server https://your-server.com --network-code <CODE> -
Start the network connection
Establish the WireGuard encrypted tunnel and connect to the virtual network.
virtuamesh up -
View connection status
Show current node info and the peer list.
virtuamesh status virtuamesh peers
virtuamesh service install to install a system service for auto-start on boot, virtuamesh service start to start the background service, and virtuamesh service stop to stop the background service.
MagicDNS
MagicDNS is VirtuaMesh's built-in DNS service that automatically assigns readable domain names to every device in the virtual network, letting you access any node without memorizing IP addresses. It builds on the core design of Tailscale MagicDNS and adds capabilities like automatic domain registration, custom records (A/AAAA/CNAME/TXT), and reverse resolution.
How it works
When a node joins a VirtuaMesh network, the control plane automatically registers a DNS record mapping the node's hostname to its virtual IP address. The client configures a local DNS search domain so devices within the virtual network can reach each other directly using short hostnames.
# Full domain format
my-server.virtuamesh.com → 100.64.0.3
# Short-name access (within the same network)
my-server → 100.64.0.3
# Multi-level subdomain
api.production.virtuamesh.com → 100.64.1.10
Enable & Configure
MagicDNS is enabled by default. You can control its behavior in the client config file:
network:
magic_dns:
enabled: true
suffix: "virtuamesh.com"
| Parameter | Default | Description |
|---|---|---|
enabled | true | Whether MagicDNS is enabled |
suffix | virtuamesh.com | DNS suffix; every node's domain ends with this |
Custom DNS records
Besides auto-registered node records, you can add custom DNS records to map dedicated domains for internal services. Supports A, AAAA, CNAME, and TXT record types.
# Register a hostname for a node via CLI (node must have joined the network first)
virtuamesh dns register --hostname "grafana" --network-id <guid> --node-id <guid>
# View all DNS records for a given network
virtuamesh dns list --network-id <guid>
# Unregister a node's hostname
virtuamesh dns unregister --network-id <guid> --node-id <guid>
| Record type | Description | Example |
|---|---|---|
| A | IPv4 address mapping | grafana.internal → 100.64.0.5 |
| AAAA | IPv6 address mapping | gateway.internal → fd7a:115c:a1e0::1 |
| CNAME | Domain alias | docs.internal → web-server.virtuamesh.com |
| TXT | Text record | _service.internal → "version=2.1.0" |
DNS diagnostic commands
VirtuaMesh provides a set of DNS diagnostic commands to help troubleshoot DNS resolution issues:
# Resolve a given domain
virtuamesh dns resolve my-server
# View DNS stats
virtuamesh dns stats
# Clear the local DNS cache
virtuamesh dns cache clear
Common use cases
Scenario 1: Microservice internal communication
In a microservice architecture, services reach each other via MagicDNS domains — no need to hardcode IP addresses. When services migrate or scale, DNS records update automatically; no config changes required.
# Service-to-service calls
curl http://api-gateway:8080/v1/users
curl http://redis-cache:6379
curl http://kafka-broker:9092
Scenario 2: Internal service domain mapping
For internal services like Grafana, Redis, and Kafka, use virtuamesh dns register to register hostnames for nodes and map stable internal domains, avoiding hardcoded IPs.
# Register hostnames for a node (requires the owning network ID and node ID)
virtuamesh dns register --hostname "grafana" --network-id <guid> --node-id <guid>
virtuamesh dns register --hostname "docs" --network-id <guid> --node-id <guid>
Troubleshooting
DNS resolution failure
# View DNS stats
virtuamesh dns stats
# Clear the DNS cache
virtuamesh dns cache clear
# View the detailed resolution process
virtuamesh dns resolve --verbose my-server
Short name cannot be resolved
If a short name (e.g. my-server) cannot be resolved, check:
- Whether MagicDNS is enabled:
virtuamesh dns statsto view stats - Whether the DNS search domain is configured correctly
- Whether the target node is online and has a registered DNS record
Split DNS not taking effect
Confirm that the domain suffix in the Split DNS config matches the domain actually being queried. Use virtuamesh dns check-availability --hostname <name> to check whether a hostname is available for registration.
🌐 Exit Node
Exit Node lets all internet traffic from a device in the network be forwarded out through another designated node. It's like wrapping the device in a "secure proxy" — all outbound access originates from the exit node's network.
Typical uses: Safe browsing over the corporate network while traveling / cross-border access to domestic systems / bypassing public Wi-Fi snooping / unifying egress IPs to meet compliance audit requirements.
How it works
After you enable an exit node on the client, the device's all non-LAN traffic is sent through the WireGuard tunnel to the exit node, which accesses the internet on your behalf and returns the result along the same path. The whole path is end-to-end encrypted; intermediate nodes (including DERP relays) cannot decrypt the traffic.
- The exit node needs a stable internet connection and sufficient bandwidth
- Enabling an exit node adds latency (one extra forwarding hop); pick a node with good network quality
- All outbound traffic rules of the exit node's network apply to you (e.g. firewalls, content filtering)
- Exit Node functionality is limited in kernel mode; userspace WireGuard mode is recommended
How to configure an Exit Node
This device will handle forwarding traffic. Pick a device with a stable network and ample bandwidth (e.g. an office desktop, a cloud server, a NAS).
Turn on "Allow as exit node" in the client settings, or use the command:
virtuamesh exit-node enable
Select the exit node to use in the client settings, or use the command:
virtuamesh exit-node use <node-id>
Visit https://ifconfig.me or a similar site and confirm the displayed IP is the exit node's IP, not your local network's IP.
Common commands
virtuamesh exit-node enable # Enable exit node (allow this machine to act as exit)
virtuamesh exit-node disable # Disable exit node
virtuamesh exit-node status # Show exit node status
virtuamesh exit-node use server-01 # Use the specified exit node
virtuamesh exit-node off # Don't use an exit node (direct)
Use cases
Differs from a regular proxy (VPN)
| Comparison | Legacy VPN proxy | VirtuaMesh Exit Node |
|---|---|---|
| Deployment | Need to buy/rent a VPN service | Use your own device as exit, zero cost |
| Data sovereignty | Traffic passes through a third-party provider | Forwarded entirely between nodes you control |
| Simultaneous networking | Can only browse, no internal mesh | Both egress browsing and internal device access |
| Encryption strength | Depends on the provider | WireGuard end-to-end encryption, self-controlled |
| Switching exit | Need to disconnect and reconnect | Real-time switch, internal connections not interrupted |
WireGuard Mode
VirtuaMesh supports two WireGuard implementation modes, selectable based on platform and performance needs.
| Mode | Config value | Description |
|---|---|---|
| Userspace | userspace |
WireGuard.NET cross-platform userspace implementation (default); no extra dependencies, best compatibility |
| Kernel | kernel |
Linux kernel module mode (Linux only); requires wireguard-tools, better performance |
kernel mode is selected but the system doesn't support it, VirtuaMesh automatically falls back to userspace mode to keep the service running.
Configuration example
network:
interface_name: "virtuamesh0"
virtual_ip: ""
mtu: 1280
wireguard_mode: "userspace" # "userspace" or "kernel"
Install kernel mode dependencies
# Ubuntu/Debian
sudo apt-get install wireguard-tools
# CentOS/RHEL
sudo yum install wireguard-tools
CLI Command Reference
Node management
| Command | Description | Example |
|---|---|---|
init | Initialize local config | virtuamesh init |
register | Register with the control plane | virtuamesh register --server <url> --network-code <CODE> |
Network connection
| Command | Description | Example |
|---|---|---|
up | Start and connect to the network | virtuamesh up |
down | Disconnect and stop | virtuamesh down |
service install | Install as a system service (auto-start on boot) | virtuamesh service install |
service start | Start the background service | virtuamesh service start |
service stop | Stop the background service | virtuamesh service stop |
service restart | Restart the background service | virtuamesh service restart |
Status queries
| Command | Description | Example |
|---|---|---|
status | Show connection status | virtuamesh status |
peers | Show the peer list | virtuamesh peers |
nodes | List network nodes | virtuamesh nodes |
top | Real-time network monitor | virtuamesh top |
traffic | View traffic stats | virtuamesh traffic |
Network diagnostics
| Command | Description | Example |
|---|---|---|
test-connection | Test connectivity to a peer | virtuamesh test-connection --target-ip <ip> |
test-connection --all | Test all peers | virtuamesh test-connection --all |
logs | View logs | virtuamesh logs follow |
Utility commands
| Command | Description | Example |
|---|---|---|
version | Show version | virtuamesh version |
gen-key | Generate a WireGuard private key | virtuamesh gen-key |
pub-key | Derive a public key from a private key | virtuamesh pub-key --private-key <key> |
completion | Generate a shell completion script | virtuamesh completion |
interactive | Start an interactive shell | virtuamesh interactive |
DNS commands
| Command | Description | Example |
|---|---|---|
dns resolve | Resolve a domain | virtuamesh dns resolve my-server |
dns stats | View DNS stats | virtuamesh dns stats |
dns cache clear | Clear the DNS cache | virtuamesh dns cache clear |
dns cache status | View DNS cache status | virtuamesh dns cache status |
dns register | Register a hostname for a node | virtuamesh dns register --hostname "app" --network-id <guid> --node-id <guid> |
dns unregister | Unregister a node hostname | virtuamesh dns unregister --network-id <guid> --node-id <guid> |
dns list | List a network's DNS records | virtuamesh dns list --network-id <guid> |
dns check-availability | Check if a hostname is available for registration | virtuamesh dns check-availability --hostname "app" |
dns search | Search DNS records | virtuamesh dns search <query> |
dns reverse | Reverse resolution | virtuamesh dns reverse <ip> |
Ports & Protocols
Server ports
| Port | Protocol | Service | Description |
|---|---|---|---|
| 80 | TCP | HTTP | API reverse proxy (redirects to HTTPS) |
| 443 | TCP | HTTPS | API + gRPC + DERP + Web admin UI |
| 3478 | UDP | STUN | NAT traversal probe |
| 3306 | TCP | MySQL | Database (internal access only) |
| 6379 | TCP | Redis | Cache (internal access only) |
Client ports
| Port | Protocol | Description |
|---|---|---|
| 51820 | UDP | WireGuard default listen port |
Configuration Reference
The client config file uses YAML format; default path is ~/.virtuamesh/config.yaml.
version: "1.0"
node:
id: ""
hostname: ""
control:
server_url: "https://control.virtuamesh.com"
node_token: ""
network:
interface_name: "virtuamesh0"
virtual_ip: ""
mtu: 1420
wireguard_mode: "userspace"
magic_dns:
enabled: true
suffix: "virtuamesh.com"
exit_node:
enabled: false
subnet_router:
enabled: false
derp:
servers: []
nat_traversal:
stun_servers:
- "stun.l.google.com:19302"
- "stun.cloudflare.com:3478"
turn_servers: []
logging:
level: info
retained_days: 30
max_file_size_mb: 10
max_file_count: 7
console_output: true
✅ Pre-deployment Checklist
Before you start deploying, go through each item below. Checking them off one by one helps you avoid 90% of common pitfalls.
🖥️ Server environment
🔐 Accounts & keys
🌐 Network connectivity
💡 Choose a deployment mode
Different scenarios call for different deployment styles — pick the one that fits:
| Your situation | Recommended deployment | Notes |
|---|---|---|
| Personal / home use, < 10 devices | Single-host Docker Compose | A 2-core 4GB cloud VPS is enough; costs around $5-8/month |
| Small team / studio, 10-50 devices | Single server + multi-region DERP | Primary control + 1-2 DERP relays (Hong Kong / Tokyo recommended) |
| Company / 50+ devices | Kubernetes cluster deployment | Stateless control plane scales horizontally; DERP multi-region |
| Compliance required (data stays in-country) | Private deployment + private DERP | Full stack deployed on-prem; only essential outbound ports opened |
⚖️ Comparison with Similar Products
Choosing is hard — here's a horizontal comparison of mainstream networking solutions to help you decide in 5 minutes.
| Feature | VirtuaMesh | Tailscale | ZeroTier | Nebula | WireGuard native |
|---|---|---|---|---|---|
| Self-hosted control plane | ✅ Yes (data sovereignty) | ❌ Uses official cloud | ⚠️ Self-hostable (planet/moon) | ✅ Yes (lighthouse) | ✅ DIY |
| End-to-end encryption | ✅ WireGuard | ✅ WireGuard | ✅ Self-developed protocol | ✅ Self-developed protocol | ✅ WireGuard |
| NAT traversal | ✅ Automatic | ✅ Automatic | ✅ Automatic | ✅ Automatic | ❌ Manual port forwarding |
| Relay fallback | ✅ DERP multi-region | ✅ DERP | ✅ Planet | ✅ Lighthouse | ❌ None |
| MagicDNS (auto domains) | ✅ Auto-registration + custom records | ✅ Included | ❌ None | ❌ None | ❌ Self-configured |
| ACL access control | ✅ Tags + ports + time | ✅ ACL rules | ⚠️ Basic rules | ⚠️ Basic | ❌ None |
| Web admin console | ✅ Full UI | ✅ Full UI | ⚠️ Third-party | ❌ None | ❌ None |
| REST API | ✅ Complete | ✅ Complete | ⚠️ Partial | ❌ None | ❌ None |
| Open-source license | Apache 2.0 | Partially open | GPL v2 | MIT | GPL v2 |
| Free for commercial use | ✅ Completely free | ⚠️ Free for personal, paid for enterprise | ✅ Free | ✅ Free | ✅ Free |
| Learning curve | ⭐⭐ Low (5-min onboarding) | ⭐⭐ Low | ⭐⭐⭐ Medium | ⭐⭐⭐⭐ High | ⭐⭐⭐⭐⭐ Very high |
- You want data sovereignty — no third-party cloud in the path
- You need a full toolchain: web UI, ACL, API
- Your team has hybrid cloud / IoT onboarding needs
- You want to avoid Tailscale Business device-count limits
- Pure personal, < 3 devices, can't be bothered to operate: pick Tailscale
- Only need to bridge two LANs: pick ZeroTier / Nebula
- Chasing extreme performance / embedded: use WireGuard directly
- Already have an OpenVPN stack: stick with OpenVPN for now
🩺 Troubleshooting Flowchart
Don't panic when something goes wrong — follow the flow below step by step. 99% of issues are resolved in the first 3 steps.
One-click diagnostics
Run this command first — it automatically tests connectivity to all peers:
virtuamesh test-connection --all
The output shows latency and packet loss to each node, helping you quickly locate the problematic node.
Decision flowchart
Common symptom quick reference
| Symptom | 90% cause | Fix |
|---|---|---|
up shows offline |
Server port 443 blocked by firewall | Open in both cloud provider security group and server ufw |
Status online but ping fails |
ACL rule not allowing | virtuamesh acl list to view rules |
Short name my-nas won't resolve |
MagicDNS not enabled or cache expired | virtuamesh dns cache clear to refresh cache |
| P2P keeps falling back to DERP | Both sides behind symmetric NAT | Deploy a closer DERP or use IPv6 |
| Speed far below expected | MTU too small or multiple relays | Adjust MTU to 1420; enable kernel mode |
| Client keeps reconnecting | Server time out of sync | sudo ntpdate time.google.com |
| Works on phone, not on PC | PC firewall / antivirus | Temporarily disable and retry; allow 51820/UDP |
| Windows says insufficient permissions | Not running as administrator | Right-click → Run as administrator |
Viewing logs
# Client live logs
virtuamesh logs follow
# Client debug logs (more detail)
virtuamesh logs show --level debug
# Server logs (Docker deployment)
docker logs -f virtuamesh-api
docker logs -f virtuamesh-derp
# Server logs (systemd deployment)
journalctl -u virtuamesh-api.service -f
# Filter client logs by keyword
virtuamesh logs show --level error
virtuamesh status --verbose and virtuamesh test-connection --all and email it to support@virtuamesh.com — the author usually replies within 24 hours.
FAQ
How do I view node connection status?
virtuamesh status
This command shows the current node's virtual IP, connection status, number of online peers, and more.
What if P2P connection fails?
VirtuaMesh automatically falls back to a DERP relay server to keep the connection available. If latency is high, consider deploying a DERP server in a closer region. Use virtuamesh test-connection --all to test connectivity to all peers.
How do I view logs?
# Server logs (Docker deployment)
docker-compose -f docker-compose.prod.yml logs -f api
# Server logs (systemd deployment)
journalctl -u virtuamesh-api.service -f
# Server log files
tail -f /data/virtuamesh/server/logs/virtuamesh-*.log
# Client logs
virtuamesh logs follow
virtuamesh logs show --level error
How do I update the client?
The client has a built-in auto-update feature that checks the server's /api/v1/updates/latest endpoint on startup and downloads the new version automatically. You can also trigger an update for a specific node from the admin console → Node Management.
What dependencies does Linux kernel mode need?
The kernel WireGuard mode requires wireguard-tools:
# Ubuntu/Debian
sudo apt-get install wireguard-tools
# CentOS/RHEL
sudo yum install wireguard-tools
How do I configure an Exit Node?
Enable exit_node.enabled: true in the client config, then designate that node as an exit node. All traffic from other nodes will be routed through it. Note: Exit Node functionality is limited in kernel mode.
How do I configure a Subnet Router?
Enable subnet_router.enabled: true in the client config to expose the local subnet to the VirtuaMesh network so other nodes can reach devices in the local subnet.
What if MagicDNS short names can't be resolved?
First use virtuamesh dns stats to view DNS stats, then use virtuamesh dns resolve --verbose <name> to see the detailed resolution process. Common causes: MagicDNS not enabled, target node offline, or DNS cache expired (use virtuamesh dns cache clear to clear the cache).
How do I configure a custom domain for an internal service?
Use the virtuamesh dns register command to register a hostname for a node. For example: virtuamesh dns register --hostname "grafana" --network-id <guid> --node-id <guid>. After registration you can access the node via grafana.virtuamesh.com.
🎉 What to do next after deployment?
Reaching this section means your network is up and running. Below is a follow-up roadmap for both beginners and developers, ordered from shallow to deep — each step tells you what specific problem it solves.
Click any path title below to expand its content. The open/closed state is remembered automatically and persists across visits.
1
Pure home user
Just want to use it, no fuss
Pure home user
Just want to use it, no fuss
- Give each device a memorable name: In Admin Console → Node List → Edit Device, rename "my-macbook-pro" to "My Laptop" or "Pixel-7" to "Wife's Phone." Then
ping My-Laptopfinds it. - Enable MagicDNS: In Admin Console → Network Settings, enable MagicDNS so clients can access devices by name instead of IP.
- Expose the NAS to all devices: On the NAS, configure the VirtuaMesh client as a "subnet router" (see Remote NAS walkthrough); all home devices can then reach the NAS across networks.
- Bind a fixed domain (optional): At your domain registrar, point an A record at your server's public IP so you can access home services from outside via the domain.
- Check the admin console regularly: The dashboard shows online devices, recent traffic, and alerts. If you see an unfamiliar login or stranger node, disable it and change the password immediately.
2
SMB / team
Need stability and security
SMB / team
Need stability and security
- Configure ACL access control: By default, devices in the same network can reach each other; use
acls/rulesto enforce "finance PCs can only reach finance systems" or "frontend servers can't connect to databases." See Security Best Practices. - Deploy DERP relays: Deploy 1-2 more DERP nodes on your intranet / same region (see DERP Configuration); avoid routing cross-region access through foreign public relays and cut latency by over 50%.
- Review audit logs: Audit logs are enabled by default; all user logins, node joins, and ACL changes are recorded automatically. View them in Admin Console → Audit Logs for compliance.
- Set up automatic backups: Back up the entire
/data/virtuamesh/server/directory (including the SQLite database and config) to object storage (S3 / OSS / COS) daily. Disaster recovery time drops from 24 hours to 1 hour. - Integrate SSO (optional): The server supports OIDC integration with WeCom, Lark, Azure AD, and Okta — employees sign in with one click using their corporate account, and permissions are auto-revoked on departure.
3
Developer / ops
Need automation and integration
Developer / ops
Need automation and integration
- Use the API instead of the web console: All admin operations (create nodes, revoke devices, edit ACLs) have a RESTful API; managing them with scripts/programs is far faster than clicking through the console 1000 times.
- Write a client install script: Wrap
virtuamesh register --network-code xxx && virtuamesh upin an Ansible/Shell script so new machines auto-join the network within 5 minutes of boot. Example:#!/bin/bash curl -fsSL https://control.virtuamesh.com/install/linux.sh | sh virtuamesh register --server https://control.virtuamesh.com --network-code $1 virtuamesh up --accept-routes - Bring CI/CD build machines into the network: Install the VirtuaMesh client on GitHub Actions runners / Jenkins agents so pipelines can reach internal test servers for deployment. Pair with
virtuamesh exit-node useto route pipeline traffic through the corporate exit. - Monitor with Prometheus: The server exposes a
/metricsendpoint (see the API section); feed node online rate, traffic peaks, and handshake failures into Grafana. Set alert thresholds so you get notified within 1 minute of a service issue. - Use MagicDNS + Service Discovery: Have all microservices use
service-name.namespaceMagicDNS domains — no need to maintain hosts files, and scaling in/out requires no config changes when IPs change. - Enable WireGuard kernel mode: On Linux servers set
wireguard.mode: kernelto boost throughput from 500 Mbps to 5 Gbps and cut CPU usage by 80% (see Performance Tuning).
🛠 Routine maintenance checklist (recommended monthly)
🌍 Want more?
virtuamesh status --json output and the steps you took); the community and official team will help you look into it.