2019-08-17 22:34:43 +02:00
|
|
|
/* TODO: Translate this to a service/module at some point? Something like 'cryto.network' that handles all the internal-networking stuff. */
|
|
|
|
|
|
|
|
{ hostname, nodes, pingInterval ? 10 }:
|
2020-05-31 02:17:16 +02:00
|
|
|
{ pkgs, lib, ... }: let
|
2019-08-17 22:34:43 +02:00
|
|
|
/* NOTE: We cannot just use simple string interpolation, because tinc's configuration format is not indentation-tolerant. Therefore, we do some programmatic concatenation magic to ensure that everything is indentation-free, without turning this file into a mess of wrong indentation. */
|
|
|
|
generateConfiguration = options:
|
|
|
|
let
|
|
|
|
keys = builtins.attrNames options;
|
|
|
|
toPairs = map (key: {key = key; value = options.${key};});
|
|
|
|
createConfigEntries = map (item: "${item.key} = ${toString item.value}");
|
|
|
|
in
|
|
|
|
builtins.concatStringsSep "\n" (createConfigEntries (toPairs keys));
|
|
|
|
in {
|
|
|
|
deployment.secrets = {
|
|
|
|
"tinc-key" = {
|
|
|
|
source = "../private/${hostname}/tinc-key.priv";
|
|
|
|
destination = "/etc/tinc/cryto/ed25519_key.priv";
|
|
|
|
owner = { user = "tinc.cryto"; };
|
|
|
|
action = [ "systemctl" "restart" "tinc.cryto.service" ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
services.tinc.networks.cryto = {
|
|
|
|
debugLevel = 3;
|
2020-05-31 02:17:16 +02:00
|
|
|
chroot = false;
|
2020-06-01 01:50:04 +02:00
|
|
|
ed25519PrivateKeyFile = "/etc/tinc/cryto/ed25519_key.priv";
|
2019-08-17 22:34:43 +02:00
|
|
|
|
|
|
|
extraConfig = generateConfiguration {
|
|
|
|
AutoConnect = "yes";
|
|
|
|
PingInterval = pingInterval;
|
|
|
|
};
|
|
|
|
|
|
|
|
hosts = let
|
2022-02-27 12:19:01 +01:00
|
|
|
escapeHostname = hostname: builtins.replaceStrings [ "." "-" ] [ "_" "_" ] hostname;
|
|
|
|
stripSuffix = hostname: builtins.head (builtins.match "^(.+?)\.cryto\.net$" hostname);
|
|
|
|
makeMapper = keyMapper: (
|
|
|
|
nodeName: nodeConfiguration:
|
|
|
|
lib.nameValuePair
|
|
|
|
/* NOTE: The below is because for a machine named `foo.bar-baz.net`, tinc expects a configuration file named `foo_bar_baz_net`. */
|
|
|
|
# ( builtins.replaceStrings [ "." "-" ] [ "_" "_" ] nodeName )
|
|
|
|
( keyMapper nodeName )
|
|
|
|
( generateConfiguration {
|
|
|
|
# Address = nodeName;
|
|
|
|
/* TODO: Figure out why a DNS name doesn't work here ("Error looking up machine-borg2-01.cryto.net port 655: Device or resource busy") */
|
|
|
|
Address = nodeConfiguration.ipv4;
|
|
|
|
Subnet = "${nodeConfiguration.internalIpv4}/32";
|
|
|
|
Ed25519PublicKey = nodeConfiguration.tincPublicKey;
|
|
|
|
} )
|
|
|
|
);
|
|
|
|
# NOTE: We generate both hostname formats and then just use one, since this seems to keep changing... this makes it easier to revert later
|
|
|
|
mapperA = makeMapper ( nodeName: escapeHostname (stripSuffix nodeName) );
|
|
|
|
mapperB = makeMapper ( nodeName: escapeHostname nodeName );
|
|
|
|
hostsA = lib.mapAttrs' mapperA nodes;
|
|
|
|
# hostsB = lib.mapAttrs' mapperB nodes;
|
|
|
|
hostsB = {};
|
|
|
|
in hostsA // hostsB;
|
2019-08-17 22:34:43 +02:00
|
|
|
};
|
|
|
|
|
2020-05-31 02:17:16 +02:00
|
|
|
# networking.interfaces."tinc.cryto".ipv4.addresses = [{
|
|
|
|
# address = nodes.${hostname}.internalIpv4;
|
|
|
|
# prefixLength = 24;
|
|
|
|
# }];
|
2019-08-17 22:34:43 +02:00
|
|
|
|
|
|
|
networking.firewall = {
|
|
|
|
allowedTCPPorts = [
|
|
|
|
655
|
|
|
|
];
|
|
|
|
allowedUDPPorts = [
|
|
|
|
655
|
|
|
|
];
|
|
|
|
trustedInterfaces = [
|
|
|
|
"tinc.cryto"
|
|
|
|
];
|
|
|
|
};
|
2020-05-31 02:17:16 +02:00
|
|
|
|
|
|
|
# FIXME: Make the netmask be generated from the prefixLength, instead of hard-coding it
|
|
|
|
environment.etc = {
|
|
|
|
"tinc/cryto/tinc-up".source = pkgs.writeScript "tinc-up-cryto" ''
|
|
|
|
#!${pkgs.stdenv.shell}
|
|
|
|
${pkgs.nettools}/bin/ifconfig tinc.cryto ${nodes.${hostname}.internalIpv4} netmask 255.255.255.0
|
|
|
|
'';
|
|
|
|
"tinc/cryto/tinc-down".source = pkgs.writeScript "tinc-down-cryto" ''
|
|
|
|
#!${pkgs.stdenv.shell}
|
|
|
|
/run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig tinc.cryto down
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
security.sudo.extraRules = [{
|
|
|
|
users = [ "tinc.cryto" ];
|
|
|
|
commands = [{
|
|
|
|
command = "${pkgs.nettools}/bin/ifconfig tinc.cryto down";
|
|
|
|
options = [ "NOPASSWD" ];
|
|
|
|
}];
|
|
|
|
}];
|
2020-06-01 01:50:04 +02:00
|
|
|
|
|
|
|
# Override this to get rid of the automatic key generation
|
|
|
|
systemd.services."tinc.cryto".preStart = lib.mkForce ''
|
|
|
|
mkdir -p /etc/tinc/cryto/hosts
|
|
|
|
chown tinc.cryto /etc/tinc/cryto/hosts
|
|
|
|
mkdir -p /etc/tinc/cryto/invitations
|
|
|
|
chown tinc.cryto /etc/tinc/cryto/invitations
|
|
|
|
'';
|
2019-08-17 22:34:43 +02:00
|
|
|
}
|