diff --git a/configuration/data/nodes.nix b/configuration/data/nodes.nix new file mode 100644 index 0000000..fa5f877 --- /dev/null +++ b/configuration/data/nodes.nix @@ -0,0 +1,12 @@ +{ + "machine-haless-03.cryto.net" = { + ipv4 = "31.7.187.145"; + internalIpv4 = "10.217.0.5"; + tincPublicKey = builtins.readFile ./tinc-keys/machine-haless-03.cryto.net.pub; + }; + "machine-borg2-01.cryto.net" = { + ipv4 = "205.185.121.93"; + internalIpv4 = "10.217.0.6"; + tincPublicKey = builtins.readFile ./tinc-keys/machine-borg2-01.cryto.net.pub; + }; +} diff --git a/configuration/data/tinc-keys/machine-borg2-01.cryto.net.pub b/configuration/data/tinc-keys/machine-borg2-01.cryto.net.pub new file mode 100644 index 0000000..12d9f6a --- /dev/null +++ b/configuration/data/tinc-keys/machine-borg2-01.cryto.net.pub @@ -0,0 +1 @@ +FZNH5Z50Tr/Ep0VpbnIBasUxekLteUphr5Vzi6ONrNH diff --git a/configuration/data/tinc-keys/machine-haless-03.cryto.net.pub b/configuration/data/tinc-keys/machine-haless-03.cryto.net.pub new file mode 100644 index 0000000..6bde251 --- /dev/null +++ b/configuration/data/tinc-keys/machine-haless-03.cryto.net.pub @@ -0,0 +1 @@ +P4MOft3fYOHYpG0I58lYxdZm40u9CXhTH0jvuyIbKZP diff --git a/configuration/default.nix b/configuration/default.nix index 7dd5903..542ef5c 100644 --- a/configuration/default.nix +++ b/configuration/default.nix @@ -24,6 +24,8 @@ let reverseProxy = (import ./presets/nginx/reverse-proxy.nix); letsEncrypt = (import ./presets/nginx/lets-encrypt.nix); }; + nodes = (import ./data/nodes.nix); + tincConfiguration = (import ./lib/tinc-configuration.nix); in { network = { inherit pkgs; @@ -33,10 +35,14 @@ in { "machine-borg2-01.cryto.net" = { pkgs, lib, ... }: { system.stateVersion = "18.09"; + # FIXME: Why is this needed? + nixpkgs.overlays = []; + imports = [ presets.base presets.kvm ./hardware-configurations/machine-borg2-01.nix + (tincConfiguration { hostname = "machine-borg2-01.cryto.net"; nodes = nodes; }) ]; boot.loader.grub.device = lib.mkForce "/dev/vda"; @@ -77,6 +83,7 @@ in { presets.base presets.kvm ./hardware-configurations/machine-haless-03.nix + (tincConfiguration { hostname = "machine-haless-03.cryto.net"; nodes = nodes; }) ]; deployment.healthChecks.http = let diff --git a/configuration/lib/tinc-configuration.nix b/configuration/lib/tinc-configuration.nix new file mode 100644 index 0000000..a513f01 --- /dev/null +++ b/configuration/lib/tinc-configuration.nix @@ -0,0 +1,62 @@ +/* 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 }: + { lib, ... }: let + /* 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; + + extraConfig = generateConfiguration { + AutoConnect = "yes"; + PingInterval = pingInterval; + }; + + hosts = let + mapper = 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 ) + ( 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; + } ); + in lib.mapAttrs' mapper nodes; + }; + + networking.interfaces."tinc.cryto".ipv4.addresses = [{ + address = nodes.${hostname}.internalIpv4; + prefixLength = 24; + }]; + + networking.firewall = { + allowedTCPPorts = [ + 655 + ]; + allowedUDPPorts = [ + 655 + ]; + trustedInterfaces = [ + "tinc.cryto" + ]; + }; + } diff --git a/deploy-secrets b/deploy-secrets new file mode 100755 index 0000000..fae1e91 --- /dev/null +++ b/deploy-secrets @@ -0,0 +1 @@ +SSH_USER=root morph --keep-result upload-secrets "$@" configuration/default.nix diff --git a/notes/tinc-key-setup.txt b/notes/tinc-key-setup.txt new file mode 100644 index 0000000..f448a68 --- /dev/null +++ b/notes/tinc-key-setup.txt @@ -0,0 +1,5 @@ +# From the machine's `private` folder: +nix-shell --command 'tinc --batch --config ./ -n cryto generate-ed25519-keys' --packages tinc_pre + +# NOTE: Change the machine name! +mv ed25519_key.priv tinc-key.priv && sed -i -r 's/^Ed25519PublicKey = //' ed25519_key.pub && mv ed25519_key.pub ../../configuration/data/tinc-keys/machine-haless-03.cryto.net.pub