at master 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 ] 83 ++ lib.optional (types.path.check cfg.pass) cfg.pass; 84 # This is for BindReadOnlyPaths= 85 # to allow traversal of directories they create in RootDirectory=. 86 UMask = "0066"; 87 # Create rootDir in the host's mount namespace. 88 RuntimeDirectory = [ (baseNameOf rootDir) ]; 89 RuntimeDirectoryMode = "700"; 90 SystemCallFilter = [ 91 "@system-service" 92 "~@aio" 93 "~@keyring" 94 "~@memlock" 95 "~@privileged" 96 "~@setuid" 97 "~@sync" 98 "~@timer" 99 ]; 100 SystemCallArchitectures = "native"; 101 SystemCallErrorNumber = "EPERM"; 102 }; 103 }; 104 105 networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall cfg.ports; 106 }; 107 108 meta.maintainers = with lib.maintainers; [ 109 hax404 110 julm 111 ]; 112}