Skip to content

Commit bedb05d

Browse files
committed
Add WireGuard network support
- Introduced a new network type: WireGuard. - Updated network type definitions and handling in various components. - Implemented the `nicWireguard` device type for managing WireGuard interfaces. - Added validation and configuration logic for WireGuard networks. - Enhanced network loading and management to include WireGuard functionality. This update allows users to create and manage WireGuard networks within the system, expanding the networking capabilities significantly. Signed-off-by: Salem Yaslem <[email protected]>
1 parent 7e6d271 commit bedb05d

File tree

12 files changed

+1205
-10
lines changed

12 files changed

+1205
-10
lines changed

doc/explanation/networks.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ Incus supports the following network types:
8080
This means that you can create your own OVN network as a non-admin user, even in a restricted project.
8181
```
8282

83+
{ref}`network-wireguard`
84+
: % Include content from [../reference/network_wireguard.md](../reference/network_wireguard.md)
85+
```{include} ../reference/network_wireguard.md
86+
:start-after: <!-- Include start wireguard intro -->
87+
:end-before: <!-- Include end wireguard intro -->
88+
```
89+
90+
In Incus context, the `wireguard` network type creates a WireGuard VPN interface that instances can connect to.
91+
WireGuard operates at layer 3 (network layer), making it suitable for secure VPN connections.
92+
8393
### External networks
8494

8595
% Include content from [../reference/network_external.md](../reference/network_external.md)

doc/howto/network_create.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ The following network types are available:
2929
* - `physical`
3030
- {ref}`network-physical`
3131
- {ref}`network-physical-options`
32+
* - `wireguard`
33+
- {ref}`network-wireguard`
34+
- {ref}`network-wireguard-options`
3235
3336
```
3437

doc/reference/devices_nic.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ The following NICs can be added using the `nictype` or `network` options:
5353
The following NICs can be added using only the `network` option:
5454

5555
- [`ovn`](nic-ovn): Uses an existing OVN network and creates a virtual device pair to connect the instance to it.
56+
- [`wireguard`](nic-wireguard): Uses an existing WireGuard network and creates a routed connection to it.
5657

5758
The following NICs can be added using only the `nictype` option:
5859

@@ -294,6 +295,37 @@ NIC devices of type `p2p` have the following device options:
294295
You can select this NIC type only through the `nictype` option.
295296
```
296297

298+
A `routed` NIC creates a virtual device pair to connect the host to the instance and sets up static routes and proxy ARP/NDP entries to allow the instance to join the network of a designated parent interface.
299+
300+
(nic-wireguard)=
301+
### `nictype`: `wireguard`
302+
303+
```{note}
304+
You can select this NIC type only through the `network` option (see {ref}`network-wireguard` for information about the managed `wireguard` network).
305+
```
306+
307+
A `wireguard` NIC connects an instance to a WireGuard VPN network.
308+
The instance will automatically receive an IP address from the WireGuard network's address range if not manually specified.
309+
310+
WireGuard operates at layer 3 (network layer), making it suitable for secure VPN connections between instances and remote peers.
311+
312+
#### Device options
313+
314+
NIC devices of type `wireguard` have the following device options:
315+
316+
% Include content from [config_options.txt](../config_options.txt)
317+
```{include} ../config_options.txt
318+
:start-after: <!-- config group devices-nic_wireguard start -->
319+
:end-before: <!-- config group devices-nic_wireguard end -->
320+
```
321+
322+
(nic-routed)=
323+
### `nictype`: `routed`
324+
325+
```{note}
326+
You can select this NIC type only through the `nictype` option.
327+
```
328+
297329
A `routed` NIC creates a virtual device pair to connect the host to the instance and sets up static routes and proxy ARP/NDP entries to allow the instance to join the network of a designated parent interface.
298330
For containers it uses a virtual Ethernet device pair, and for VMs it uses a TAP device.
299331

@@ -359,6 +391,68 @@ NIC devices of type `routed` have the following device options:
359391

360392
## `bridged`, `macvlan` or `ipvlan` for connection to physical network
361393

394+
The `bridged`, `macvlan` and `ipvlan` interface types can be used to connect to an existing physical network.
395+
However, it differs from `ipvlan` because it does not need IPVLAN support in the kernel, and the host and the instance can communicate with each other.
396+
397+
This NIC type respects `netfilter` rules on the host and uses the host's routing table to route packets, which can be useful if the host is connected to multiple networks.
398+
399+
IP addresses, gateways and routes
400+
: You must manually specify the IP addresses (using `ipv4.address` and/or `ipv6.address`) before the instance is started.
401+
402+
For containers, the NIC configures the following link-local gateway IPs on the host end and sets them as the default gateways in the container's NIC interface:
403+
404+
169.254.0.1
405+
fe80::1
406+
407+
For VMs, the gateways must be configured manually or via a mechanism like `cloud-init` (see the {ref}`how to guide <instances-routed-nic-vm>`).
408+
409+
```{note}
410+
If your container image is configured to perform DHCP on the interface, it will likely remove the automatically added configuration.
411+
In this case, you must configure the IP addresses and gateways manually or via a mechanism like `cloud-init`.
412+
```
413+
414+
The NIC type configures static routes on the host pointing to the instance's `veth` interface for all of the instance's IPs.
415+
416+
Multiple IP addresses
417+
: Each NIC device can have multiple IP addresses added to it.
418+
419+
However, it might be preferable to use multiple `routed` NIC interfaces instead.
420+
In this case, set the `ipv4.gateway` and `ipv6.gateway` values to `none` on any subsequent interfaces to avoid default gateway conflicts.
421+
Also consider specifying a different host-side address for these subsequent interfaces using `ipv4.host_address` and/or `ipv6.host_address`.
422+
423+
Parent interface
424+
: This NIC can operate with and without a `parent` network interface set.
425+
426+
: With the `parent` network interface set, proxy ARP/NDP entries of the instance's IPs are added to the parent interface, which allows the instance to join the parent interface's network at layer 2.
427+
: To enable this, the following network configuration must be applied on the host via `sysctl`:
428+
429+
- When using IPv4 addresses:
430+
431+
```
432+
net.ipv4.conf.<parent>.forwarding=1
433+
```
434+
435+
- When using IPv6 addresses:
436+
437+
```
438+
net.ipv6.conf.all.forwarding=1
439+
net.ipv6.conf.<parent>.forwarding=1
440+
net.ipv6.conf.all.proxy_ndp=1
441+
net.ipv6.conf.<parent>.proxy_ndp=1
442+
```
443+
444+
#### Device options
445+
446+
NIC devices of type `routed` have the following device options:
447+
448+
% Include content from [config_options.txt](../config_options.txt)
449+
```{include} ../config_options.txt
450+
:start-after: <!-- config group devices-nic_routed start -->
451+
:end-before: <!-- config group devices-nic_routed end -->
452+
```
453+
454+
## `bridged`, `macvlan` or `ipvlan` for connection to physical network
455+
362456
The `bridged`, `macvlan` and `ipvlan` interface types can be used to connect to an existing physical network.
363457

364458
`macvlan` effectively lets you fork your physical NIC, getting a second interface that is then used by the instance.

doc/reference/network_wireguard.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
(network-wireguard)=
2+
# WireGuard network
3+
4+
<!-- Include start wireguard intro -->
5+
{abbr}`WireGuard` is a modern, fast, and secure VPN tunnel that uses state-of-the-art cryptography.
6+
It is designed to be faster, simpler, and more secure than IPsec and OpenVPN.
7+
See [`www.wireguard.com`](https://www.wireguard.com/) for more information.
8+
<!-- Include end wireguard intro -->
9+
10+
The `wireguard` network type allows you to create a WireGuard VPN interface that instances can connect to using the `wireguard` NIC type.
11+
This enables secure point-to-point and site-to-site VPN connections.
12+
13+
WireGuard networks operate at layer 3 (network layer), making them suitable for routing traffic between instances and remote peers.
14+
15+
```{note}
16+
WireGuard requires the `wireguard-tools` package to be installed on the host system.
17+
```
18+
19+
(network-wireguard-options)=
20+
## Configuration options
21+
22+
The following configuration key namespaces are currently supported for the `wireguard` network type:
23+
24+
- `user` (free-form key/value for user metadata)
25+
26+
```{note}
27+
{{note_ip_addresses_CIDR}}
28+
```
29+
30+
The following configuration options are available for the `wireguard` network type:
31+
32+
% Include content from [config_options.txt](../config_options.txt)
33+
```{include} ../config_options.txt
34+
:start-after: <!-- config group network_wireguard-common start -->
35+
:end-before: <!-- config group network_wireguard-common end -->
36+
```
37+
38+
(network-wireguard-features)=
39+
## Supported features
40+
41+
The following features are supported for the `wireguard` network type:
42+
43+
- **Node-specific configuration**: Each cluster member can have different WireGuard interface configurations
44+
- **Network peering**: WireGuard networks support peering with remote WireGuard peers
45+
46+
(network-wireguard-examples)=
47+
## Examples
48+
49+
### Create a basic WireGuard network
50+
51+
```bash
52+
incus network create wg0 --type=wireguard ipv4.address=10.0.0.1/24
53+
```
54+
55+
### Create a WireGuard network with IPv6
56+
57+
```bash
58+
incus network create wg0 --type=wireguard ipv4.address=10.0.0.1/24 ipv6.address=2001:db8::1/64
59+
```
60+
61+
### Create a WireGuard network with a peer
62+
63+
```bash
64+
incus network create wg0 --type=wireguard \
65+
ipv4.address=10.0.0.1/24 \
66+
private_key="<base64_private_key>" \
67+
peers.remote.public_key="<base64_public_key>" \
68+
peers.remote.allowed_ips="10.0.0.0/24" \
69+
peers.remote.endpoint="192.168.1.100:51820" \
70+
peers.remote.persistent_keepalive=25
71+
```
72+
73+
### Connect an instance to a WireGuard network
74+
75+
```bash
76+
incus launch images:ubuntu/jammy/cloud myinstance --network=wg0
77+
```
78+
79+
The instance will automatically receive an IP address from the WireGuard network's address range.
80+

internal/server/db/networks.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -561,11 +561,12 @@ type NetworkType int
561561

562562
// Network types.
563563
const (
564-
NetworkTypeBridge NetworkType = iota // Network type bridge.
565-
NetworkTypeMacvlan // Network type macvlan.
566-
NetworkTypeSriov // Network type sriov.
567-
NetworkTypeOVN // Network type ovn.
568-
NetworkTypePhysical // Network type physical.
564+
NetworkTypeBridge NetworkType = iota // Network type bridge.
565+
NetworkTypeMacvlan // Network type macvlan.
566+
NetworkTypeSriov // Network type sriov.
567+
NetworkTypeOVN // Network type ovn.
568+
NetworkTypePhysical // Network type physical.
569+
NetworkTypeWireguard // Network type wireguard.
569570
)
570571

571572
// NetworkNode represents a network node.
@@ -693,6 +694,8 @@ func networkFillType(network *api.Network, netType NetworkType) {
693694
network.Type = "ovn"
694695
case NetworkTypePhysical:
695696
network.Type = "physical"
697+
case NetworkTypeWireguard:
698+
network.Type = "wireguard"
696699
default:
697700
network.Type = "" // Unknown
698701
}

internal/server/device/device_load.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ func newByType(state *state.State, projectName string, conf deviceConfig.Device)
3838
dev = &nicBridged{}
3939
case "routed":
4040
dev = &nicRouted{}
41+
case "wireguard":
42+
dev = &nicWireguard{}
4143
case "macvlan":
4244
dev = &nicMACVLAN{}
4345
case "sriov":

0 commit comments

Comments
 (0)