at master 3.4 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10let 11 cfg = config.services.zerotierone; 12 13 settingsFormat = pkgs.formats.json { }; 14 localConfFile = settingsFormat.generate "zt-local.conf" cfg.localConf; 15 localConfFilePath = "/var/lib/zerotier-one/local.conf"; 16in 17{ 18 options.services.zerotierone.enable = mkEnableOption "ZeroTierOne"; 19 20 options.services.zerotierone.joinNetworks = mkOption { 21 default = [ ]; 22 example = [ "a8a2c3c10c1a68de" ]; 23 type = types.listOf types.str; 24 description = '' 25 List of ZeroTier Network IDs to join on startup. 26 Note that networks are only ever joined, but not automatically left after removing them from the list. 27 To remove networks, use the ZeroTier CLI: `zerotier-cli leave <network-id>` 28 ''; 29 }; 30 31 options.services.zerotierone.port = mkOption { 32 default = 9993; 33 type = types.port; 34 description = '' 35 Network port used by ZeroTier. 36 ''; 37 }; 38 39 options.services.zerotierone.package = mkPackageOption pkgs "zerotierone" { }; 40 41 options.services.zerotierone.localConf = mkOption { 42 default = { }; 43 description = '' 44 Optional configuration to be written to the Zerotier JSON-based local.conf. 45 If set, the configuration will be symlinked to `/var/lib/zerotier-one/local.conf` at build time. 46 To understand the configuration format, refer to <https://docs.zerotier.com/config/#local-configuration-options>. 47 ''; 48 example = { 49 settings.allowTcpFallbackRelay = false; 50 }; 51 type = settingsFormat.type; 52 }; 53 54 config = mkIf cfg.enable { 55 systemd.services.zerotierone = { 56 description = "ZeroTierOne"; 57 58 wantedBy = [ "multi-user.target" ]; 59 after = [ "network.target" ]; 60 wants = [ "network-online.target" ]; 61 62 path = [ cfg.package ]; 63 64 preStart = '' 65 mkdir -p /var/lib/zerotier-one/networks.d 66 chmod 700 /var/lib/zerotier-one 67 chown -R root:root /var/lib/zerotier-one 68 69 # cleans up old symlinks also if we unset localConf 70 if [[ -L "${localConfFilePath}" && "$(readlink "${localConfFilePath}")" =~ ^${builtins.storeDir}.* ]]; then 71 rm ${localConfFilePath} 72 fi 73 '' 74 + (concatMapStrings (netId: '' 75 touch "/var/lib/zerotier-one/networks.d/${netId}.conf" 76 '') cfg.joinNetworks) 77 + lib.optionalString (cfg.localConf != { }) '' 78 # in case the user has applied manual changes to the local.conf, we backup the file 79 if [ -f "${localConfFilePath}" ]; then 80 mv ${localConfFilePath} ${localConfFilePath}.bak 81 fi 82 ln -s ${localConfFile} ${localConfFilePath} 83 ''; 84 85 serviceConfig = { 86 ExecStart = "${cfg.package}/bin/zerotier-one -p${toString cfg.port}"; 87 Restart = "always"; 88 KillMode = "process"; 89 TimeoutStopSec = 5; 90 }; 91 }; 92 93 # ZeroTier does not issue DHCP leases, but some strangers might... 94 networking.dhcpcd.denyInterfaces = [ "zt*" ]; 95 96 # ZeroTier receives UDP transmissions 97 networking.firewall.allowedUDPPorts = [ cfg.port ]; 98 99 environment.systemPackages = [ cfg.package ]; 100 101 # Prevent systemd from potentially changing the MAC address 102 systemd.network.links."50-zerotier" = { 103 matchConfig = { 104 OriginalName = "zt*"; 105 }; 106 linkConfig = { 107 AutoNegotiation = false; 108 MACAddressPolicy = "none"; 109 }; 110 }; 111 }; 112}