WG(4) | Device Drivers Manual | WG(4)

# NAME

`wg` — virtual private network tunnel (EXPERIMENTAL)

# SYNOPSIS

`pseudo-device wg`

# DESCRIPTION

The `wg` interface implements a roaming-capable virtual private network tunnel, configured with ifconfig(8) and wgconfig(8).

WARNING: `wg` is experimental.

Packets exchanged on a `wg` interface are authenticated and encrypted with a secret key negotiated with the peer, and the encapsulation is exchanged over IP or IPv6 using UDP.

Every `wg` interface can be configured with an IP address using ifconfig(8), a private key generated with wg-keygen(8), an optional listen port, and a collection of peers.

Each peer configured on an `wg` interface has a public key and a range of IP addresses the peer is allowed to use for its `wg` interface inside the tunnel. Each peer may also optionally have a preshared secret key and a fixed endpoint IP address outside the tunnel.

# EXAMPLES

Typical network topology:

    Stationary server:                         Roaming client:
    +---------+                                    +---------+
    |    A    |                                    |    B    |
    |---------|                                    |---------|
    |         | 192.0.2.123          198.51.100.45 |         |
    |        [wm0]----------internet-----------[bge0]        |
    |    [wg0] port 1234 - - - (tunnel) - - - - - - [wg0]    |
    |   10.2.0.1                  |               10.2.0.42  |
    |   fd00:2::1                 |              fd00:2::42  |
    |         |                   |                |         |
    +--[wm1]--+          +-----------------+       +---------+
         | 10.1.0.1      | VPN 10.2.0.0/24 |
         |               |     fd00:2::/64 |
         |               +-----------------+
    +-----------------+
    | LAN 10.1.0.0/24 |
    |     fd00:1::/64 |
    +-----------------+

Generate key pairs on A and B:

    A# (umask 0077; wg-keygen > /etc/wg/wg0)
    A# wg-keygen --pub < /etc/wg/wg0 > /etc/wg/wg0.pub
    A# cat /etc/wg/wg0.pub
    N+B4Nelg+4ysvbLW3qenxIwrJVE9MdjMyqrIisH7V0Y=

    B# (umask 0077; wg-keygen > /etc/wg/wg0)
    B# wg-keygen --pub < /etc/wg/wg0 > /etc/wg/wg0.pub
    B# cat /etc/wg/wg0.pub
    X7EGm3T3IfodBcyilkaC89j0SH3XD6+/pwvp7Dgp5SU=

Generate a pre-shared key on A and copy it to B to defend against potential future quantum cryptanalysis (not necessary for functionality):

    A# (umask 0077; wg-keygen > /etc/wg/wg0.A-B)

Configure A to listen on port 1234 and allow connections from B to appear in the 10.2.0.0/24 and fd00:2::/64 subnets:

    A# ifconfig wg0 create
    A# ifconfig wg0 inet 10.2.0.1/24
    A# ifconfig wg0 inet6 fd00:2::1/64
    A# wgconfig wg0 set private-key /etc/wg/wg0
    A# wgconfig wg0 set listen-port 1234
    A# wgconfig wg0 add peer B \
        X7EGm3T3IfodBcyilkaC89j0SH3XD6+/pwvp7Dgp5SU= \
        --preshared-key=/etc/wg/wg0.A-B \
        --allowed-ips=10.2.0.42/32,fd00:2::42/128
    A# ifconfig wg0 up
    A# ifconfig wg0
    wg0: flags=0x8041<UP,RUNNING,MULTICAST> mtu 1420
            status: active
            inet6 fe80::22f7:d6ff:fe3a:1e60%wg0/64 flags 0 scopeid 0x3
            inet6 fd00:2::1/64 flags 0
            inet 10.2.0.1/24 flags 0

You can put all these commands in /etc/ifconfig.wg0 so that the interface gets configured automatically during startup:

    A# cat /etc/ifconfig.wg0
    net 10.2.0.1/24
    inet6 fd00:2::1/64
    !wgconfig $int set private-key /etc/wg/wg0
    !wgconfig $int set listen-port 1234
    !wgconfig $int add peer B X7EGm3T3IfodBcyilkaC89j0SH3XD6+/pwvp7Dgp5SU= \
        --preshared-key=/etc/wg/wg0.A-B \
        --allowed-ips=10.2.0.42/32,fd00:2::1/128
    up

Configure B to connect to A at 192.0.2.123 on port 1234 and the packets can begin to flow:

    B# ifconfig wg0 create
    B# ifconfig wg0 inet 10.2.0.42/24
    B# ifconfig wg0 inet6 fd00:2::42/64
    B# wgconfig wg0 set private-key /etc/wg/wg0
    B# wgconfig wg0 add peer A \
        N+B4Nelg+4ysvbLW3qenxIwrJVE9MdjMyqrIisH7V0Y= \
        --preshared-key=/etc/wg/wg0.A-B \
        --allowed-ips=10.2.0.1/32,fd00:2::1/128 \
        --endpoint=192.0.2.123:1234
    B# ifconfig wg0 up
    B# ifconfig wg0
    wg0: flags=0x8041<UP,RUNNING,MULTICAST> mtu 1420
            status: active
            inet6 fe80::56eb:59ff:fe3d:d413%wg0/64 flags 0 scopeid 0x3
            inet6 fd00:2::42/64 flags 0
            inet 10.2.0.42/24 flags 0
    B# ping -n 10.2.0.1
    PING 10.2.0.1 (10.2.0.1): 56 data bytes
    64 bytes from 10.2.0.1: icmp_seq=0 ttl=255 time=2.721110 ms
    ...
    B# ping6 -n fd00:2::1
    PING6(56=40+8+8 bytes) fd00:2::42 --> fd00:2::1
    16 bytes from fd00:2::1, icmp_seq=0 hlim=64 time=2.634 ms
    ...

Same as before, you can put all these commands in /etc/ifconfig.wg0 so that the interface gets configured automatically during startup:

    B# cat /etc/ifconfig.wg0
    inet 10.2.0.42/24
    inet6 fd00:2::42/64
    !wgconfig $int set private-key /etc/wg/wg0
    !wgconfig $int add peer A N+B4Nelg+4ysvbLW3qenxIwrJVE9MdjMyqrIisH7V0Y= \
        --preshared-key=/etc/wg/wg0.A-B \
        --allowed-ips=10.2.0.1/32,fd00:2::1/128 \
        --endpoint=192.0.2.123:1234
    up

# SEE ALSO

wg-keygen(8), wgconfig(8), wg-userspace(8)

# COMPATIBILITY

The `wg` interface aims to be compatible with the WireGuard protocol, as described in:

Jason A. Donenfeld, WireGuard: Next Generation Kernel Network Tunnel, https://web.archive.org/web/20180805103233/https://www.wireguard.com/papers/wireguard.pdf, 2018-06-30, Document ID: 4846ada1492f5d92198df154f48c3d54205657bc.

# HISTORY

The `wg` interface first appeared in NetBSD 10.0.

# AUTHORS

The `wg` interface was implemented by Ryota Ozaki <ozaki.ryota@gmail.com>.

December 16, 2024 | NetBSD 11.0