WireGuard Backend

The WireGuard backend allows to generate WireGuard configurations.

Its schema is limited to a subset of the features available in WireGuard and it doesn’t recognize interfaces, radios, wireless settings and so on.

The main methods work just like the OpenWrt backend:

  • __init__

  • render

  • generate

  • write

  • json

The main differences are in the resulting configuration and in its schema.

See an example of initialization and rendering below:

from netjsonconfig import Wireguard

config = Wireguard(
    {
        "wireguard": [
            {
                "name": "wg",
                "private_key": "QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI=",
                "port": 40842,
                "address": "10.0.0.1/24",
                "peers": [
                    {
                        "public_key": "jqHs76yCH0wThMSqogDshndAiXelfffUJVcFmz352HI=",
                        "allowed_ips": "10.0.0.3/32",
                    },
                    {
                        "public_key": "94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE=",
                        "allowed_ips": "10.0.0.4/32",
                        "preshared_key": "xisFXck9KfEZga4hlkproH6+86S8ki1tmLtMtqVipjg=",
                        "endpoint_host": "192.168.1.35",
                        "endpoint_port": 4908,
                    },
                ],
            }
        ]
    }
)
print(config.render())

Will return the following output:

# wireguard config: wg

[Interface]
Address = 10.0.0.1/24
ListenPort = 40842
PrivateKey = QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI=

[Peer]
AllowedIPs = 10.0.0.3/32
PublicKey = jqHs76yCH0wThMSqogDshndAiXelfffUJVcFmz352HI=

[Peer]
AllowedIPs = 10.0.0.4/32
Endpoint = 192.168.1.35:4908
PreSharedKey = xisFXck9KfEZga4hlkproH6+86S8ki1tmLtMtqVipjg=
PublicKey = 94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE=

WireGuard backend schema

The Wireguard backend schema is limited, it only recognizes an wireguard key with a list of dictionaries representing vpn instances. The structure of these dictionaries is described below.

Alternatively you may also want to take a look at the WireGuard JSON-Schema source code.

According to the NetJSON spec, any unrecognized property will be ignored.

Server settings (valid both for client and server)

Required properties:

  • name

  • port

  • private_key

key name

type

default

allowed values

name

string

2 to 15 alphanumeric characters, dashes and underscores

port

integer

51820

integers

private_key

string

base64-encoded private key

dns

list

[]

list of strings containing DNS servers

mtu

integer

1420

Interface MTU, set to 1280 if using IPv6

table

string

auto

Controls the routing table to which routes are added

pre_up

string

Script snippet which will be executed before setting up the interface.

post_up

string

Script snippet which will be executed after setting up the interface.

pre_down

string

Script snippet which will be executed before tearing down the interface.

post_down

string

Script snippet which will be executed after tearing down the interface.

save_config

boolean

false

Save the configuration from the current state of interface upon shutdown.

peers

list

[]

list of dictionaries containing following information of each peer:

key name

type

allowed values

public_key

string

base64-encoded public key of peer

allowed_ips

string

internal VPN IP address of peer in CIDR notation

endpoint_host

string

public IP address of peer

endpoint_port

integer

integers

preshared_key

string

base64-encoded pre-shared key

Working around schema limitations

The schema does not include all the possible WireGuard settings, but it can render appropriately any property not included in the schema as long as its type is one the following:

  • boolean

  • integer

  • strings

  • lists

For a list of all the WireGuard configuration settings, refer to the “Configuration” section of wg-quick(8) and “Configuration File Format” section of wg(8)

Automatic generation of clients

classmethod OpenWrt.wireguard_auto_client(**kwargs)[source]

Example:

from netjsonconfig import OpenWrt

server_config = {
    "name": "wg",
    "port": 51820,
    "public_key": "94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE=",
    "server_ip_network": "10.0.0.1/32",
}
client_config = OpenWrt.wireguard_auto_client(
    host="wireguard.test.com",
    server=server_config,
    public_key=server_config["public_key"],
    port=51820,
    private_key="QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI=",
    ip_address="10.0.0.5/32",
    server_ip_network=server_config["server_ip_network"],
)
print(OpenWrt(client_config).render())

Will be rendered as:

package network

config interface 'wg'
        list addresses '10.0.0.5/32/32'
        option listen_port '51820'
        option mtu '1420'
        option nohostroute '0'
        option private_key 'QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI='
        option proto 'wireguard'

config wireguard_wg 'wgpeer'
        list allowed_ips '10.0.0.1/32'
        option endpoint_host 'wireguard.test.com'
        option endpoint_port '51820'
        option persistent_keepalive '60'
        option public_key '94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE='
        option route_allowed_ips '1'

Note

The current implementation of WireGuard VPN backend is implemented with OpenWrt backend. Hence, the example above shows configuration generated for OpenWrt.