R.A.I.T. - Redundant Array of Inexpensive Tunnels
About
rait, acronym for redundant array of inexpensive tunnels, is the missing the missing piece of the puzzle, for using wireguard to create distributed overlay networks. It serves the purpose by creating point to point tunnels between all participants, forming fully-meshed link-local connectivity.
Status
This project has reached a certain point of stability, bugs will be sorted out and code quality will be improved. Meanwhile, efforts are poured into wireguard itself to eliminate the need of multiple wireguard tunnels, more specifically, to implement AF_WIREGUARD in order to move wireguard beyond IP, enabling exotic use cases such as MPLS over wireguard.
Operation
Due to technical limitation of wireguard, namely crypto routing, it struggles to be integrated into routing daemons, thus we takes a different approach, creating a separate interface for each peer, abusing wireguard as a point to point transport, opposing to it's original design. While this approach do ensures fully-meshed connectivity instead of a hub and spoke architecture, it also voids the possibility to reuse a single port for multiple peers, though the consumption of port range is negligible (after all, we have 65535 ports to waste), the coordination of port usage is a challenging task. rait solves the problem with the concept of "SendPort", a unique port assigned to each node, as the destination port of all packets originated by it. To separate overlay from underlay and avoid routing loops, rait extends the fwmark and netns used by wireguard with another mean, ifgroup, to eases the management of large volume of interfaces.
Configuration Files
# /etc/rait/rait.conf
registry = "https://example.com/rait" # url of rait registry
operator_key = "EA8CQ4CAsvLuEnJvu8FQt0OIMh+NhlWIk0o12zNgekU=" # private key of node operator
private_key = "KJJXmDtAXSrMGuIJVy/2eP65gXm1PTy7vCR/4O/vEEI=" # wireguard private key
namespace = "rait" # netns to move interfaces into
# both ifgroup and ifprefix should be unique across transports
transport {
address_family = "ip4"
address = "8.8.8.8"
send_port = 50153
mtu = 1400
ifprefix = "rait4x"
ifgroup = 54
fwmark = 54
random_port = false
}
babeld {
enabled = true
socket_type = "unix"
socket_addr = "/run/babeld.ctl"
param = "type tunnel link-quality true"
footnote = "interface host type wireless"
}
remarks = {
prefix = "1.1.1.0/24"
name = "foo"
operator = "bar"
}
Registry
Registry is path to an array of node metadata, in json format, an example is provided below.
[
{
"public_key": "qA8pQf5Zm+TvmOsKgK6+Gfl3FV5f3nsD1URQy5kdgB7=",
"operator_key": "kM4Md5q/0MfbBkqktxJnG5j20grE8ugs8Ybj8KuNp3Q=",
"remarks": {
"name": "foo"
},
"endpoints": [
{
"address_family": "ip6",
"send_port": 51932,
"address": "example.org"
}
]
},
{
"public_key": "yEvDQ5YjaoPAUIhq+qq77evNnBt93tvYFvRE+QICAXk=",
"operator_key": "0KG7d6KKaIf7+nT3m9SRer+kgtxhMd8QYYWs7FuWNF8=",
"remarks": {
"maintainer": "bob",
"name": "bar"
},
"endpoints": [
{
"address_family": "ip4",
"send_port": 23344,
"address": "example.com"
},
{
"address_family": "ip6",
"send_port": 23366,
"address": "2001::1"
}
]
}
]
URL
rait accepts the use of url in configuration files or in the command line, the url scheme is defined bellow.
/some/random/path # filesystem path
- # stdin or stdout, depending on the context
https://example.com/some/file # http url
Known Issues
When using rait with babeld version < 1.9.1, it may hang forever as the IPC protocol has changed and there's no support nor detection for older versions of the protocol.
该项目的开发工作由大学生创新创业项目支持