lol

nixos/cryptpad: harden service

cryptpad is not directly exposed to the network, but has plenty that can
be hardened more properly, so fix that.

+89 -8
+86 -8
nixos/modules/services/web-apps/cryptpad.nix
··· 141 141 # apparently needs proc for workers management 142 142 "/proc" 143 143 "/dev/urandom" 144 - ] ++ (if ! cfg.settings.blockDailyCheck then [ 145 - # allow DNS & TLS if telemetry is explicitly enabled 146 - "-/etc/resolv.conf" 147 - "-/run/systemd" 148 - "/etc/hosts" 149 - "/etc/ssl/certs/ca-certificates.crt" 150 - ] else []); 144 + ]; 151 145 DynamicUser = true; 152 146 Environment = [ 153 147 "CRYPTPAD_CONFIG=${cryptpadConfigFile}" 154 148 "HOME=%S/cryptpad" 155 149 ]; 156 150 ExecStart = lib.getExe cfg.package; 157 - PrivateTmp = true; 158 151 Restart = "always"; 159 152 StateDirectory = "cryptpad"; 160 153 WorkingDirectory = "%S/cryptpad"; 154 + # security way too many numerous options, from the systemd-analyze security output 155 + # at end of test: block everything except 156 + # - SystemCallFiters=@resources is required for node 157 + # - MemoryDenyWriteExecute for node JIT 158 + # - RestrictAddressFamilies=~AF_(INET|INET6) / PrivateNetwork to bind to sockets 159 + # - IPAddressDeny likewise allow localhost if binding to localhost or any otherwise 160 + # - PrivateUsers somehow service doesn't start with that 161 + # - DeviceAllow (char-rtc r added by ProtectClock) 162 + AmbientCapabilities = ""; 163 + CapabilityBoundingSet = ""; 164 + DeviceAllow = ""; 165 + LockPersonality = true; 166 + NoNewPrivileges = true; 167 + PrivateDevices = true; 168 + PrivateTmp = true; 169 + ProcSubset = "pid"; 170 + ProtectClock = true; 171 + ProtectControlGroups = true; 172 + ProtectHome = true; 173 + ProtectHostname = true; 174 + ProtectKernelLogs = true; 175 + ProtectKernelModules = true; 176 + ProtectKernelTunables = true; 177 + ProtectProc = "invisible"; 178 + ProtectSystem = "strict"; 179 + RemoveIPC = true; 180 + RestrictAddressFamilies = [ 181 + "AF_INET" 182 + "AF_INET6" 183 + ]; 184 + RestrictNamespaces = true; 185 + RestrictRealtime = true; 186 + RestrictSUIDSGID = true; 187 + RuntimeDirectoryMode = "700"; 188 + SocketBindAllow = [ 189 + "tcp:${builtins.toString cfg.settings.httpPort}" 190 + "tcp:${builtins.toString cfg.settings.websocketPort}" 191 + ]; 192 + SocketBindDeny = [ "any" ]; 193 + StateDirectoryMode = "0700"; 194 + SystemCallArchitectures = "native"; 195 + SystemCallFilter = [ 196 + "@pkey" 197 + "@system-service" 198 + "~@chown" 199 + "~@keyring" 200 + "~@memlock" 201 + "~@privileged" 202 + "~@resources" 203 + "~@setuid" 204 + "~@timer" 205 + ]; 206 + UMask = "0077"; 161 207 }; 162 208 confinement = { 163 209 enable = true; ··· 166 212 }; 167 213 }; 168 214 } 215 + # block external network access if not phoning home and 216 + # binding to localhost (default) 217 + (mkIf 218 + ( 219 + cfg.settings.blockDailyCheck 220 + && (builtins.elem cfg.settings.httpAddress [ 221 + "127.0.0.1" 222 + "::1" 223 + ]) 224 + ) 225 + { 226 + systemd.services.cryptpad = { 227 + serviceConfig = { 228 + IPAddressAllow = [ "localhost" ]; 229 + IPAddressDeny = [ "any" ]; 230 + }; 231 + }; 232 + } 233 + ) 234 + # .. conversely allow DNS & TLS if telemetry is explicitly enabled 235 + (mkIf (!cfg.settings.blockDailyCheck) { 236 + systemd.services.cryptpad = { 237 + serviceConfig = { 238 + BindReadOnlyPaths = [ 239 + "-/etc/resolv.conf" 240 + "-/run/systemd" 241 + "/etc/hosts" 242 + "/etc/ssl/certs/ca-certificates.crt" 243 + ]; 244 + }; 245 + }; 246 + }) 169 247 170 248 (mkIf cfg.configureNginx { 171 249 assertions = [
+3
nixos/tests/cryptpad.nix
··· 64 64 65 65 # test telemetry has been disabled 66 66 machine.fail("journalctl -u cryptpad | grep TELEMETRY"); 67 + 68 + # for future improvements 69 + machine.log(machine.execute("systemd-analyze security cryptpad.service")[1]) 67 70 ''; 68 71 }