VilaNet Merlin
Official VilaVPN router build

VilaVPN for every device
on your network.

vilanet-cli for Asuswrt-Merlin / Koolshare is the router-class VilaVPN client.

1
Koolshare package
HND
Asuswrt-Merlin / HND
16
CLI verbs
Memory-only
config store
What is VilaNet for Merlin

One Koolshare package. One router. Every device covered.

VilaNet ships to Asuswrt-Merlin as a single Koolshare rogsoft package.

AES-256-GCM credential store

Your VilaVPN password is sealed with an AES-256-GCM envelope under /koolshare/configs/vilanet/.

Embedded sing-box, one binary

Every protocol the VilaNet app supports, in a single static 32-bit ARM binary.

Koolshare-native

A Software Center package with an on-router Web UI plus the vilanet-cli command.

Full-device TUN gateway

When the firmware exposes TUN + nftables, every LAN client's traffic enters the tunnel.

Kill-switch / fail-closed

When the tunnel drops, the iptables rules block LAN forwarding paths that would bypass it.

Nothing sensitive on disk

Runtime VPN config, exit endpoints, and node details live only in process memory.

Installation

Install from the Software Center

VilaNet for Merlin ships as a single Koolshare rogsoft package.

Choose your router's CPU architecture

Not sure? Pick armv7 for a modern AC/AX router. Choose armv5 if you have an older router or armv7 won't run.

Download the rogsoft package

A static ARM build with the embedded sing-box, for the hnd firmware family. Install it online from the Software Center, or download it here for an offline install.

vilanet-rogsoft-armv7-1.0.0.tar.gz ≈ 11 MB Verify with SHA-256
Download

Software Center (online, recommended)

Open 软件中心 / Software Center → find VilaNet → install.

Offline / manual install

Download the .tar.gz above, then Software Center → offline install, or run sh install.sh.

More firmware families

axhnd / axhnd.675x / p1axhnd.675x are being added.

Choose a routing mode

Pick tun (whole-LAN gateway) or proxy (transparent / mixed).

# Offline install — download on the router shell, then install root@merlin:# cd /tmp root@merlin:# wget https://github.com/vilavpn/vilanet-merlin/releases/download/v1.0.0/vilanet-rogsoft-armv7-1.0.0.tar.gz root@merlin:# tar -xzf vilanet-rogsoft-armv7-1.0.0.tar.gz root@merlin:# cd vilanet && sh install.sh root@merlin:# vilanet-cli version # sanity check
Quick Start

From installed package to working tunnel

Package installed? These four steps take you from a fresh install to every LAN device exiting through VilaVPN.

1. Sign in

Sign in once. Your password is sealed into the encrypted store.

root@merlin:# vilanet-cli login [email protected] Password: # typed silently, sealed in the encrypted store Login successful.

2. Browse your servers

List the servers on your account. They appear as opaque IDs / redacted names.

root@merlin:# vilanet-cli servers root@merlin:# vilanet-cli servers --country HK

3. Enable, then connect

Enable the service once with vilanet-cli enable, then bring the tunnel up with vilanet-cli connect. (In the Web UI this is the Connect button.)

root@merlin:# vilanet-cli enable # turn the service on (once) root@merlin:# vilanet-cli connect -country HK Tunnel up — server HK-7a4f… (opaque) · routing_mode=tun

4. Verify on a LAN client

From any device on the LAN, check the public IP. It should be the VilaNet exit, not your ISP.

# On a laptop / phone connected to the router's LAN $ curl https://icanhazip.com # <- VilaNet exit, not your ISP # From the router itself, check live status root@merlin:# vilanet-cli status Connected · HK-7a4f… (opaque) · routing_mode=tun Protocol: Hysteria2
How traffic flows

From LAN port to exit node

Every LAN client's packets are captured by the router, encrypted by the embedded sing-box, and sent to a VilaVPN exit node.

┌────────────────────┐ │ LAN clients │ phones · TVs · IoT · laptops · consoles └─────────┬──────────┘ │ unmodified packets via br-lan ▼ ┌────────────────────┐ │ Merlin firewall │ iptables — kill-switch rules live here │ + capture │ TUN gateway, or transparent/mixed proxy └─────────┬──────────┘ │ packets reach the vilanet service ▼ ┌────────────────────┐ │ sing-box (embedded)│ config generated in memory only │ DNS over the tunnel│ block_dot · block_quic · block_stun │ geoip + geosite │ bypass_china · custom rules └─────────┬──────────┘ │ encrypted: Hysteria2 / VLESS-Reality / Trojan / VMess ▼ ┌────────────────────┐ │ VilaNet exit node │ opaque ID · address never on disk └─────────┬──────────┘ │ ▼ The open internet
Web UI

The Software-Center module

VilaNet's on-router Web UI is a Koolshare Software-Center module — a six-tab page: Overview, Account, Servers, Settings, Diagnostics, and Maintenance.

How to open it: Software Center → VilaNet.
Language: the on-router Web UI is English for now.

Overview

The landing tab: live VPN state, the selected server by opaque name, routing mode, TUN/proxy availability, the LAN proxy endpoint, and connect / disconnect controls.

Account

Sign in with your VilaVPN email and password — sealed into the encrypted store on the router — and see your account and subscription.

Servers

Your servers as opaque IDs / redacted display names, each with a Connect button. Real hostnames, IPs, and ports are never shown.

Settings

The config keys below as form fields. Saving writes them via vilanet-cli config and restarts the service when needed.

Diagnostics

Redacted runtime logs plus the connectivity self-test and a diagnostics dump for bug reports — endpoints and credentials scrubbed.

Maintenance

Service controls and package upkeep: enable / disable, restart, check for updates, and roll back.

Command reference

vilanet-cli on the shell

Everything in the Web UI has a vilanet-cli equivalent over SSH.

login

Sign in and seal email + password into the encrypted store.

logout

Sign out and clear stored credentials. Idempotent.

enable

Enable the VilaNet service so it survives reboot — a prerequisite for connect.

disable

Disable the VilaNet service so it no longer starts on boot.

connect

Bring the tunnel up (alias start). Starts sing-box and applies firewall rules.

disconnect

Bring the tunnel down (alias stop). Idempotent.

restart

Restart the running connection — re-reads config and re-dials the selected server.

status

Live state: running/idle, selected server, routing mode, uptime, protocol.

servers

List the servers on your account as opaque IDs / redacted names.

config

Read or write config: show · get · set · reset.

logs

Tail the redacted service log (optionally the last N lines).

web

Print how to reach the on-router Web UI (the Software-Center module).

test

Run a connectivity self-test against the active tunnel.

debug

Dump verbose, redacted diagnostics for bug reports.

version

Print the package, binary, and sing-box versions.

Try it now

Interactive terminal simulator

Type any vilanet-cli command below and see the (simulated) output.

vilanet-cli version vilanet-cli login vilanet-cli servers --country HK vilanet-cli enable vilanet-cli connect -country HK vilanet-cli status vilanet-cli disconnect vilanet-cli config show vilanet-cli logs vilanet-cli test vilanet-cli help
root@merlin — vilanet-cli simulator
root@merlin:#
Note: the simulator reproduces the look of real router output but connects to nothing.
Config

vilanet-cli config — every knob

Every Web UI Settings field maps to a config key, persisted in nvram.

global

KeyValuesDescription
global.auto_connect0 · 1Bring up the tunnel automatically when the service starts.
global.auto_reconnect0 · 1Re-dial the selected server on transient failure.
global.connection_modeglobal · rule · pacTraffic policy for traffic that enters sing-box: global sends it all through the VPN; rule (alias pac) enables smart China-bypass routing.
global.log_levelerror · warn · infoVerbosity of the redacted service log.

network

KeyValuesDescription
network.routing_modeproxy · tuntun = whole-LAN sing-box gateway (fail-closed if TUN/nft are missing). proxy = mixed + TPROXY-LAN inbounds — transparent capture when eligible, else a manual mixed HTTP/SOCKS listener.
network.dns_modefakeip · realsing-box DNS strategy — fake-ip is faster; real-DNS works with apps that don't honour DNS.
network.bypass_china0 · 1Apply the geosite-CN / geoip-CN smart bypass rules.
network.mtue.g. 1420Tunnel MTU. Lower if you see fragmentation on PPPoE / encapsulated uplinks.
network.block_ads0 · 1Geosite-category-ads reject.
network.block_porn0 · 1Geosite-category-porn reject.
network.block_dotdefault · 0 · 1Tri-state. Blocks DNS-over-TLS on the LAN to force resolution through the tunnel.
network.block_quicdefault · 0 · 1Tri-state. Blocks UDP/443 so HTTP/3 falls back to TCP/TLS, eliminating QUIC-path DNS leaks.
network.block_stundefault · 0 · 1Tri-state. Blocks STUN endpoint discovery — useful for WebRTC IP-leak prevention.
Routing modes: tun is the whole-LAN gateway; proxy is transparent / mixed capture. These are the only two routing modes.

proxy (LAN sharing)

KeyValuesDescription
proxy.enabled0 · 1Expose a mixed HTTP/SOCKS endpoint on the LAN. Opt-in.
proxy.port10081Mixed-inbound listen port on the router's LAN IP.

auth

KeyValuesDescription
auth.emailyour VilaVPN emailRead-only here. Setting it is rejected with a redirect to vilanet-cli login; the password lives only in the encrypted credential store.
Apply changes: vilanet-cli config set persists immediately; runtime-affecting changes apply after vilanet-cli restart.

What lives on the router

On-disk layout

VilaNet is a well-behaved Koolshare module: everything goes to predictable paths under /koolshare.

PathPurpose
/koolshare/bin/vilanetService binary — single static ARM executable with embedded sing-box.
/koolshare/scripts/vilanet-cliThe command-line tool documented above.
/koolshare/scripts/vilanet_*.shStartup / config helpers (incl. S99vilanet-style boot hook).
/koolshare/webs/Module_vilanet.aspThe Software-Center Web UI module page (+ vilanet_api.cgi).
/koolshare/res/vilanet/Web UI assets (JS / CSS) for the module.
/koolshare/configs/vilanet/Encrypted credential store (mode 0700).
nvram vilanet_*Persisted config keys (the tables above).
/tmp/vilanet/Runtime scratch + redacted logs. Cleared on reboot.
By design: No exit-node addresses, ports, or generated tunnel config are ever written to disk — runtime state is memory-only, and logs are redacted.
Troubleshooting

When something's off, start here

VilaNet doesn't appear in the Software Center

The installer needs a real Koolshare context. Confirm you're on Asuswrt-Merlin with the rogsoft software center, then re-run the install.

Status shows idle right after enabling

Check the log with vilanet-cli logs 200. The usual cause is a routing-mode mismatch.

LAN clients drop every few seconds

Almost always MTU. Lower network.mtu from 1420 to 1380 or 1280, then restart.

YouTube / Netflix slow but speedtest is fine

The browser is preferring QUIC. With network.block_quic on, sing-box rejects UDP/443 so it falls back to TCP.

TUN gateway won't come up

routing_mode=tun needs TUN + nftables. If missing, switch to routing_mode=proxy.

Login keeps failing — but the password is right

Probably a stale credential store. Run vilanet-cli logout then vilanet-cli login.

Need to ship a bug report

Run vilanet-cli debug and vilanet-cli logs. Both are redacted and safe to share.

Live log tailing: vilanet-cli logs follows the redacted service log while you reproduce the problem.
AI assistants

Drive vilanet-merlin with your AI

vilanet-merlin ships a universal Agent Skill at ai/vilanet-merlin/SKILL.md.

Claude Code

Drop the skill file into ~/.claude/skills/vilanet-merlin/SKILL.md.

$ mkdir -p ~/.claude/skills/vilanet-merlin $ curl -fsSL https://testingcf.jsdelivr.net/gh/vilavpn/vilanet-merlin@main/ai/vilanet-merlin/SKILL.md \ -o ~/.claude/skills/vilanet-merlin/SKILL.md

Gemini CLI ≥ 0.41

Use native Agent Skills support.

$ gemini skills install https://github.com/vilavpn/vilanet-merlin.git --path ai/vilanet-merlin # Or from a local checkout: $ gemini skills link ./ai/vilanet-merlin

Codex CLI · Cursor · Cline · Aider · Copilot CLI

The skill content is identical across every tool — only the install path differs.

$ mkdir -p .agents/skills/vilanet-merlin $ curl -fsSL https://testingcf.jsdelivr.net/gh/vilavpn/vilanet-merlin@main/ai/vilanet-merlin/SKILL.md \ -o .agents/skills/vilanet-merlin/SKILL.md # For tools that only read AGENTS.md, append (idempotent): $ grep -qxF '## VilaNet Merlin Agent Skill' AGENTS.md 2>/dev/null || \ { echo; echo '## VilaNet Merlin Agent Skill'; cat .agents/skills/vilanet-merlin/SKILL.md; } >> AGENTS.md

Once installed, here's how you talk to it

Describe what you want in plain language — these examples paste straight into your AI chat.

Install the VilaNet rogsoft package on my Asuswrt-Merlin router at 192.168.1.1 via the Software Center.
Sign in to my VilaVPN account and connect the router to a Hong Kong server.
The Web UI keeps showing the sign-in tab even though I logged in over SSH. Diagnose and fix it.
Set network.dns_mode and switch connection_mode to rule, then restart.
Block STUN, DoT, and QUIC across the LAN so DNS can't leak around the tunnel.
Switch routing_mode to tun for a whole-LAN gateway, and reconnect.
My exit IP didn't change after I enabled the tunnel. Pull a vilanet-cli debug bundle and tell me what's wrong.

Your AI translates the request into the right vilanet-cli invocation and explains the result back in plain language.