<div dir="ltr"><div dir="ltr">Hello,<br><br>I've been giving my free time on a side project called WireHub<br>(<a href="https://github.com/gawen/wirehub">https://github.com/gawen/wirehub</a>), which is a simple tool to build<br>decentralized, peer-to-peer and secure overlay networks. It dynamically<br>configures WireGuard tunnels, discoverying peers' endpoints via a authenticated<br>DHT, going through NATs, and relaying the WireGuard traffic if no P2P<br>communication is possible.<br><br>Overlay networks are defined by a single human-readable file which lists the<br>hostname and public key for each nodes of the network. Here's an example:<br><br>    name test               # network name is 'test'<br>    subnet <a href="http://10.0.42.0/24">10.0.42.0/24</a>     # overlay subnetwork is <a href="http://10.0.42.0/24">10.0.42.0/24</a><br>    workbit 8               # PoW parameter for DHT security<br><br>    # a public bootstrap node<br>    boot P17zMwXJFbBdJEn05RFIMADw9TX5_m2xgf31OgNKX3w <a href="http://bootstrap.wirehub.io">bootstrap.wirehub.io</a><br><br>    # Add trusted node 'a.test' to the overlay network.<br>    # Each trusted node are at least identified by an human-readable hostname<br>    # and a base64 public key.<br>    trust a.test KJ7YGrBeqLLm_JJ1huIS26OnqAVFy57z5UJqjyMagW4<br><br>    # If the endpoint of a peer is static, it might be set after the public key.<br>    # Note that this is optional, as endpoints can be dynamically found in the<br>    # DHT.<br>    trust b.test eIix5ldvqDzOIrG9ViKTe9TSBlF4g9nUwKi20C06hFM 12.34.56.78<br><br>    # By default WireHub assigns nodes an (overlay) private IP, but a static<br>    # private IP might be defined<br>    trust c.test 10.0.42.254 kKZzuIm11zkBSHL9ETRwEthIBbLTvz840F_k4mhI_Hs<br>    ...<br><br>To start a peer,<br><br>    # wh up ./config private-key ./sk<br><br>When a network is up, the node's hostnames are resolved in userland.<br><br>    # ping b.test<br>    PING 10.0.42.2 (10.0.42.2): 56 data bytes<br>    64 bytes from <a href="http://10.0.42.2">10.0.42.2</a>: seq=0 ttl=64 time=106.801 ms<br>    64 bytes from <a href="http://10.0.42.2">10.0.42.2</a>: seq=1 ttl=64 time=49.778 ms<br><br>WireGuard and WireHub uses the same Curve25519 key. WireHub keys must be<br>generated with `wh genkey`, which adds a Proof-of-Work to the generation of the<br>Curve25519 key, in order to mitigate Sybil attacks on the DHT. A high workbit<br>will require more work to generate a valid key.<br><br>    # wh genkey workbit 8       # fast<br>    MFaqLuutFvNs79Xc9zhOUofIbL3xSLz1uo+RB1xB73s=<br>    # wh genkey workbit 8 | wh pubkey | wh workbit<br>    8<br>    # wh genkey workbit 16      # will take more time to generate<br>    kLfotsCIfB/7OcDGeLenptfy2Dzav9wmVZjVQ0Gvnk0=<br>    # wh genkey workbit 16 | wh pubkey | wh workbit<br>    16<br><br>    # wg genkey | wh pubkey | wh workbit    # WireGuard keys have 0 workbit<br>    0<br><br>Under the hood, WireHub runs its own UDP protocol, binding the same UDP port<br>than the WireGuard interface (for NAT trasversal technique reasons). It does so using<br>libpcap. The first byte of a WireHub packet is 0xff, which corresponds to an<br>invalid WireGuard packet with message type outside the valid range 0x00-0x03.<br><br>WireHub currently authenticates its packets with a custom cryptographic scheme<br>based on the node's keys. In the future, it might be better to tunnel WireHub<br>packets through WireGuard, yet I'm not sure how to do that simply at the moment,<br>as WireHub packets are not IP packets but more like authenticated messages.<br><br>There's much room for improvement (security, allowed-ips management, more UDP<br>hole punching techniques, faster relaying), but it's usable. Docker images are<br>provided to ease quick starting.<br><br>Feel free to test and give some feedbacks!<br><br>Also, I'll be at FOSDEM 2019 next week-end, so see you there! 🍺<br><br>Gawen</div></div>