gluon-packages/net/wgpeerselector
lemoer 0a334b837f wgpeerselector: add package
For docs, see net/wgpeerselector/README.md.
2021-09-15 01:05:14 +02:00
..
files wgpeerselector: add package 2021-09-15 01:05:14 +02:00
Makefile wgpeerselector: add package 2021-09-15 01:05:14 +02:00
README.md wgpeerselector: add package 2021-09-15 01:05:14 +02:00

README.md

wgpeerselector

The wireguard peer selector is a daemon allowing to connect to only one wireguard peer of a set of N peers. It does that by randomly picking one peer, trying to connect and on failure trying to connect to the next peer. It is comparable to setting the "peer limit" to one in fastd. The daemon is written in lua and hardwired to OpenWrt mechanisms.

Features:

  • Status socket via UBUS.
  • Routes for "Allowed IPs" are installed to the kernel.
  • Synchronize time via NTP.
    • Currently necessary in wireguard to reestablish a connection after rebooting. Reference
  • Can change its unix group.

How does it work?

The daemon is configured using its netifd proto wgpeerselector. The wireguard interface is set up by the standard wireguard netifd proto wireguard. Configuring peers via the wireguard proto is not necessary because this will be done by wgpeerselector based on its uci config:

/etc/config/network:

config interface 'vpn'
	option proto 'wireguard'
	option fwmark '1'
	option private_key 'YOUR_PRIVATE_KEY_GOES_HERE'
	list addresses 'fe80::02a4:18ff:fe7e:a10d'
	option disabled '0'

config interface 'vpn_peerselector'
	option proto 'wgpeerselector'
	option transitive '1'
	option ifname 'vpn'
	option unix_group 'YOUR_UNIX_GROUP_GOES_HERE'   # this is optional

/etc/config/wgpeerselector:

config peer 'test_unknown_a'
	option enabled '1'
	option public_key 'mIDOdscl2R3Dq+YthxdTvvtH4D53VhawzEnmet+E7W0='
	list allowed_ips 'fe80::1/128'
	option ifname 'vpn'
	option endpoint 'hostname.example.com:51820'

Status information can be obtained via ubus:

root@platzhalter-525400123456:~# ubus call wgpeerselector.vpn status
{
	"peers": {
		"test_unknown_a": false,
		"test_unknown_b": false,
		"test_sn07": {
			"established": 1490
		}
	}
}

Algorithm:

A connection is considered as "established" if the latest handshakes was within the last 2.5 minutes.

Installing a peer:

  1. Resolve its endpoint if necessary.
  2. Randomly pick a remote IP.
  3. Install the peer with that ip to the kernel.
  4. Wait 5 seconds.
  5. Check whether the connection is established.
    • If not, remove the peer from the kernel again.

Main Loop:

  • Wait for the interface, if it does not exist.
  • Try to synchronize time via NTP, if not done yet.
  • If no connection is established:
    • Randomly pick a peer.
    • Try to establish a connection.
  • If a connection is established:
    • Check every 5 seconds if the connection is still established.

Picking peers is done in such a way that all peers are tried once before one peer is attempted for the second time. The same goes for the DNS resolultion of the endpoints.

Warning: This algorithm only works if something is causing traffic into the wireguard interface. This is due to the fact, that wireguard is only doing handshakes, if it has to. While running mesh protocols on top of the wireguard interface this is usually not a problem, since those protocols periodically send Hello, OGM, ... packets.