-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
For docs, see net/wgpeerselector/README.md.
- Loading branch information
1 parent
0648b2d
commit 0a334b8
Showing
5 changed files
with
656 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
include $(TOPDIR)/rules.mk | ||
|
||
PKG_NAME:=wgpeerselector | ||
PKG_VERSION:=1 | ||
|
||
include $(INCLUDE_DIR)/package.mk | ||
|
||
define Package/wgpeerselector | ||
SECTION:=net | ||
CATEGORY:=Network | ||
TITLE:=Wireguard peer selector daemon | ||
DEPENDS:=+lua +wireguard-tools +libubox-lua +libubus-lua +luaposix | ||
endef | ||
|
||
define Build/Configure | ||
endef | ||
|
||
define Build/Compile | ||
endef | ||
|
||
define Package/wgpeerselector/install | ||
$(CP) ./files/* $(1)/ | ||
endef | ||
|
||
$(eval $(call BuildPackage,wgpeerselector)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
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](https://lists.zx2c4.com/pipermail/wireguard/2019-February/003850.html) | ||
- 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. |
Empty file.
33 changes: 33 additions & 0 deletions
33
net/wgpeerselector/files/lib/netifd/proto/wgpeerselector.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/bin/sh | ||
|
||
. /lib/functions.sh | ||
. ../netifd-proto.sh | ||
init_proto "$@" | ||
|
||
proto_wgpeerselector_init_config() { | ||
proto_config_add_string 'unix_group' | ||
} | ||
|
||
proto_wgpeerselector_setup() { | ||
local config="$1" | ||
local iface="$2" | ||
local unix_group | ||
|
||
json_get_vars unix_group | ||
|
||
(proto_add_host_dependency "$config" '' "$iface") | ||
|
||
proto_init_update "$iface" 1 | ||
proto_send_update "$config" | ||
|
||
proto_run_command "$config" wgpeerselector \ | ||
-i "$iface" ${unix_group:+--group "$unix_group"} | ||
} | ||
|
||
|
||
proto_wgpeerselector_teardown() { | ||
local config="$1" | ||
proto_kill_command "$config" | ||
} | ||
|
||
add_protocol wgpeerselector |
Oops, something went wrong.