at master 4.7 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.newt; 9 type = 10 with lib.types; 11 attrsOf ( 12 nullOr (oneOf [ 13 bool 14 int 15 float 16 str 17 path 18 (listOf type) 19 ]) 20 ) 21 // { 22 description = "value coercible to CLI argument"; 23 }; 24in 25{ 26 imports = [ 27 (lib.mkRenamedOptionModule [ "services" "newt" "id" ] [ "services" "newt" "settings" "id" ]) 28 (lib.mkRenamedOptionModule 29 [ "services" "newt" "logLevel" ] 30 [ "services" "newt" "settings" "log-level" ] 31 ) 32 (lib.mkRenamedOptionModule 33 [ "services" "newt" "endpoint" ] 34 [ "services" "newt" "settings" "endpoint" ] 35 ) 36 ]; 37 38 options = { 39 services.newt = { 40 enable = lib.mkEnableOption "Newt, user space tunnel client for Pangolin"; 41 package = lib.mkPackageOption pkgs "fosrl-newt" { }; 42 settings = lib.mkOption { 43 inherit type; 44 default = { }; 45 example = { 46 endpoint = "pangolin.example.com"; 47 id = "8yfsghj438a20ol"; 48 }; 49 description = "Settings for Newt module, see [Newt CLI docs](https://github.com/fosrl/newt?tab=readme-ov-file#cli-args) for more information."; 50 }; 51 52 # provide path to file to keep secrets out of the nix store 53 environmentFile = lib.mkOption { 54 type = with lib.types; nullOr path; 55 default = null; 56 description = '' 57 Path to a file containing sensitive environment variables for Newt. See <https://docs.fossorial.io/Newt/overview#cli-args> 58 These will overwrite anything defined in the config. 59 The file should contain environment-variable assignments like: 60 NEWT_ID=2ix2t8xk22ubpfy 61 NEWT_SECRET=nnisrfsdfc7prqsp9ewo1dvtvci50j5uiqotez00dgap0ii2 62 ''; 63 }; 64 }; 65 }; 66 67 config = lib.mkIf cfg.enable { 68 69 assertions = [ 70 { 71 assertion = cfg.environmentFile != null; 72 message = "services.newt.environmentFile must be provided when Newt is enabled."; 73 } 74 ]; 75 76 systemd.services.newt = { 77 description = "Newt, user space tunnel client for Pangolin"; 78 wantedBy = [ "multi-user.target" ]; 79 after = [ "network.target" ]; 80 81 environment = { 82 HOME = "/var/lib/private/newt"; 83 }; 84 # the flag values will all be overwritten if also defined in the env file 85 serviceConfig = { 86 ExecStart = "${lib.getExe cfg.package} ${lib.cli.toGNUCommandLineShell { } cfg.settings}"; 87 DynamicUser = true; 88 StateDirectory = "newt"; 89 StateDirectoryMode = "0700"; 90 Restart = "always"; 91 RestartSec = "10s"; 92 EnvironmentFile = cfg.environmentFile; 93 # hardening 94 ProtectSystem = "strict"; 95 ProtectHome = true; 96 PrivateTmp = "disconnected"; 97 PrivateDevices = true; 98 PrivateUsers = true; 99 PrivateMounts = true; 100 ProtectKernelTunables = true; 101 ProtectKernelModules = true; 102 ProtectKernelLogs = true; 103 ProtectControlGroups = true; 104 LockPersonality = true; 105 RestrictRealtime = true; 106 ProtectClock = true; 107 ProtectProc = "noaccess"; 108 ProtectHostname = true; 109 RemoveIPC = true; 110 NoNewPrivileges = true; 111 RestrictSUIDSGID = true; 112 MemoryDenyWriteExecute = true; 113 SystemCallArchitectures = "native"; 114 UMask = "0077"; 115 RestrictAddressFamilies = [ 116 "AF_INET" 117 "AF_INET6" 118 "AF_NETLINK" 119 "AF_UNIX" 120 ]; 121 CapabilityBoundingSet = [ 122 "~CAP_BLOCK_SUSPEND" 123 "~CAP_BPF" 124 "~CAP_CHOWN" 125 "~CAP_MKNOD" 126 "~CAP_NET_RAW" 127 "~CAP_PERFMON" 128 "~CAP_SYS_BOOT" 129 "~CAP_SYS_CHROOT" 130 "~CAP_SYS_MODULE" 131 "~CAP_SYS_NICE" 132 "~CAP_SYS_PACCT" 133 "~CAP_SYS_PTRACE" 134 "~CAP_SYS_TIME" 135 "~CAP_SYS_TTY_CONFIG" 136 "~CAP_SYSLOG" 137 "~CAP_WAKE_ALARM" 138 ]; 139 SystemCallFilter = [ 140 "~@aio:EPERM" 141 "~@chown:EPERM" 142 "~@clock:EPERM" 143 "~@cpu-emulation:EPERM" 144 "~@debug:EPERM" 145 "~@keyring:EPERM" 146 "~@memlock:EPERM" 147 "~@module:EPERM" 148 "~@mount:EPERM" 149 "~@obsolete:EPERM" 150 "~@pkey:EPERM" 151 "~@privileged:EPERM" 152 "~@raw-io:EPERM" 153 "~@reboot:EPERM" 154 "~@resources:EPERM" 155 "~@sandbox:EPERM" 156 "~@setuid:EPERM" 157 "~@swap:EPERM" 158 "~@sync:EPERM" 159 "~@timer:EPERM" 160 ]; 161 }; 162 }; 163 }; 164 165 meta.maintainers = with lib.maintainers; [ jackr ]; 166}