JSON Schema
JSON Schema is a declarative language that allows you to annotate and validate JSON documents.
JSON Schema can also be used to validate YAML documents and as such cunīcu's configuration file. YAML Ain't Markup Language (YAML) is a powerful data serialization language that aims to be human friendly.
Most JSON is syntactically valid YAML, but idiomatic YAML follows very different conventions. While YAML has advanced features that cannot be directly mapped to JSON, most YAML files use features that can be validated by JSON Schema. JSON Schema is the most portable and broadly supported choice for YAML validation.
The schema of cunīcu's configuration file is available at:
Editor / Language Server support
Redhat's YAML Visual Studio Code extension provides comprehensive YAML Language support, via the yaml-language-server.
It provides completion, validation and code lenses based on JSON Schemas.
To make use of it, you need to associate your config file with the JSON Schema by adding the following line into your config:
# yaml-language-server: $schema=https://cunicu.li/schemas/config.yaml
---
watch_interval: 1s
Reference
Here is a rendered reference based on this schema:
watch_interval | string (Duration) (\d+(\.\d)?(ns|us|µs|ms|s|m|h))+ An interval at which cunīcu will periodically check for added, removed or modified WireGuard interfaces. |
backends | Array of strings <uri> (Signaling backends) [ items <uri > ] Default: ["grpc://signal.cunicu.li:443"] These backends are used for exchanging control-plane messages between the peers. Examples of the exchanged information are ICE candidates or peer information. |
object (RPC Settings) Settings for controlling cunīcu via the CLI. | |
object (Logging Settings) Settings of logging system. | |
mtu | number (MTU) The Maximum Transmission Unit (MTU) of the WireGuard interface. If not specified, the MTU is automatically determined from the endpoint addresses or the system default route, which is usually a sane choice. However, to manually specify an MTU to override this automatic discovery, this value may be specified explicitly. |
addresses | Array of strings (Addresses) A list of IP (v4 or v6) addresses (optionally with CIDR masks) to be assigned to the interface. |
prefixes | Array of strings (Prefixes) A list of prefixes which cunīcu uses to derive local addresses from the interfaces public key. |
Array of IP Address (any) or IP Address (any) (DNS Servers) A list of IP (v4 or v6) addresses to be set as the interface's DNS servers, or non-IP hostnames to be set as the interface's DNS search domains.
Upon bringing the interface up, this runs | |
private_key | string (Base64Key) [^-A-Za-z0-9+/=]|=[^=]|={3,}$ A base64 encoded WireGuard private key.
This key can be generated via the |
userspace | boolean (Use userspace WireGuard implementation) Default: false Create WireGuard interfaces using bundled wireguard-go user space implementation. This will be the default if there is no WireGuard kernel module present. |
object (Listen Port Range) A range constraint for an automatically assigned selected listen port. If the interface has no listen port specified, cunīcu will use the first available port from this range. | |
listen_port | integer (Listen Port) [ 0 .. 65535 ] Default: 51820 An UDP port for listening. If not specified, first available port from listen_port_range will be used. |
fwmark | integer (Firewall Mark) A 32-bit firewall mark for outgoing packets which can be used for Netfilter or Traffic Control (TC) classification.
If set to |
object (WireGuard peer) The remote WireGuard peers provided as a dictionary. The keys of this dictionary are used as names for the peers. | |
sync_routes | boolean (Route Synchronization) Default: true Enable route synchronization. |
routing_table | integer (Kernel Routing Table) Default: 254 Kernel routing table which is used.
On Linux, see |
watch_routes | boolean (Watch Routes) Default: true Keep watching the for changes in the kernel routing table via netlink multicast group. |
sync_config | boolean (Config Synchronization) Enable config synchronization. |
watch_config | boolean (Watch Configuration Files) Keep watching for changes in the configuration and apply them on-the-fly |
sync_hosts | boolean (/etc/hosts Synchronization) Default: true Enable hosts file synchronization. |
domain | string (Domain) The domain name which is appended to each of the peer host names |
discover_peers | boolean (Peer Discovery) Default: true Enable/disable peer discovery. |
hostname | string <hostname> (Hostname) The hostname which gets advertised to remote peers. |
community | string (Community) non-empty A passphrase shared among all peers of the same community. |
networks | Array of strings (Networks) Networks which are reachable via this peer and get advertised to remote peers. These will be part of this interfaces AllowedIPs at the remote peers. |
whitelist | Array of strings (Peer Whitelist) [[^-A-Za-z0-9+/=]|=[^=]|={3,}$] A list of WireGuard public keys which are accepted peers. If not configured, all peers will be accepted. |
blacklist | Array of strings (Peer Blacklist) [[^-A-Za-z0-9+/=]|=[^=]|={3,}$] A list of WireGuard public keys which are rejected as peers. |
discover_endpoints | boolean (Endpoint Discovery) Default: true Enable/disable endpoint discovery. |
object (IceSettings) Interactive Connectivity Establishment (ICE) parameters. | |
Array of Web Hook Settings (object) or Sub-process Hook (object) (Hook Settings) | |
object (Interface specific settings / overwrites) Most of the top-level settings of this configuration file can be customized for specific interfaces. The keys of the 'interfaces' dictionary are glob(7) patterns which will be matched against the interface names. Settings are overlayed in the order in which the keys are provided in the interface map. Multiple patterns are supported and evaluated in the order they a defined in the configuration file. Keys which are not a glob(7) pattern, will be created as new interfaces if they do not exist already in the system. |
{- "watch_interval": "300ms",
- "backends": [
- "grpc://signal.cunicu.li:443"
], - "rpc": {
- "socket": "/var/run/cunicu.sock",
- "wait": false
}, - "log": {
- "banner": true,
- "color": "auto",
- "file": "/var/log/cunicu.log",
- "level": "debug2",
- "rules": [
- "debug5:watcher,daemon"
]
}, - "mtu": 1420,
- "addresses": [
- "fc2f:9a4d::/32"
], - "prefixes": [
- "fc2f:9a4d::/32"
], - "dns": [
- { }
], - "private_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "userspace": false,
- "listen_port_range": {
- "min": 52820,
- "max": 65535
}, - "listen_port": 51820,
- "fwmark": 4096,
- "peers": {
- "property1": {
- "public_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key_passphrase": "theifo1we1Ayahth",
- "endpoint": "192.0.2.1:51820",
- "persistent_keepalive": "300ms",
- "allowed_ips": [
- "fc2f:9a4d::/32"
]
}, - "property2": {
- "public_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key_passphrase": "theifo1we1Ayahth",
- "endpoint": "192.0.2.1:51820",
- "persistent_keepalive": "300ms",
- "allowed_ips": [
- "fc2f:9a4d::/32"
]
}
}, - "sync_routes": true,
- "routing_table": 254,
- "watch_routes": true,
- "sync_config": true,
- "watch_config": true,
- "sync_hosts": true,
- "domain": "wg-local",
- "discover_peers": true,
- "hostname": "my-node",
- "community": "some-common-password",
- "networks": [
- "192.168.1.0/24"
], - "whitelist": [
- "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
], - "blacklist": [
- "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
], - "discover_endpoints": true,
- "ice": {
- "urls": [
- "grpc://relay.cunicu.li"
], - "username": "string",
- "password": "string",
- "insecure_skip_verify": false,
- "network_types": [
- "udp4"
], - "candidate_types": [
- "host"
], - "interface_filter": "eth*",
- "lite": true,
- "mdns": false,
- "max_binding_requests": 7,
- "nat_1to1_ips": [
- { }
], - "port_range": {
- "min": 49152,
- "max": 65535
}, - "check_interval": "300ms",
- "disconnected_timeout": "300ms",
- "failed_timeout": "300ms",
- "restart_timeout": "300ms",
- "keepalive_interval": "300ms"
}, - "hooks": [
- {
- "type": "web",
- "method": "DELETE",
- "headers": {
- "Content-type": "application/json"
}
}
], - "interfaces": {
- "property1": {
- "mtu": 1420,
- "addresses": [
- "fc2f:9a4d::/32"
], - "prefixes": [
- "fc2f:9a4d::/32"
], - "dns": [
- { }
], - "private_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "userspace": false,
- "listen_port_range": {
- "min": 52820,
- "max": 65535
}, - "listen_port": 51820,
- "fwmark": 4096,
- "peers": {
- "property1": {
- "public_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key_passphrase": "theifo1we1Ayahth",
- "endpoint": "192.0.2.1:51820",
- "persistent_keepalive": "300ms",
- "allowed_ips": [
- "fc2f:9a4d::/32"
]
}, - "property2": {
- "public_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key_passphrase": "theifo1we1Ayahth",
- "endpoint": "192.0.2.1:51820",
- "persistent_keepalive": "300ms",
- "allowed_ips": [
- "fc2f:9a4d::/32"
]
}
}, - "sync_routes": true,
- "routing_table": 254,
- "watch_routes": true,
- "sync_config": true,
- "watch_config": true,
- "sync_hosts": true,
- "domain": "wg-local",
- "discover_peers": true,
- "hostname": "my-node",
- "community": "some-common-password",
- "networks": [
- "192.168.1.0/24"
], - "whitelist": [
- "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
], - "blacklist": [
- "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
], - "discover_endpoints": true,
- "ice": {
- "urls": [
- "grpc://relay.cunicu.li"
], - "username": "string",
- "password": "string",
- "insecure_skip_verify": false,
- "network_types": [
- "udp4"
], - "candidate_types": [
- "host"
], - "interface_filter": "eth*",
- "lite": true,
- "mdns": false,
- "max_binding_requests": 7,
- "nat_1to1_ips": [
- { }
], - "port_range": {
- "min": 49152,
- "max": 65535
}, - "check_interval": "300ms",
- "disconnected_timeout": "300ms",
- "failed_timeout": "300ms",
- "restart_timeout": "300ms",
- "keepalive_interval": "300ms"
}, - "hooks": [
- {
- "type": "web",
- "method": "DELETE",
- "headers": {
- "Content-type": "application/json"
}
}
]
}, - "property2": {
- "mtu": 1420,
- "addresses": [
- "fc2f:9a4d::/32"
], - "prefixes": [
- "fc2f:9a4d::/32"
], - "dns": [
- { }
], - "private_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "userspace": false,
- "listen_port_range": {
- "min": 52820,
- "max": 65535
}, - "listen_port": 51820,
- "fwmark": 4096,
- "peers": {
- "property1": {
- "public_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key_passphrase": "theifo1we1Ayahth",
- "endpoint": "192.0.2.1:51820",
- "persistent_keepalive": "300ms",
- "allowed_ips": [
- "fc2f:9a4d::/32"
]
}, - "property2": {
- "public_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key": "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI=",
- "preshared_key_passphrase": "theifo1we1Ayahth",
- "endpoint": "192.0.2.1:51820",
- "persistent_keepalive": "300ms",
- "allowed_ips": [
- "fc2f:9a4d::/32"
]
}
}, - "sync_routes": true,
- "routing_table": 254,
- "watch_routes": true,
- "sync_config": true,
- "watch_config": true,
- "sync_hosts": true,
- "domain": "wg-local",
- "discover_peers": true,
- "hostname": "my-node",
- "community": "some-common-password",
- "networks": [
- "192.168.1.0/24"
], - "whitelist": [
- "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
], - "blacklist": [
- "zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
], - "discover_endpoints": true,
- "ice": {
- "urls": [
- "grpc://relay.cunicu.li"
], - "username": "string",
- "password": "string",
- "insecure_skip_verify": false,
- "network_types": [
- "udp4"
], - "candidate_types": [
- "host"
], - "interface_filter": "eth*",
- "lite": true,
- "mdns": false,
- "max_binding_requests": 7,
- "nat_1to1_ips": [
- { }
], - "port_range": {
- "min": 49152,
- "max": 65535
}, - "check_interval": "300ms",
- "disconnected_timeout": "300ms",
- "failed_timeout": "300ms",
- "restart_timeout": "300ms",
- "keepalive_interval": "300ms"
}, - "hooks": [
- {
- "type": "web",
- "method": "DELETE",
- "headers": {
- "Content-type": "application/json"
}
}
]
}
}
}