at 25.11-pre 3.2 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 inherit (lib) types; 9 cfg = config.services.croc; 10 rootDir = "/run/croc"; 11in 12{ 13 options.services.croc = { 14 enable = lib.mkEnableOption "croc relay"; 15 ports = lib.mkOption { 16 type = with types; listOf port; 17 default = [ 18 9009 19 9010 20 9011 21 9012 22 9013 23 ]; 24 description = "Ports of the relay."; 25 }; 26 pass = lib.mkOption { 27 type = with types; either path str; 28 default = "pass123"; 29 description = "Password or passwordfile for the relay."; 30 }; 31 openFirewall = lib.mkEnableOption "opening of the peer port(s) in the firewall"; 32 debug = lib.mkEnableOption "debug logs"; 33 }; 34 35 config = lib.mkIf cfg.enable { 36 systemd.services.croc = { 37 after = [ "network.target" ]; 38 wantedBy = [ "multi-user.target" ]; 39 serviceConfig = { 40 ExecStart = "${pkgs.croc}/bin/croc --pass '${cfg.pass}' ${lib.optionalString cfg.debug "--debug"} relay --ports ${ 41 lib.concatMapStringsSep "," toString cfg.ports 42 }"; 43 # The following options are only for optimizing: 44 # systemd-analyze security croc 45 AmbientCapabilities = ""; 46 CapabilityBoundingSet = ""; 47 DynamicUser = true; 48 # ProtectClock= adds DeviceAllow=char-rtc r 49 DeviceAllow = ""; 50 LockPersonality = true; 51 MemoryDenyWriteExecute = true; 52 MountAPIVFS = true; 53 NoNewPrivileges = true; 54 PrivateDevices = true; 55 PrivateMounts = true; 56 PrivateNetwork = lib.mkDefault false; 57 PrivateTmp = true; 58 PrivateUsers = true; 59 ProcSubset = "pid"; 60 ProtectClock = true; 61 ProtectControlGroups = true; 62 ProtectHome = true; 63 ProtectHostname = true; 64 ProtectKernelLogs = true; 65 ProtectKernelModules = true; 66 ProtectKernelTunables = true; 67 ProtectProc = "invisible"; 68 ProtectSystem = "strict"; 69 RemoveIPC = true; 70 RestrictAddressFamilies = [ 71 "AF_INET" 72 "AF_INET6" 73 ]; 74 RestrictNamespaces = true; 75 RestrictRealtime = true; 76 RestrictSUIDSGID = true; 77 RootDirectory = rootDir; 78 # Avoid mounting rootDir in the own rootDir of ExecStart='s mount namespace. 79 InaccessiblePaths = [ "-+${rootDir}" ]; 80 BindReadOnlyPaths = [ 81 builtins.storeDir 82 ] ++ lib.optional (types.path.check cfg.pass) cfg.pass; 83 # This is for BindReadOnlyPaths= 84 # to allow traversal of directories they create in RootDirectory=. 85 UMask = "0066"; 86 # Create rootDir in the host's mount namespace. 87 RuntimeDirectory = [ (baseNameOf rootDir) ]; 88 RuntimeDirectoryMode = "700"; 89 SystemCallFilter = [ 90 "@system-service" 91 "~@aio" 92 "~@keyring" 93 "~@memlock" 94 "~@privileged" 95 "~@setuid" 96 "~@sync" 97 "~@timer" 98 ]; 99 SystemCallArchitectures = "native"; 100 SystemCallErrorNumber = "EPERM"; 101 }; 102 }; 103 104 networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall cfg.ports; 105 }; 106 107 meta.maintainers = with lib.maintainers; [ 108 hax404 109 julm 110 ]; 111}