2021-10-28 20:10:47 +00:00
|
|
|
{ config, pkgs, lib, ... }:
|
2021-10-28 20:07:49 +00:00
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
hosts = import ./hosts;
|
|
|
|
|
|
|
|
cfg = config.services.my-tinc;
|
|
|
|
|
|
|
|
hostNames = builtins.attrNames hosts;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
imports = [ ./hosts.nix ];
|
2022-05-31 16:45:33 +00:00
|
|
|
|
2021-10-28 20:07:49 +00:00
|
|
|
options.services.my-tinc = {
|
|
|
|
enable = mkEnableOption "my private tinc cloud configuration";
|
|
|
|
rsaPrivateKey = mkOption {
|
|
|
|
type = types.nullOr types.path;
|
|
|
|
default = null;
|
|
|
|
example = "./my-key.priv";
|
|
|
|
description = "The key file to be used as the private key";
|
|
|
|
};
|
|
|
|
ed25519PrivateKey = mkOption {
|
|
|
|
type = types.nullOr types.path;
|
|
|
|
default = null;
|
|
|
|
example = "./my-key-ed25519.priv";
|
|
|
|
description = "The key file to be used as the private key";
|
|
|
|
};
|
|
|
|
hostName = mkOption {
|
|
|
|
type = types.enum hostNames;
|
|
|
|
description = "The configured host name";
|
|
|
|
};
|
2021-10-28 22:15:24 +00:00
|
|
|
bindPort = mkOption {
|
|
|
|
type = types.port;
|
|
|
|
default = 655;
|
|
|
|
description = "The port to listen on";
|
|
|
|
};
|
2021-10-28 20:07:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable (builtins.seq
|
|
|
|
(mkIf (isNull cfg.rsaPrivateKey && isNull cfg.ed25519PrivateKey) (builtins.abort "one of the keys must be defined"))
|
2022-05-31 16:45:33 +00:00
|
|
|
(
|
|
|
|
let
|
|
|
|
networkName = "my-tinc";
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
myHost = builtins.getAttr cfg.hostName hosts;
|
|
|
|
myMeshIp = myHost.subnetAddr;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
# Scripts that set up the tinc services
|
|
|
|
environment.etc = {
|
|
|
|
"tinc/${networkName}/tinc-up".source = pkgs.writeScript "tinc-up-${networkName}" ''
|
2021-10-28 20:07:49 +00:00
|
|
|
#!${pkgs.stdenv.shell}
|
|
|
|
${pkgs.nettools}/bin/ifconfig $INTERFACE ${myMeshIp} netmask 255.255.255.0
|
2022-05-31 16:45:33 +00:00
|
|
|
'';
|
|
|
|
"tinc/${networkName}/tinc-down".source = pkgs.writeScript "tinc-down-${networkName}" ''
|
2021-10-28 20:07:49 +00:00
|
|
|
#!${pkgs.stdenv.shell}
|
|
|
|
/run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
|
2022-05-31 16:45:33 +00:00
|
|
|
'';
|
|
|
|
};
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
# Allow the tinc service to call ifconfig without sudo password.
|
|
|
|
security.sudo.extraRules = [
|
|
|
|
{
|
|
|
|
users = [ "tinc.${networkName}" ];
|
|
|
|
commands = [
|
|
|
|
{
|
|
|
|
command = "${pkgs.nettools}/bin/ifconfig";
|
|
|
|
options = [ "NOPASSWD" ];
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}
|
|
|
|
];
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
# simple interface setup
|
|
|
|
# ----------------------
|
|
|
|
networking.interfaces."tinc.${networkName}".ipv4.addresses = [{ address = myMeshIp; prefixLength = 24; }];
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
# firewall
|
|
|
|
networking.firewall.allowedUDPPorts = [ 655 ];
|
|
|
|
networking.firewall.allowedTCPPorts = [ 655 ];
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
# configure tinc service
|
|
|
|
# ----------------------
|
|
|
|
services.tinc.networks."${networkName}" = {
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
name = cfg.hostName; # who are we in this network.
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
debugLevel = 3; # the debug level for journal -u tinc.private
|
|
|
|
chroot = false; # otherwise addresses can't be a DNS
|
|
|
|
interfaceType = "tap"; # tun might also work.
|
2021-10-28 20:07:49 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
bindToAddress = "* ${toString cfg.bindPort}";
|
2021-10-28 22:15:24 +00:00
|
|
|
|
2022-05-31 16:45:33 +00:00
|
|
|
ed25519PrivateKeyFile = cfg.ed25519PrivateKey;
|
|
|
|
rsaPrivateKeyFile = cfg.rsaPrivateKey;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
)
|
2021-10-28 20:07:49 +00:00
|
|
|
);
|
|
|
|
}
|