From 9ddb6c9cc9231cf85c5cdaba3964be2ad63cbcd7 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Sat, 23 Aug 2014 17:33:31 -0700 Subject: [PATCH] nixos/tinc: Add daemon configuration --- nixos/modules/module-list.nix | 1 + nixos/modules/services/networking/tinc.nix | 154 +++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 nixos/modules/services/networking/tinc.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ded94d9ea830..dc97e7203ba0 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -293,6 +293,7 @@ ./services/networking/syncthing.nix ./services/networking/tcpcrypt.nix ./services/networking/teamspeak3.nix + ./services/networking/tinc.nix ./services/networking/tftpd.nix ./services/networking/tlsdated.nix ./services/networking/tox-bootstrapd.nix diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix new file mode 100644 index 000000000000..16cf1f68fcaa --- /dev/null +++ b/nixos/modules/services/networking/tinc.nix @@ -0,0 +1,154 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.tinc; + +in + +{ + + ###### interface + + options = { + + services.tinc = { + + networks = mkOption { + default = { }; + type = types.loaOf types.optionSet; + description = '' + Defines the tinc networks which will be started. + Each network invokes a different daemon. + ''; + options = { + + extraConfig = mkOption { + default = ""; + type = types.lines; + description = '' + Extra lines to add to the tinc service configuration file. + ''; + }; + + name = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The name of the node which is used as an identifier when communicating + with the remote nodes in the mesh. If null then the hostname of the system + is used. + ''; + }; + + debugLevel = mkOption { + default = 0; + type = types.addCheck types.int (l: l >= 0 && l <= 5); + description = '' + The amount of debugging information to add to the log. 0 means little + logging while 5 is the most logging. man tincd for + more details. + ''; + }; + + hosts = mkOption { + default = { }; + type = types.loaOf types.lines; + description = '' + The name of the host in the network as well as the configuration for that host. + This name should only contain alphanumerics and underscores. + ''; + }; + + interfaceType = mkOption { + default = "tun"; + type = types.addCheck types.str (n: n == "tun" || n == "tap"); + description = '' + The type of virtual interface used for the network connection + ''; + }; + + package = mkOption { + default = pkgs.tinc; + description = '' + The package to use for the tinc daemon's binary. + ''; + }; + + }; + }; + }; + + }; + + + ###### implementation + + config = mkIf (cfg.networks != { }) { + + environment.etc = fold (a: b: a // b) { } + (flip mapAttrsToList cfg.networks (network: data: + flip mapAttrs' data.hosts (host: text: nameValuePair + ("tinc/${network}/hosts/${host}") + ({ mode = "0444"; inherit text; }) + ) // { + "tinc/${network}/tinc.conf" = { + mode = "0444"; + text = '' + Name = ${if data.name == null then "$HOST" else data.name} + DeviceType = ${data.interfaceType} + Device = /dev/net/tun + Interface = tinc.${network} + ${data.extraConfig} + ''; + }; + } + )); + + networking.interfaces = flip mapAttrs' cfg.networks (network: data: nameValuePair + ("tinc.${network}") + ({ + virtual = true; + virtualType = "${data.interfaceType}"; + }) + ); + + systemd.services = flip mapAttrs' cfg.networks (network: data: nameValuePair + ("tinc.${network}") + ({ + description = "Tinc Daemon - ${network}"; + wantedBy = [ "network.target" ]; + after = [ "network-interfaces.target" ]; + path = [ data.package ]; + restartTriggers = [ config.environment.etc."tinc/${network}/tinc.conf".source ] + ++ mapAttrsToList (host: _ : config.environment.etc."tinc/${network}/hosts/${host}".source) data.hosts; + serviceConfig = { + Type = "simple"; + PIDFile = "/run/tinc.${network}.pid"; + }; + preStart = '' + mkdir -p /etc/tinc/${network}/hosts + + # Prefer ED25519 keys (only in 1.1+) + [ -f "/etc/tinc/${network}/ed25519_key.priv" ] || tinc -n ${network} generate-ed25519-keys + + # Otherwise use RSA keys + [ -f "/etc/tinc/${network}/rsa_key.priv" ] || tinc -n ${network} generate-rsa-keys 4096 + ''; + script = '' + ${data.package}/sbin/tincd -D -U tinc.${network} -n ${network} --pidfile /run/tinc.${network}.pid -d ${toString data.debugLevel} + ''; + }) + ); + + users.extraUsers = flip mapAttrs' cfg.networks (network: _: + nameValuePair ("tinc.${network}") ({ + description = "Tinc daemon user for ${network}"; + }) + ); + + }; + +}