Skip to content

Instantly share code, notes, and snippets.

@stv0g
Last active August 11, 2023 22:16
Show Gist options
  • Save stv0g/fe7c9f625345bde7a095dd1998ea851c to your computer and use it in GitHub Desktop.
Save stv0g/fe7c9f625345bde7a095dd1998ea851c to your computer and use it in GitHub Desktop.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Schema of cunicu configuration file",
"allOf": [
{
"$ref": "#/$defs/GlobalSettings"
},
{
"$ref": "#/$defs/InterfaceSettings"
},
{
"type": "object",
"properties": {
"interfaces": {
"title": "Interface specific settings / overwrites",
"description": "Most of the top-level settings of this configuration file can be customized for specific interfaces.\n\nThe keys of the 'interfaces' dictionary are [glob(7)](https://man7.org/linux/man-pages/man7/glob.7.html) patterns which will be matched against the interface names.\nSettings are overlayed in the order in which the keys are provided in the interface map.\nMultiple patterns are supported and evaluated in the order they a defined in the configuration file.\n\nKeys which are not a [glob(7)](https://man7.org/linux/man-pages/man7/glob.7.html) pattern, will be created as new interfaces if they do not exist already in the system.\n",
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/InterfaceSettings"
}
}
}
}
],
"$defs": {
"GlobalSettings": {
"type": "object",
"properties": {
"watch_interval": {
"type": "string",
"title": "Watch Interval",
"description": "An interval at which cunīcu will periodically check for added, removed or modified WireGuard interfaces.\n"
},
"backends": {
"title": "Signaling backends",
"description": "These backends are used for exchanging control-plane messages between the peers.\n\nE.g. ICE candidates, Peer information\n",
"type": "array",
"items": {
"type": "string",
"format": "uri"
},
"default": [
"grpc://signal.cunicu.li:443"
]
},
"rpc": {
"title": "RPC settings",
"description": "Settings for controlling cunicu via the CLI",
"type": "object",
"properties": {
"socket": {
"title": "Socket Path",
"description": "Path to a Unix socket for management and monitoring of the cunicu daemon.",
"type": "string",
"default": "/var/run/cunicu.sock"
},
"wait": {
"description": "Start of cunīcu daemon will block until\nits unblocked via the control socket.\nMostly useful for testing automation\n",
"type": "boolean",
"default": false
}
}
},
"log": {
"title": "Logging configuration",
"description": "Configure logging.",
"type": "object",
"properties": {
"banner": {
"title": "Banner",
"description": "Show a banner during start of daemon",
"type": "boolean",
"default": true
},
"color": {
"title": "Colorize log output",
"description": "Use one of:\n- `auto` only colorize log output on TTYs\n- `never` never colorize log output\n- `always` always colorize log output\n",
"type": "string",
"enum": [
"auto",
"never",
"always"
]
},
"file": {
"title": "A path to a custom log file",
"type": "string",
"examples": [
"/var/log/cunicu.log"
]
},
"level": {
"title": "The standard log level",
"type": "string",
"default": "info"
},
"rules": {
"title": "Additional logging rules",
"description": "Rule syntax:\n\n RULE: LEVELS:NAMESPACES\n\n LEVELS: LEVEL[,LEVELS]\n LEVEL: one of\n - SEVERITY for matching all levels with equal or higher severity\n - >SEVERITY for matching all levels with higher severity\n - =SEVERITY for matching all levels with equal severity\n - <SEVERITY for matching all levels with lower severity\n\n SEVERITY: one of\n - debug10..debug1\n - debug\n - info\n - warn\n - error\n - fatal\n - panic\n\n NAMESPACES: NAMESPACE[,NAMESPACES]\n NAMESPACE: one of\n - namespace should be exactly this namespace\n - *mat*ch* should match\n - -NAMESPACE should not match a namespace\n",
"type": "array",
"items": {
"type": "string",
"examples": [
"debug5:watcher,daemon",
"debug6:epdisc.*"
]
}
}
}
}
}
},
"InterfaceSettings": {
"title": "Interface Settings",
"allOf": [
{
"$ref": "#/$defs/BasicInterfaceSettings"
},
{
"$ref": "#/$defs/WireGuardInterfaceSettings"
},
{
"$ref": "#/$defs/RouteSyncSettings"
},
{
"$ref": "#/$defs/ConfigSyncSettings"
},
{
"$ref": "#/$defs/HostsSyncSettings"
},
{
"$ref": "#/$defs/PeerDiscoverySettings"
}
]
},
"BasicInterfaceSettings": {
"type": "object",
"title": "Basic interface settings",
"properties": {
"mtu": {
"title": "Maximum Transmission Unit",
"description": "The Maximum Transfer Unit of the WireGuard interface.\nIf not specified, the MTU is automatically determined from\nthe endpoint addresses or the system default route,\nwhich is usually a sane choice.\nHowever, to manually specify an MTU to override this\nautomatic discovery, this value may be specified explicitly.\n",
"type": "number",
"examples": [
1420
]
},
"addresses": {
"type": "array",
"title": "Addresses",
"description": "A list of IP (v4 or v6) addresses (optionally with CIDR masks) to be assigned to the interface.\n",
"items": {
"type": "string",
"examples": [
"10.10.0.1/24"
]
}
},
"prefixes": {
"type": "array",
"title": "Prefixes",
"description": "A list of prefixes which cunicu uses to derive local addresses from the interfaces public key.\n",
"items": {
"type": "string",
"examples": [
"fc2f:9a4d::/32",
"10.237.0.0/16"
]
}
},
"dns": {
"type": "array",
"title": "DNS Servers",
"description": "A list of IP (v4 or v6) addresses to be set as the interface's\nDNS servers, or non-IP hostnames to be set as the interface's\nDNS search domains.\nMay be specified multiple times.\nUpon bringing the interface up, this runs `resolvconf -a tun.INTERFACE -m 0 -x`\nand upon bringing it down, this runs `resolvconf -d tun.INTERFACE`.\nIf these particular invocations of resolvconf(8) are undesirable,\ncustom hooks can be used instead.\n",
"items": {
"type": "string",
"examples": [
"1.1.1.1"
]
}
},
"hooks": {
"type": "array",
"items": {
"$ref": "#/$defs/HookSettings"
}
}
}
},
"WireGuardInterfaceSettings": {
"type": "object",
"title": "WireGuard Interface Settings",
"description": "These settings configure WireGuard specific settings of the interface.",
"properties": {
"private_key": {
"title": "WireGuard Private Key",
"description": "A base64 encoded WireGuard private key.\nThis key can be generated via the `wg genkey` command.\nWill be automatically generated if not provided.\n",
"type": "string"
},
"userspace": {
"title": "Use userspace WireGuard implementation",
"description": "Create WireGuard interfaces using bundled wireguard-go user space implementation.\nThis will be the default if there is no WireGuard kernel module present.\n",
"type": "boolean",
"default": false
},
"listen_port_range": {
"title": "Listen Port Range",
"description": "A range constraint for an automatically assigned selected listen port.\nIf the interface has no listen port specified, cunīcu will use the first available port from this range.\n",
"type": "object",
"properties": {
"min": {
"title": "Minimum Port",
"description": "Minimum port used to select a listen port.\n",
"type": "integer",
"default": 52820,
"minimum": 0,
"maximum": 65535
},
"max": {
"title": "Maximum Port",
"description": "Maximum port used to select a listen port.\n",
"type": "integer",
"default": 65535,
"minimum": 0,
"maximum": 65535
}
}
},
"listen_port": {
"title": "Listen Port",
"description": "An UDP port for listening.\nIf not specified, first available port from listen_port_range will be used.\n",
"type": "integer",
"default": 51820,
"minimum": 0,
"maximum": 65535
},
"fwmark": {
"title": "Firewall Mark",
"type": "integer",
"description": "A 32-bit firewall mark for outgoing packets which can be used for Netfilter or Traffic Control (TC) classification.\nIf set to `0`, this option is disabled.\nMay be specified in hexadecimal by prepending `0x`.\n",
"examples": [
4096
]
},
"peers": {
"title": "WireGuard peer",
"description": "The remote WireGuard peers provided as a dictionary\nThe keys of this dictionary are used as names for the peers\n",
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/WireGuardPeerSettings"
}
}
}
},
"WireGuardPeerSettings": {
"type": "object",
"properties": {
"public_key": {
"title": "Public Key",
"description": "A base64 public key calculated by `wg pubkey` from a private key,\nand usually transmitted out of band to the author of the configuration file.\n",
"type": "string",
"examples": [
"zu86NBVsWOU3cx4UKOQ6MgNj3gv8GXsV9ATzSemdqlI="
]
},
"preshared_key": {
"title": "Preshared Key",
"description": "A base64 pre-shared key generated by `wg genpsk`.\nOptional, and may be omitted.\nThis option adds an additional layer of symmetric-key\ncryptography to be mixed into the already existing\npublic-key cryptography, for post-quantum resistance.\n",
"type": "string",
"examples": [
"VGOJmibJ1XwdVEqMyzL0GCTY+slNeIASGkJLyzusCew="
]
},
"preshared_key_passphrase": {
"title": "Preshared Key Passphrase",
"description": "A pre-shared passphrase which is used to derive a preshared key.\ncunīcu is using Argon2id as the key derivation function.\n",
"type": "string",
"examples": [
"theifo1we1Ayahth"
]
},
"endpoint": {
"title": "Endpoint",
"description": "An endpoint IP or hostname, followed by a colon,\nand then a port number. This endpoint will be updated\nautomatically to the most recent source IP address and\nport of correctly authenticated packets from the peer.\nIf provided, no endpoint discovery will be performed.\n",
"type": "string",
"examples": [
"192.0.2.1:51820",
"vpn.example.com:51820"
]
},
"persistent_keepalive": {
"title": "Persistent Keepalive",
"description": "A time duration, between 1 and 65535s inclusive, of how\noften to send an authenticated empty packet to the peer\nfor the purpose of keeping a stateful firewall or NAT mapping\nvalid persistently. For example, if the interface very rarely\nsends traffic, but it might at anytime receive traffic from a\npeer, and it is behind NAT, the interface might benefit from\nhaving a persistent keepalive interval of 25 seconds.\nIf set to zero, this option is disabled.\nBy default or when unspecified, this option is off.\n\nMost users will not need this.\n",
"type": "string",
"default": "120s"
},
"allowed_ips": {
"title": "Allowed IPs",
"description": "A list of IP (v4 or v6) addresses with\nCIDR masks from which incoming traffic for this peer is\nallowed and to which outgoing traffic for this peer is directed.\nThe catch-all `0.0.0.0/0` may be specified for matching\nall IPv4 addresses, and `::/0` may be specified for matching\nall IPv6 addresses.\n",
"type": "array",
"items": {
"type": "string",
"examples": [
"192.0.2.0/24",
"192.0.2.0/24",
"2001:DB8::/32"
]
}
}
}
},
"IceSettings": {
"type": "object",
"title": "Interactive Connectivity Establishment (ICE) parameters",
"properties": {
"urls": {
"type": "array",
"title": "ICE URLs",
"description": "A list of STUN and TURN servers used by ICE.\n",
"items": {
"type": "string",
"format": "uri",
"examples": [
"grpc://relay.cunicu.li",
"stun:stun3.l.google.com:19302",
"stun:relay.webwormhole.io",
"stun:stun.sipgate.net",
"stun:stun.ekiga.net",
"stun:stun.services.mozilla.com"
]
}
},
"username": {
"title": "Username",
"description": "Username credential for STUN/TURN URLs configured above.\n",
"type": "string"
},
"password": {
"title": "Password",
"description": "Username credential for STUN/TURN URLs configured above.\n",
"type": "string"
},
"insecure_skip_verify": {
"title": "Skip TLS verification",
"description": "Allow connections to STUNS/TURNS servers for which we can not validate TLS certificates.\n",
"type": "boolean",
"default": false
},
"network_types": {
"title": "ICE Network Types",
"type": "array",
"items": {
"type": "string",
"enum": [
"udp4",
"udp6",
"tcp4",
"tcp6"
]
}
},
"candidate_types": {
"title": "ICE Candidate Types",
"type": "array",
"items": {
"type": "string",
"enum": [
"host",
"srflx",
"prflx",
"relay"
]
}
},
"interface_filter": {
"title": "Interface Filter",
"description": "A glob(7) pattern to match interfaces against which are used to gather ICE candidates (e.g. \\\"eth[0-9]\\\").\n",
"type": "string",
"default": "*",
"examples": [
"eth*",
"wlan0"
]
},
"lite": {
"title": "Lite Agent",
"description": "Lite agents do not perform connectivity check and only provide host candidates.\n",
"type": "boolean"
},
"mdns": {
"title": "Multicast DNS Discovery",
"description": "Enable local Multicast DNS discovery.\n",
"type": "boolean",
"default": false
},
"max_binding_requests": {
"title": "Maximum Number of Binding Requests",
"description": "Sets the max amount of binding requests the agent will send over a candidate pair for validation or nomination.\nIf after the the configured number, the candidate is yet to answer a binding request or a nomination we set the pair as failed.\n",
"type": "number",
"minimum": 0,
"default": 7
},
"nat_1to1_ips": {
"title": "1-to-1 NAT IP Addresses",
"description": "A list of external IP addresses of 1:1 (D)NAT and a candidate type for which the external IP address is used.\nThis is useful when you are host a server using Pion on an AWS EC2 instance which has a private address, behind a 1:1 DNAT with a public IP (e.g. Elastic IP).\nIn this case, you can give the public IP address so that Pion will use the public IP address in its candidate instead of the private IP address.\n",
"type": "array",
"items": {
"type": "string",
"examples": [
"10.10.2.3"
]
}
},
"port_range": {
"title": "Port Range",
"description": "Limit the port range used by ICE\n",
"type": "object",
"properties": {
"min": {
"title": "Minimum Port",
"description": "Minimum port for allocation policy for ICE sockets.\n",
"type": "integer",
"default": 49152
},
"max": {
"title": "Maximum Port",
"description": "Maximum port for allocation policy for ICE sockets.\n",
"type": "integer",
"default": 65535
}
}
},
"check_interval": {
"title": "Check Interval",
"description": "Interval at which the agent performs candidate checks in the connecting phase.\n",
"type": "string",
"default": "200ms"
},
"disconnected_timeout": {
"title": "Disconnected Timeout",
"description": "Time until an Agent transitions disconnected.\nIf the duration is 0, the ICE Agent will never go to disconnected.\n",
"type": "string",
"default": "5s"
},
"failed_timeout": {
"title": "Failed Timeout",
"description": "Time until an Agent transitions to failed after disconnected.\nIf the duration is 0, we will never go to failed.\n",
"type": "string",
"default": "5s"
},
"restart_timeout": {
"title": "Restart Timeout",
"description": "Time to wait before attempting an ICE restart.\n",
"type": "string",
"default": "5s"
},
"keepalive_interval": {
"title": "Keepalive Interval",
"description": "Interval between STUN keepalives (should be less then connection timeout above).\nAf the interval is 0, we never send keepalive packets.\n",
"type": "string",
"default": "2s"
}
}
},
"HookSettings": {
"title": "Hook callbacks.",
"description": "Hook callback can be used to invoke subprocesses or web-hooks on certain events within cunīcu.\n",
"type": "object",
"properties": {
"type": {
"title": "Type",
"description": "The type of hook.\n",
"type": "string",
"enum": [
"web",
"exec"
]
}
},
"required": [
"type"
]
},
"WebHookSettings": {
"type": "object",
"title": "Web Hook Settings",
"description": "A 'web' hook performs HTTP requests for each event.\n",
"properties": {
"url": {
"title": "Webhook Endpoint",
"description": "URL of the webhook endpoint.\n",
"type": "string",
"format": "uri",
"examples": [
"https://my-webhook-endpoint.com/api/v1/webhook"
]
},
"method": {
"title": "HTTP Method",
"description": "HTTP method of the request.\n",
"type": "string",
"enum": [
"DELETE",
"GET",
"HEAD",
"OPTIONS",
"PATCH",
"POST",
"PUT",
"TRACE"
]
},
"headers": {
"title": "HTTP Headers",
"description": "Additional HTTP headers which are used for the requests.\n",
"type": "object",
"additionalProperties": {
"type": "string"
},
"examples": [
{
"Content-type": "application/json"
},
{
"Authorization": "Bearer XXXXXX"
}
]
}
}
},
"ExecHookSettings": {
"title": "Sub-process Hook",
"description": "An 'exec' hook spawn a subprocess for each event.\n",
"type": "object",
"properties": {
"command": {
"type": "string",
"examples": [
"../../scripts/hook.sh"
]
},
"args": {
"title": "Command Arguments",
"description": "Prepend additional arguments.\n",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"stdin": {
"title": "Standard Input",
"description": "Pass JSON object via Stdin to command.\n",
"type": "boolean"
},
"env": {
"title": "Environment Variables",
"description": "Set environment variables for invocation\n",
"type": "object",
"additionalProperties": {
"type": "string"
},
"examples": [
{
"COLOR": "1"
}
]
}
}
},
"RouteSyncSettings": {
"title": "Route Synchronization",
"description": "Synchronize the kernel routing table with WireGuard's AllowedIPs setting\n\nIt checks for routes in the kernel routing table which have a peers address\nas next-hop and adds those routes to the AllowedIPs setting of the respective peer.\n\nIn reverse, also networks listed in a peers AllowedIPs setting will be installed as a\nkernel route with the peers address as the routes next-hop. \n",
"type": "object",
"properties": {
"sync_routes": {
"title": "Route Synchronization",
"description": "Enable route synchronization.\n",
"type": "boolean",
"default": true
},
"routing_table": {
"title": "Kernel Routing Table",
"description": "Kernel routing table which is used.\nOn Linux, see `/etc/iproute2/rt_tables` for table ids and names \n",
"type": "integer",
"default": 254
},
"watch_routes": {
"title": "Watch Routes",
"description": "Keep watching the for changes in the kernel routing table via netlink multicast group.\n",
"type": "boolean",
"default": true
}
}
},
"ConfigSyncSettings": {
"title": "Config Synchronization",
"description": "Synchronize local WireGuard interface configuration with wg(8) config-files.\n",
"type": "object",
"properties": {
"sync_config": {
"title": "Config Synchronization",
"description": "Enable config synchronization.\n",
"type": "boolean"
},
"watch_config": {
"title": "Watch Configuration Files",
"description": "Keep watching for changes in the configuration and apply them on-the-fly\n",
"type": "boolean"
}
}
},
"HostsSyncSettings": {
"title": "/etc/hosts Synchronization",
"description": "Synchronizes the local /etc/hosts file with host names and addresses of connected peers. \n",
"type": "object",
"properties": {
"sync_hosts": {
"title": "/etc/hosts Synchronization",
"description": "Enable hosts file synchronization.\n",
"type": "boolean",
"default": true
},
"domain": {
"title": "Domain",
"description": "The domain name which is appended to each of the peer host names\n",
"type": "string",
"examples": [
"wg-local"
]
}
}
},
"PeerDiscoverySettings": {
"title": "Peer Discovery",
"description": "Peer discovery finds new peers within the same community and adds them to the respective interface.",
"type": "object",
"properties": {
"discover_peers": {
"title": "Peer Discovery",
"description": "Enable/disable peer discovery.",
"type": "boolean",
"default": true
},
"hostname": {
"title": "Hostname",
"description": "The hostname which gets advertised to remote peers.",
"type": "string",
"examples": [
"my-node"
]
},
"community": {
"title": "Community",
"description": "A passphrase shared among all peers of the same community.",
"type": "string",
"minLength": 1,
"examples": [
"some-common-password"
]
},
"networks": {
"title": "Networks",
"description": "Networks which are reachable via this peer and get advertised to remote peers.\nThese will be part of this interfaces AllowedIPs at the remote peers.\n",
"type": "array",
"items": {
"type": "string",
"examples": [
"192.168.1.0/24",
"10.2.0.0/24"
]
}
},
"whitelist": {
"title": "Peer Whitelist",
"description": "A list of WireGuard public keys which are accepted peers.\nIf not configured, all peers will be accepted.\n",
"type": "array",
"items": {
"type": "string",
"examples": [
"coNsGPwVPdpahc8U+dbbWGzTAdCd6+1BvPIYg10wDCI="
]
}
},
"blacklist": {
"title": "Peer Blacklist",
"description": "A list of WireGuard public keys which are rejected as peers.\n",
"type": "array",
"items": {
"type": "string",
"examples": [
"AOZzBaNsoV7P8vo0D5UmuIJUQ7AjMbHbGt2EA8eAuEc"
]
}
}
}
},
"EndpointDiscoverySettings": {
"title": "Endpoint Discovery",
"description": "Endpoint discovery uses Interactive Connectivity Establishment (ICE) as used by WebRTC to\ngather a list of candidate endpoints and performs connectivity checks to find a suitable\nendpoint address which can be used by WireGuard\n",
"type": "object",
"properties": {
"discover_endpoints": {
"title": "Endpoint Discovery",
"description": "Enable/disable endpoint discovery.\n",
"type": "boolean",
"default": true
},
"ice": {
"$ref": "#/$defs/IceSettings"
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment