WireGuard
LibreELEC can be configured as a WireGuard VPN client allowing you to accessing media in a remote location or tunnel traffic to avoid local inspection of network activity. This guide assumes configuration of a single WireGuard tunnel that is persistent, i.e. activated on device boot so that Kodi network traffic is routed through the WireGuard VPN tunnel.
WireGuard tunnels are managed by a ConnMan VPN plugin (connman-vpn.service) that acts as a companion to the network connection manager daemon (connman.service). The VPN plugin watches /storage/.config/wireguard/*.config and definea ConnMan services from auto-discovered configuration files. Once a valid WireGuard .config has been imported it can be connected manually using connmanctl from the SSH console or scripted from a systemd service that runs on boot. Connections can also be managed using the network 'Connections' tab in the LibreELEC settings add-on which controls ConnMan via d-bus.

Sample Config

ConnMan uses its own configuration file format (see below) so you cannot import/use the files exported from WireGuard server tools and third-party VPN services - the format is different. Those files will contain everything you need, but you must manually transpose the information into the ConnMan format:
1
[provider_wireguard]
2
Type = WireGuard
3
Name = WireGuard (Home)
4
Host = 185.210.30.121
5
WireGuard.Address = 10.2.0.2/24
6
WireGuard.ListenPort = 51820
7
WireGuard.PrivateKey = qKIj010hDdWSjQQyVCnEgthLXusBgm3I6HWrJUaJymc=
8
WireGuard.PublicKey = zzqUfWGIil6QxrAGz77HE5BGUEdD2PgHYnCg3CDKagE=
9
WireGuard.PresharedKey = DfEYeVs04HS9XhKGM4/ZXHG3Qc4MFK2AJd8XouYDbRQ=
10
WireGuard.DNS = 8.8.8.8, 1.1.1.1
11
WireGuard.AllowedIPs = 0.0.0.0/0
12
WireGuard.EndpointPort = 51820
13
WireGuard.PersistentKeepalive = 25
Copied!
Name = AnythingYouLike Host = IP of the WireGuard server WireGuard.Address = The internal IP of the client node, e.g. a /24 address WireGuard.ListenPort = The client listen port (optional) WireGuard.PrivateKey = The client private key WireGuard.PublicKey = The server public key WireGuard.PresharedKey = The server pre-shared key (optional) WireGuard.DNS = Nameserver to be used with the connection (optional) WireGuard.AllowedIPs = Subnets accessed via the tunnel, 0.0.0.0/0 is "route all traffic" WireGuard.EndpointPort = The server ListenPort WireGuard.PersistentKeepalive = Periodic keepalive in seconds (optional)

Creating Keys

If you need to create some, run wg-keygen from the SSH console and /storage/.cache/wireguard will contain new publickey, privatekey, and preshared files with keys inside. Most users will not need to generate WireGuard keys as they will be in the configuration file provided by a VPN service provider.

Testing Connections

Once you have saved a configuration file, check it is valid:
1
RPi4:~ # connmanctl services
2
* R home vpn_185_210_30_121
3
*AO Wired ethernet_dca622135939_cable
Copied!
In the above example vpn_185_210_30_121 was created (vpn_host) as the ConnMan service name. Test the service will connect using:
1
RPi4:~ # connmanctl connect vpn_185_210_30_121
Copied!
ConnMan will create a new network interface, so ifconfig will show wg0 or sometimes a higer number like wg1 or wg2:
1
RPi4:~ # ifconfig
2
eth0 Link encap:Ethernet HWaddr DC:A6:32:13:26:3b
3
inet addr:192.168.10.25 Bcast:192.168.10.255 Mask:255.255.255.0
4
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
5
RX packets:3136938 errors:0 dropped:40816 overruns:0 frame:0
6
TX packets:242506 errors:0 dropped:0 overruns:0 carrier:0
7
collisions:0 txqueuelen:1000
8
RX bytes:310409413 (296.0 MiB) TX bytes:22433323 (21.3 MiB)
9
10
lo Link encap:Local Loopback
11
inet addr:127.0.0.1 Mask:255.0.0.0
12
inet6 addr: ::1/128 Scope:Host
13
UP LOOPBACK RUNNING MTU:65536 Metric:1
14
RX packets:6109 errors:0 dropped:0 overruns:0 frame:0
15
TX packets:6109 errors:0 dropped:0 overruns:0 carrier:0
16
collisions:0 txqueuelen:1000
17
RX bytes:415013 (405.2 KiB) TX bytes:415013 (405.2 KiB)
18
19
wg0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
20
inet addr:10.2.0.2 P-t-P:10.2.0.2 Mask:255.255.255.0
21
UP POINTOPOINT RUNNING NOARP MTU:1420 Metric:1
22
RX packets:13744 errors:0 dropped:0 overruns:0 frame:0
23
TX packets:11080 errors:0 dropped:0 overruns:0 carrier:0
24
collisions:0 txqueuelen:1000
25
RX bytes:13775220 (13.1 MiB) TX bytes:1232552 (1.1 MiB)
Copied!
You should be able to ping the remote (server) side of the WireGuard VPN tunnel. In our example this is 10.2.0.1:
1
RPi4:~ # ping 10.2.0.1
2
PING 10.2.0.1 (10.2.0.1): 56 data bytes
3
64 bytes from 10.2.0.1: seq=0 ttl=64 time=147.936 ms
4
64 bytes from 10.2.0.1: seq=1 ttl=64 time=147.955 ms
Copied!
The routing table will show normal traffic routed to the wg0 interface:
1
RPi4:~ # route
2
Kernel IP routing table
3
Destination Gateway Genmask Flags Metric Ref Use Iface
4
default * 0.0.0.0 U 0 0 0 wg0
5
1.1.1.1 * 255.255.255.255 UH 0 0 0 wg0
6
8.8.8.8 * 255.255.255.255 UH 0 0 0 wg0
7
10.2.0.0 * 255.255.255.0 U 0 0 0 wg0
8
192.168.10.0 * 255.255.255.0 U 0 0 0 eth0
9
192.168.10.1 * 255.255.255.255 UH 0 0 0 eth0
10
185.210.30.121 192.168.10.1 255.255.255.255 UGH 0 0 0 eth0
Copied!
To disconnect the ConnMan service:
1
RPi4:~ # connmanctl disconnect vpn_185_210_30_121
Copied!
Check ifconfig again and the WireGuard interface will be gone.

Configuring Systemd

Create a systemd wireguard.service file to start the connection automatically on boot, after the network starts, and before Kodi is launched. The sample wireguard.service file looks like:
1
[Unit]
2
Description=WireGuard VPN Service
3
After=network-online.target nss-lookup.target wait-time-sync.service connman-vpn.service
4
Before=kodi.service
5
6
[Service]
7
Type=oneshot
8
RemainAfterExit=yes
9
ExecStart=/usr/bin/connmanctl connect vpn_service_name_goes_here
10
ExecStop=/usr/bin/connmanctl disconnect vpn_service_name_goes_here
11
12
[Install]
13
WantedBy=multi-user.target
Copied!
Copy the sample wireguard.service file to /storage/.config/system.d/wireguard.service
1
cp /storage/.config/system.d/wireguard.service.sample /storage/.config/system.d/wireguard.service
Copied!
Replace vpn_service_name_goes_here with your service name, e.g. vpn_185_210_30_121 using nano. Use ctrl+o to save changes and ctrl+x to exit nano:
1
nano /storage/.config/system.d/wireguard.service
Copied!
Now we can enable and start the service:
1
RPi4:~ # systemctl enable /storage/.config/system.d/wireguard.service
2
Created symlink /storage/.config/system.d/multi-user.target.wants/wireguard.service → /storage/.config/system.d/wireguard.service.
3
RPi4:~ # systemctl start wireguard.service
Copied!
Check the WireGuard tunnel is active using "ifconfig" and "ping" and if all is good, reboot to test the WireGuard tunnel comes up automatically on boot.

Known Issues

ConnMan makes wg0 route all traffic over the WireGuard tunnel by default, no matter what WireGuard.AllowedIPs configuration you set. To route only specific networks via the tunnel the ConnMan service order (which influences routing order) must be changed.
Note thesleep and connmanctl move-after and route add commands used in the following tweaked systemd service file:
1
[Unit]
2
Description=WireGuard VPN Service
3
After=network-online.target nss-lookup.target connman.service connman-vpn.service bluetooth.service
4
Wants=network-online.target nss-lookup.target connman.service connman-vpn.service bluetooth.service
5
6
[Service]
7
Type=oneshot
8
RemainAfterExit=yes
9
ExecStart=/bin/sleep 5
10
ExecStart=/usr/bin/connmanctl connect vpn_X_klaus
11
ExecStart=/usr/bin/connmanctl move-after vpn_X_klaus ethernet_b827eb10c45a_cable
12
ExecStart=/usr/bin/connmanctl move-after vpn_X_klaus ethernet_b827eb10c45a_cable
13
ExecStart=/usr/sbin/route add -net 192.168.2.0 netmask 255.255.255.0 gw 10.0.0.2
14
ExecStop=/usr/bin/connmanctl disconnect vpn_X_klaus
15
16
[Install]
17
WantedBy=multi-user.target
Copied!

Thanks

Big thanks! to ConnMan maintainer Daniel Wagner (wagi) who worked with LibreELEC staff to implement WireGuard support in ConnMan (he wrote the code, we abused tested it).
Last modified 9mo ago