140 lines
4.2 KiB
Nix
140 lines
4.2 KiB
Nix
import ../make-test-python.nix ({ lib, ... }:
|
|
let
|
|
snakeoil-keys = import ./snakeoil-keys.nix;
|
|
|
|
hosts = lib.attrNames snakeoil-keys;
|
|
|
|
subnetOf = name: config:
|
|
let
|
|
subnets = config.services.tinc.networks.myNetwork.hostSettings.${name}.subnets;
|
|
in
|
|
(builtins.head subnets).address;
|
|
|
|
makeTincHost = name: { subnet, extraConfig ? { } }: lib.mkMerge [
|
|
{
|
|
subnets = [{ address = subnet; }];
|
|
settings = {
|
|
Ed25519PublicKey = snakeoil-keys.${name}.ed25519Public;
|
|
};
|
|
rsaPublicKey = snakeoil-keys.${name}.rsaPublic;
|
|
}
|
|
extraConfig
|
|
];
|
|
|
|
makeTincNode = { config, ... }: name: extraConfig: lib.mkMerge [
|
|
{
|
|
services.tinc.networks.myNetwork = {
|
|
inherit name;
|
|
rsaPrivateKeyFile =
|
|
builtins.toFile "rsa.priv" snakeoil-keys.${name}.rsaPrivate;
|
|
ed25519PrivateKeyFile =
|
|
builtins.toFile "ed25519.priv" snakeoil-keys.${name}.ed25519Private;
|
|
|
|
hostSettings = lib.mapAttrs makeTincHost {
|
|
static = {
|
|
subnet = "10.0.0.11";
|
|
# Only specify the addresses in the node's vlans, Tinc does not
|
|
# seem to try each one, unlike the documentation suggests...
|
|
extraConfig.addresses = map
|
|
(vlan: { address = "192.168.${toString vlan}.11"; port = 655; })
|
|
config.virtualisation.vlans;
|
|
};
|
|
dynamic1 = { subnet = "10.0.0.21"; };
|
|
dynamic2 = { subnet = "10.0.0.22"; };
|
|
};
|
|
};
|
|
|
|
networking.useDHCP = false;
|
|
|
|
networking.interfaces."tinc.myNetwork" = {
|
|
virtual = true;
|
|
virtualType = "tun";
|
|
ipv4.addresses = [{
|
|
address = subnetOf name config;
|
|
prefixLength = 24;
|
|
}];
|
|
};
|
|
|
|
# Prevents race condition between NixOS service and tinc creating the
|
|
# interface.
|
|
# See: https://github.com/NixOS/nixpkgs/issues/27070
|
|
systemd.services."tinc.myNetwork" = {
|
|
after = [ "network-addresses-tinc.myNetwork.service" ];
|
|
requires = [ "network-addresses-tinc.myNetwork.service" ];
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = [ 655 ];
|
|
networking.firewall.allowedUDPPorts = [ 655 ];
|
|
}
|
|
extraConfig
|
|
];
|
|
|
|
in
|
|
{
|
|
name = "tinc";
|
|
meta.maintainers = with lib.maintainers; [ minijackson ];
|
|
|
|
nodes = {
|
|
|
|
static = { ... } @ args:
|
|
makeTincNode args "static" {
|
|
virtualisation.vlans = [ 1 2 ];
|
|
|
|
networking.interfaces.eth1.ipv4.addresses = [{
|
|
address = "192.168.1.11";
|
|
prefixLength = 24;
|
|
}];
|
|
|
|
networking.interfaces.eth2.ipv4.addresses = [{
|
|
address = "192.168.2.11";
|
|
prefixLength = 24;
|
|
}];
|
|
};
|
|
|
|
|
|
dynamic1 = { ... } @ args:
|
|
makeTincNode args "dynamic1" {
|
|
virtualisation.vlans = [ 1 ];
|
|
};
|
|
|
|
dynamic2 = { ... } @ args:
|
|
makeTincNode args "dynamic2" {
|
|
virtualisation.vlans = [ 2 ];
|
|
};
|
|
|
|
};
|
|
|
|
testScript = ''
|
|
start_all()
|
|
|
|
static.wait_for_unit("tinc.myNetwork.service")
|
|
dynamic1.wait_for_unit("tinc.myNetwork.service")
|
|
dynamic2.wait_for_unit("tinc.myNetwork.service")
|
|
|
|
# Static is accessible by the other hosts
|
|
dynamic1.succeed("ping -c5 192.168.1.11")
|
|
dynamic2.succeed("ping -c5 192.168.2.11")
|
|
|
|
# The other hosts are in separate vlans
|
|
dynamic1.fail("ping -c5 192.168.2.11")
|
|
dynamic2.fail("ping -c5 192.168.1.11")
|
|
|
|
# Each host can ping themselves through Tinc
|
|
static.succeed("ping -c5 10.0.0.11")
|
|
dynamic1.succeed("ping -c5 10.0.0.21")
|
|
dynamic2.succeed("ping -c5 10.0.0.22")
|
|
|
|
# Static is accessible by the other hosts through Tinc
|
|
dynamic1.succeed("ping -c5 10.0.0.11")
|
|
dynamic2.succeed("ping -c5 10.0.0.11")
|
|
|
|
# Static can access the other hosts through Tinc
|
|
static.succeed("ping -c5 10.0.0.21")
|
|
static.succeed("ping -c5 10.0.0.22")
|
|
|
|
# The other hosts in separate vlans can access each other through Tinc
|
|
dynamic1.succeed("ping -c5 10.0.0.22")
|
|
dynamic2.succeed("ping -c5 10.0.0.21")
|
|
'';
|
|
})
|