Skip to content

Configuration

mqvpn supports both INI and JSON config files. If the file content starts with {, it is parsed as JSON; otherwise as INI. CLI arguments override config values.

INI Format

Server

ini
# /etc/mqvpn/server.conf
[Interface]
Listen = 0.0.0.0:443
Subnet = 10.0.0.0/24
Subnet6 = 2001:db8:1::/112

[TLS]
Cert = /etc/mqvpn/server.crt
Key = /etc/mqvpn/server.key

[Auth]
Key = mPyVpoQWcp/5gr404xvS19aRC03o0XS2mrb2tZJ1Ii4=
User = alice:<ALICE_PSK>
User = bob:<BOB_PSK>

[Multipath]
Scheduler = wlb

Client

ini
# /etc/mqvpn/client.conf
[Server]
Address = 203.0.113.1:443

[Auth]
Key = mPyVpoQWcp/5gr404xvS19aRC03o0XS2mrb2tZJ1Ii4=

[Interface]
TunName = mqvpn0
DNS = 1.1.1.1, 8.8.8.8
LogLevel = info

[Multipath]
Scheduler = wlb
Path = eth0
Path = wlan0

JSON Format

JSON config is useful for structured management and automation tooling.

Server

json
{
  "mode": "server",
  "listen": "0.0.0.0:443",
  "tun_name": "mqvpn0",
  "log_level": "info",
  "subnet": "10.0.0.0/24",
  "subnet6": "2001:db8:1::/112",
  "cert_file": "/etc/mqvpn/server.crt",
  "key_file": "/etc/mqvpn/server.key",
  "auth_key": "<YOUR_PSK_HERE>",
  "users": [
    { "name": "alice", "key": "<ALICE_PSK>" },
    { "name": "bob", "key": "<BOB_PSK>" }
  ],
  "max_clients": 64,
  "scheduler": "wlb"
}

Client

json
{
  "mode": "client",
  "server_addr": "203.0.113.1:443",
  "tun_name": "mqvpn0",
  "log_level": "info",
  "auth_key": "<YOUR_PSK_HERE>",
  "insecure": false,
  "dns": ["1.1.1.1", "8.8.8.8"],
  "kill_switch": false,
  "reconnect": true,
  "reconnect_interval": 5,
  "scheduler": "wlb",
  "paths": ["eth0", "wlan0"]
}

Multi-User Authentication

The server can authenticate multiple users, each with their own PSK. In JSON config, add a users array where each entry is either an object ({"name":"alice","key":"..."}) or a shorthand string ("alice:key"). In INI config, use repeatable User = NAME:KEY lines in the [Auth] section. You can also use the Control API to manage users at runtime.

When both auth_key (global key) and users are set, clients can authenticate with either. To restrict access to named users only, remove auth_key from the config.

Removing a user (via config change or the Control API) only prevents new connections. Existing sessions remain active until they disconnect or the server restarts.

Running with Config Files

bash
sudo mqvpn --config /etc/mqvpn/server.conf
sudo mqvpn --config /etc/mqvpn/server.json

Config Reference

[Server] (client only)

KeyDescriptionDefault
AddressServer address (HOST:PORT, e.g. [2001:db8::1]:443 for IPv6)Required
InsecureSkip TLS certificate verificationfalse

[Interface]

KeyDescriptionDefault
ListenListen address (HOST:PORT, server only)0.0.0.0:443
SubnetClient IPv4 pool (server only)10.0.0.0/24
Subnet6Client IPv6 pool (server only)
TunNameTUN device namemqvpn0
DNSDNS servers (comma-separated)
LogLevelLog level (debug, info, warn, error)info
KillSwitchBlock traffic outside the VPN tunnel (client only)false
ReconnectEnable automatic reconnection (client only)true
ReconnectIntervalSeconds between reconnection attempts5

[TLS] (server only)

KeyDescriptionDefault
CertTLS certificate path (PEM)Required
KeyTLS private key path (PEM)Required

[Auth]

KeyDescriptionDefault
KeyPre-shared key (base64, generate with mqvpn --genkey)Required unless User is set
UserPer-user PSK in NAME:KEY format (repeatable)
MaxClientsMaximum concurrent clients (server only)64

[Multipath]

KeyDescriptionDefault
SchedulerScheduler algorithm (minrtt or wlb)wlb
PathNetwork interface to bind (repeatable)Default interface

See Multipath for scheduler details.

Control API

A running server can be managed at runtime over a local TCP socket using JSON commands. This is useful for adding or removing users without restarting the server.

Enable

bash
sudo mqvpn --mode server ... --control-port 9090

The control API binds to 127.0.0.1 by default. It has no authentication, so only bind to trusted interfaces.

Commands

Add a user:

bash
echo '{"cmd":"add_user","name":"carol","key":"carol-secret"}' | nc 127.0.0.1 9090

Remove a user:

bash
echo '{"cmd":"remove_user","name":"carol"}' | nc 127.0.0.1 9090

List users:

bash
echo '{"cmd":"list_users"}' | nc 127.0.0.1 9090

Get stats:

bash
echo '{"cmd":"get_stats"}' | nc 127.0.0.1 9090

All commands return a JSON response with an "ok" field. Each connection handles one command, then the server closes the connection.

systemd

Install the binary and unit files first (one-time setup):

bash
sudo cmake --install build --prefix /usr/local

Server

bash
sudo cp systemd/server.conf.example /etc/mqvpn/server.conf
# Edit /etc/mqvpn/server.conf with your settings
sudo systemctl enable --now mqvpn-server

Client (template unit)

The client uses a template unit — the instance name maps to the config file:

bash
sudo cp systemd/client.conf.example /etc/mqvpn/client-home.conf
sudo systemctl enable --now mqvpn-client@home
# This reads /etc/mqvpn/client-home.conf

INFO

The systemd units expect INI .conf files. The server unit's NAT helper scripts also parse the INI config directly, so JSON cannot be used with the standard units as-is.

Released under the Apache License 2.0