Path: /etc/dnstm/config.json
{
"log": {
"level": "info",
"output": "",
"timestamp": true
},
"listen": {
"address": "0.0.0.0:53"
},
"proxy": {
"port": 1080
},
"backends": [
{
"tag": "socks",
"type": "socks",
"address": "127.0.0.1:1080"
},
{
"tag": "ssh",
"type": "ssh",
"address": "127.0.0.1:22"
},
{
"tag": "ss-primary",
"type": "shadowsocks",
"shadowsocks": {
"password": "generated-password",
"method": "aes-256-gcm"
}
}
],
"tunnels": [
{
"tag": "tunnel-1",
"enabled": true,
"transport": "slipstream",
"backend": "ss-primary",
"domain": "t1.example.com",
"port": 5310,
"slipstream": {
"cert": "/etc/dnstm/tunnels/tunnel-1/cert.pem",
"key": "/etc/dnstm/tunnels/tunnel-1/key.pem"
}
},
{
"tag": "tunnel-2",
"enabled": true,
"transport": "dnstt",
"backend": "socks",
"domain": "t2.example.com",
"port": 5311,
"dnstt": {
"mtu": 1232,
"private_key": "/etc/dnstm/tunnels/tunnel-2/server.key"
}
}
],
"route": {
"mode": "single",
"active": "tunnel-1",
"default": "tunnel-1"
}
}Forward traffic to a SOCKS5 proxy (e.g., microsocks).
{
"tag": "socks",
"type": "socks",
"address": "127.0.0.1:1080"
}With optional username/password authentication:
{
"tag": "socks",
"type": "socks",
"address": "127.0.0.1:1080",
"socks": {
"user": "myuser",
"password": "mypass"
}
}Authentication can also be configured via CLI: dnstm backend auth -t socks --user myuser --password mypass
Forward traffic to an SSH server.
{
"tag": "ssh",
"type": "ssh",
"address": "127.0.0.1:22"
}Use Shadowsocks encryption (Slipstream only, via SIP003 plugin).
{
"tag": "ss-primary",
"type": "shadowsocks",
"shadowsocks": {
"password": "your-password",
"method": "aes-256-gcm"
}
}Supported methods:
aes-256-gcm(recommended)chacha20-ietf-poly1305
Forward traffic to any custom address.
{
"tag": "web-server",
"type": "custom",
"address": "192.168.1.100:8080"
}High-performance DNS tunnel with TLS encryption.
{
"tag": "my-tunnel",
"transport": "slipstream",
"backend": "ss-primary",
"domain": "t.example.com",
"port": 5310,
"slipstream": {
"cert": "/etc/dnstm/tunnels/my-tunnel/cert.pem",
"key": "/etc/dnstm/tunnels/my-tunnel/key.pem"
}
}Slipstream supports all backend types including Shadowsocks.
Classic DNS tunnel using Curve25519 keys.
{
"tag": "my-tunnel",
"transport": "dnstt",
"backend": "socks",
"domain": "t.example.com",
"port": 5311,
"dnstt": {
"mtu": 1232,
"private_key": "/etc/dnstm/tunnels/my-tunnel/server.key"
}
}Note: DNSTT does not support the shadowsocks backend type.
Next-generation DNS tunnel using Curve25519 keys with KCP transport.
{
"tag": "my-tunnel",
"transport": "vaydns",
"backend": "socks",
"domain": "t.example.com",
"port": 5312,
"vaydns": {
"mtu": 1232,
"private_key": "/etc/dnstm/tunnels/my-tunnel/server.key",
"idle_timeout": "10s",
"keep_alive": "2s",
"clientid_size": 2,
"queue_size": 512
}
}VayDNS with dnstt-compatible wire format:
{
"tag": "my-compat-tunnel",
"transport": "vaydns",
"backend": "socks",
"domain": "t.example.com",
"port": 5313,
"vaydns": {
"mtu": 1232,
"dnstt_compat": true
}
}VayDNS configuration fields:
| Field | Type | Default | Description |
|---|---|---|---|
mtu |
int | 1232 | MTU size (512-1400) |
private_key |
string | (auto-generated) | Path to Curve25519 private key |
idle_timeout |
string | 10s (native) / 2m (dnstt-compat) |
Connection idle timeout |
keep_alive |
string | 2s (native) / 10s (dnstt-compat) |
Keepalive interval (must be < idle_timeout) |
fallback |
string | (empty) | UDP endpoint for non-DNS packets |
dnstt_compat |
bool | false | Enable dnstt-compatible wire format (8-byte client IDs) |
clientid_size |
int | 2 | Client ID size in bytes (1-8, ignored when dnstt_compat is true) |
queue_size |
int | 512 | Packet queue size (min 32) |
kcp_window_size |
int | 0 | KCP window size (0 = queue_size/2, must be ≤ queue_size) |
queue_overflow |
string | drop |
Queue overflow strategy: drop or block |
log_level |
string | info |
Server log level: debug, info, warning, error |
record_type |
string | txt |
DNS record type: txt, cname, a, aaaa, mx, ns, srv (must be txt when dnstt_compat is enabled) |
Note: VayDNS does not support the shadowsocks backend type.
| Transport | socks | ssh | shadowsocks | custom |
|---|---|---|---|---|
| slipstream | ✓ | ✓ | ✓ | ✓ |
| dnstt | ✓ | ✓ | ✗ | ✓ |
| vaydns | ✓ | ✓ | ✗ | ✓ |
{
"route": {
"mode": "single",
"active": "tunnel-1",
"default": "tunnel-1"
}
}| Field | Description |
|---|---|
mode |
Operating mode: single or multi |
active |
Active tunnel tag (single mode only) |
default |
Default route for unmatched domains (multi mode) |
/etc/dnstm/
├── config.json # Main configuration (JSON)
└── tunnels/ # Per-tunnel directories
└── <tag>/
├── cert.pem # TLS certificate (Slipstream)
├── key.pem # TLS private key (Slipstream)
├── server.key # Curve25519 private key (DNSTT, VayDNS)
├── server.pub # Curve25519 public key (DNSTT, VayDNS)
└── config.json # Shadowsocks config for SIP003
Location: /etc/dnstm/tunnels/<tag>/cert.pem and key.pem
Properties:
- ECDSA P-256 algorithm
- 10-year validity
- Self-signed
- Auto-generated per tunnel if not provided
View fingerprint:
dnstm tunnel status <tag>Location: /etc/dnstm/tunnels/<tag>/server.key and server.pub
Auto-generated per tunnel if not provided. Both DNSTT and VayDNS use Curve25519 key pairs.
View public key:
dnstm tunnel status <tag>Ports auto-allocated starting from 5310:
- First tunnel: 5310
- Second tunnel: 5311
- etc.
Port 53 is used by:
- Active transport (single-mode, binds directly)
- DNS router (multi-mode)
Services run as dnstm system user:
- UID: auto-allocated
- Home:
/etc/dnstm - Shell:
/usr/sbin/nologin
Directory permissions:
/etc/dnstm/- 755/etc/dnstm/tunnels/- 750/etc/dnstm/tunnels/<tag>/- 750
ufw allow 53/udp
ufw allow 53/tcpfirewall-cmd --permanent --add-port=53/udp
firewall-cmd --permanent --add-port=53/tcpTransport binaries are stored in /usr/local/bin/:
dnstm- CLI toolslipstream-server- Slipstream transportdnstt-server- DNSTT transportvaydns-server- VayDNS transportssserver- Shadowsocks servermicrosocks- SOCKS5 proxysshtun-user- SSH user management tool
# Export current config to file
dnstm config export -o backup.json
# Validate a config file
dnstm config validate backup.json
# Load config from file
dnstm config load backup.jsonThe config load command provides a quick way to deploy a complete configuration.
Prerequisites: Run dnstm install first to set up the system user, directories, and services.
- Cleanup: Existing tunnel services are stopped and removed
- Validation: Config file is validated before applying
- Crypto Material:
- If cert/key paths are provided, they are validated (must exist and be readable by dnstm user)
- If no paths provided, certificates (Slipstream) or keys (DNSTT) are auto-generated
- Services: Tunnel services are created and the router is started automatically
- Output: Displays connection info (fingerprints/public keys) and file paths
# 1. Install dnstm
dnstm install --mode multi
# 2. Load config (tunnels start immediately)
dnstm config load config.jsonWhen cert/key paths are omitted, they are auto-generated:
{
"tunnels": [
{
"tag": "my-slip",
"transport": "slipstream",
"backend": "socks",
"domain": "t1.example.com",
"port": 5310
},
{
"tag": "my-vaydns",
"transport": "vaydns",
"backend": "socks",
"domain": "t2.example.com",
"port": 5311,
"vaydns": {
"mtu": 1232,
"idle_timeout": "15s",
"keep_alive": "3s"
}
}
],
"route": {
"mode": "multi"
}
}Provide paths to use existing certificates:
{
"tunnels": [
{
"tag": "my-slip",
"transport": "slipstream",
"backend": "socks",
"domain": "t.example.com",
"port": 5310,
"slipstream": {
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem"
}
}
],
"route": {
"mode": "multi"
}
}Note: Both cert and key must be provided together. Files must be readable by the dnstm user.
Enable username/password authentication on the built-in SOCKS5 proxy:
{
"backends": [
{
"tag": "socks",
"type": "socks",
"socks": {
"user": "myuser",
"password": "mypass"
}
}
],
"tunnels": [
{
"tag": "my-slip",
"transport": "slipstream",
"backend": "socks",
"domain": "t.example.com",
"port": 5310
}
],
"route": {
"mode": "multi"
}
}The SOCKS5 credentials are applied to microsocks during config load and included in generated dnst:// share URLs.