Merge pull request 'yggdrasil: read peers from exports' (#5657) from yggdrasil-export-peers into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5657
This commit is contained in:
@@ -1,7 +1,23 @@
|
|||||||
|
🚧🚧🚧 Experimental 🚧🚧🚧
|
||||||
|
|
||||||
|
Use at your own risk.
|
||||||
|
|
||||||
|
We are still refining its interfaces, instability and breakages are expected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
This module sets up [yggdrasil](https://yggdrasil-network.github.io/) across your clan.
|
This module sets up [yggdrasil](https://yggdrasil-network.github.io/) across your clan.
|
||||||
|
|
||||||
Yggdrasil is designed to be a future-proof and decentralised alternative to
|
Yggdrasil is designed to be a future-proof and decentralised alternative to the
|
||||||
the structured routing protocols commonly used today on the internet. Inside your clan, it will allow you to reach all of your machines.
|
structured routing protocols commonly used today on the internet. Inside your
|
||||||
|
clan, it will allow you to reach all of your machines.
|
||||||
|
|
||||||
|
If you have other services in your inventory which export peers (e.g. the
|
||||||
|
`internet` or the services) as [service
|
||||||
|
exports](https://docs.clan.lol/reference/options/clan_service/#exports), they
|
||||||
|
will be added as yggdrasil peers automatically. This allows using the stable
|
||||||
|
yggdrasil IPv6 address to refer to other hosts and letting yggdrasil decide on
|
||||||
|
the best routing based on available connections.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
|
|||||||
@@ -29,12 +29,13 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
options.peers = lib.mkOption {
|
options.extraPeers = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
Static peers to configure for this host.
|
Additional static peers to configure for this host. If you use a
|
||||||
If not set, local peers will be auto-discovered
|
VPN clan service, it will automatically be added as peers to other hosts.
|
||||||
|
Local peers are also auto-discovered and don't need to be added.
|
||||||
'';
|
'';
|
||||||
example = [
|
example = [
|
||||||
"tcp://192.168.1.1:6443"
|
"tcp://192.168.1.1:6443"
|
||||||
@@ -45,16 +46,67 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
perInstance =
|
perInstance =
|
||||||
{ settings, ... }:
|
{
|
||||||
|
settings,
|
||||||
|
roles,
|
||||||
|
exports,
|
||||||
|
...
|
||||||
|
}:
|
||||||
{
|
{
|
||||||
nixosModule =
|
nixosModule =
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
lib,
|
||||||
|
clan-core,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
|
||||||
|
mkPeers = ip: [
|
||||||
|
# "tcp://${ip}:6443"
|
||||||
|
"quic://${ip}:6443"
|
||||||
|
"ws://${ip}:6443"
|
||||||
|
"tls://${ip}:6443"
|
||||||
|
];
|
||||||
|
|
||||||
|
select' = clan-core.inputs.nix-select.lib.select;
|
||||||
|
|
||||||
|
# TODO make it nicer @lassulus, @picnoir wants microlens
|
||||||
|
# Get a list of all exported IPs from all VPN modules
|
||||||
|
exportedPeerIPs = builtins.foldl' (
|
||||||
|
acc: e:
|
||||||
|
if e == { } then
|
||||||
|
acc
|
||||||
|
else
|
||||||
|
acc ++ (lib.flatten (builtins.filter (s: s != "") (lib.attrValues (select' "peers.*.plain" e))))
|
||||||
|
) [ ] (lib.attrValues (select' "instances.*.networking.?peers.*.host.?plain" exports));
|
||||||
|
|
||||||
|
# Construct a list of peers in yggdrasil format
|
||||||
|
exportedPeers = lib.flatten (map mkPeers exportedPeerIPs);
|
||||||
|
|
||||||
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
|
# Set <yggdrasil ip> <hostname>.<tld> for all hosts.
|
||||||
|
# Networking modules will then add themselves as peers, so we can
|
||||||
|
# always use this to resolve a host via the best possible route,
|
||||||
|
# doing fail-over if needed.
|
||||||
|
networking.extraHosts = lib.strings.concatStringsSep "\n" (
|
||||||
|
lib.filter (n: n != "") (
|
||||||
|
map (
|
||||||
|
name:
|
||||||
|
let
|
||||||
|
ipPath = "${config.clan.core.settings.directory}/vars/per-machine/${name}/yggdrasil/address/value";
|
||||||
|
in
|
||||||
|
if builtins.pathExists ipPath then
|
||||||
|
"${builtins.readFile ipPath} ${name}.${config.clan.core.settings.tld}"
|
||||||
|
else
|
||||||
|
""
|
||||||
|
) (lib.attrNames roles.default.machines)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
clan.core.vars.generators.yggdrasil = {
|
clan.core.vars.generators.yggdrasil = {
|
||||||
|
|
||||||
files.privateKey = { };
|
files.privateKey = { };
|
||||||
@@ -99,7 +151,7 @@
|
|||||||
settings = {
|
settings = {
|
||||||
PrivateKeyPath = "/key";
|
PrivateKeyPath = "/key";
|
||||||
IfName = "ygg";
|
IfName = "ygg";
|
||||||
Peers = settings.peers;
|
Peers = lib.lists.unique (exportedPeers ++ settings.extraPeers);
|
||||||
MulticastInterfaces = [
|
MulticastInterfaces = [
|
||||||
# Ethernet is preferred over WIFI
|
# Ethernet is preferred over WIFI
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,13 @@
|
|||||||
roles.default.machines.peer1 = { };
|
roles.default.machines.peer1 = { };
|
||||||
roles.default.machines.peer2 = { };
|
roles.default.machines.peer2 = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Peers are set form exports of the internet service
|
||||||
|
instances."internet" = {
|
||||||
|
module.name = "internet";
|
||||||
|
roles.default.machines.peer1.settings.host = "peer1";
|
||||||
|
roles.default.machines.peer2.settings.host = "peer2";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user