1 { config, lib, pkgs, ... }:
4 cfg = config.services.croc;
8 options.services.croc = {
9 enable = lib.mkEnableOption (lib.mdDoc "croc relay");
10 ports = lib.mkOption {
11 type = with types; listOf port;
12 default = [9009 9010 9011 9012 9013];
13 description = lib.mdDoc "Ports of the relay.";
16 type = with types; either path str;
18 description = lib.mdDoc "Password or passwordfile for the relay.";
20 openFirewall = lib.mkEnableOption (lib.mdDoc "opening of the peer port(s) in the firewall");
21 debug = lib.mkEnableOption (lib.mdDoc "debug logs");
24 config = lib.mkIf cfg.enable {
25 systemd.services.croc = {
26 after = [ "network.target" ];
27 wantedBy = [ "multi-user.target" ];
29 ExecStart = "${pkgs.croc}/bin/croc --pass '${cfg.pass}' ${lib.optionalString cfg.debug "--debug"} relay --ports ${lib.concatMapStringsSep "," toString cfg.ports}";
30 # The following options are only for optimizing:
31 # systemd-analyze security croc
32 AmbientCapabilities = "";
33 CapabilityBoundingSet = "";
35 # ProtectClock= adds DeviceAllow=char-rtc r
37 LockPersonality = true;
38 MemoryDenyWriteExecute = true;
40 NoNewPrivileges = true;
41 PrivateDevices = true;
43 PrivateNetwork = lib.mkDefault false;
48 ProtectControlGroups = true;
50 ProtectHostname = true;
51 ProtectKernelLogs = true;
52 ProtectKernelModules = true;
53 ProtectKernelTunables = true;
54 ProtectProc = "invisible";
55 ProtectSystem = "strict";
57 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
58 RestrictNamespaces = true;
59 RestrictRealtime = true;
60 RestrictSUIDSGID = true;
61 RootDirectory = rootDir;
62 # Avoid mounting rootDir in the own rootDir of ExecStart='s mount namespace.
63 InaccessiblePaths = [ "-+${rootDir}" ];
66 ] ++ lib.optional (types.path.check cfg.pass) cfg.pass;
67 # This is for BindReadOnlyPaths=
68 # to allow traversal of directories they create in RootDirectory=.
70 # Create rootDir in the host's mount namespace.
71 RuntimeDirectory = [(baseNameOf rootDir)];
72 RuntimeDirectoryMode = "700";
75 "~@aio" "~@keyring" "~@memlock" "~@privileged" "~@setuid" "~@sync" "~@timer"
77 SystemCallArchitectures = "native";
78 SystemCallErrorNumber = "EPERM";
82 networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall cfg.ports;
85 meta.maintainers = with lib.maintainers; [ hax404 julm ];