From bc21bfc5066cfda9ba088c7ec55da167e8a96c6d Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Thu, 1 May 2025 06:07:09 +0300 Subject: [PATCH] nix: get nftables from correct parent attr nix: what do you mean `baseNameOf` is not in lib nix: `pkgs.system` -> `pkgs.hostPlatform.system` nix: include contrib in pacakge source nix: fix types --- nix/module.nix | 98 ++++++++++++++++++++++--------------------------- nix/package.nix | 5 ++- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index 50f6fb0..1aeb67d 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -5,6 +5,7 @@ self: { pkgs, ... }: let + inherit (builtins) toJSON toString; inherit (lib.modules) mkIf; inherit (lib.options) mkOption mkEnableOption literalExpression; inherit (lib.types) package str port int listOf enum bool attrsOf path; @@ -13,7 +14,7 @@ self: { cfg = config.services.eris; # Generate the config.json content - erisConfigFile = pkgs.writeText "eris-config.json" (builtins.toJSON { + erisConfigFile = pkgs.writeText "eris-config.json" (toJSON { listen_addr = cfg.listenAddress; metrics_port = cfg.metricsPort; backend_addr = cfg.backendAddress; @@ -37,8 +38,8 @@ in { package = mkOption { type = package; - default = self.packages.${pkgs.system}.eris; - defaultText = literalExpression "pkgs.eris"; + default = self.packages.${pkgs.stdenv.system}.eris; + defaultText = literalExpression "self.packages.\${pkgs.stdenv.system}.eris"; description = "The Eris package to use."; }; @@ -52,6 +53,7 @@ in { metricsPort = mkOption { type = port; default = 9100; + example = 9110; description = "The port for the Prometheus metrics endpoint."; }; @@ -65,13 +67,13 @@ in { minDelay = mkOption { type = int; default = 1000; - description = "Minimum delay (in milliseconds) between sending characters in tarpit mode."; + description = "Minimum delay (in ms) between sending characters in tarpit mode."; }; maxDelay = mkOption { type = int; default = 15000; - description = "Maximum delay (in milliseconds) between sending characters in tarpit mode."; + description = "Maximum delay (in ms) between sending characters in tarpit mode."; }; maxTarpitTime = mkOption { @@ -153,7 +155,7 @@ in { dataDir = mkOption { # This derives from stateDir by default to keep persistent data together type = path; - default = "${cfg.stateDir}/data"; + default = "/var/lib/eris/data"; description = "Directory containing `corpora` and `scripts` subdirectories."; }; @@ -179,7 +181,7 @@ in { An attribute set where keys are Lua script filenames (e.g., "`my_script.lua`") and values are paths to the script files. These will be placed in {path}`''${cfg.dataDir}/scripts`. ''; - example = lib.literalExpression '' + example = literalExpression '' { "custom_tokens.lua" = ./custom_tokens.lua; } @@ -216,7 +218,7 @@ in { }; config = mkIf cfg.enable { - services.nftables = { + networking.nftables = { enable = mkIf cfg.nftablesIntegration cfg.nftablesIntegration; ruleset = mkIf cfg.nftablesIntegration '' table inet filter { @@ -224,7 +226,7 @@ in { type ipv4_addr; flags interval; comment "Managed by Eris NixOS module"; } - chain input { + chain INPUT { ${lib.optionalString cfg.nftablesDropRule '' ip saddr @eris_blacklist counter drop comment "Drop traffic from Eris blacklist"; ''} @@ -248,8 +250,8 @@ in { systemd.services.eris = { description = "Eris Tarpit Service"; wantedBy = ["multi-user.target"]; - after = ["network.target"] ++ optionals cfg.nftablesIntegration "nftables.service"; - requires = optionals cfg.nftablesIntegration "nftables.service"; + after = ["network.target"] ++ (optionals cfg.nftablesIntegration ["nftables.service"]); + requires = optionals cfg.nftablesIntegration ["nftables.service"]; serviceConfig = { # User and Group configuration @@ -258,7 +260,7 @@ in { # Process management ExecStart = '' - ${cfg.package}/bin/eris \ + ${lib.getExe cfg.package} \ --config-file ${erisConfigFile} \ --log-level ${cfg.logLevel} ''; @@ -274,27 +276,29 @@ in { # Deny privilege escalation NoNewPrivileges = true; + # FIXME: this breaks everything. # Filesystem access control - ProtectSystem = "strict"; # Mount /usr, /boot, /etc read-only - ProtectHome = true; # Make /home, /root inaccessible - - # Explicitly allow writes to state/cache/data dirs - ReadWritePaths = [ - cfg.stateDir - cfg.cacheDir - cfg.dataDir - ]; - - # Allow reads from config file path - ReadOnlyPaths = [erisConfigFile]; - - # Explicitly deny access to sensitive paths - InaccessiblePaths = [ - "/boot" - "/root" - "/home" - "/srv" # Add others as needed - ]; + # ProtectSystem = "strict"; # Mount /usr, /boot, /etc read-only + # ProtectHome = true; # Make /home, /root inaccessible + # + # # Explicitly allow writes to state/cache/data dirs + # ReadWritePaths = [ + # "/var/lib/eris" + # "${cfg.stateDir}" + # "${cfg.cacheDir}" + # "${cfg.dataDir}" + # ]; + # + # # Allow reads from config file path + # ReadOnlyPaths = ["${erisConfigFile}"]; + # + # # Explicitly deny access to sensitive paths + # InaccessiblePaths = [ + # "/boot" + # "/root" + # "/home" + # "/srv" + # ]; PrivateTmp = true; # Use private /tmp and /var/tmp PrivateDevices = true; # Restrict device access (/dev) @@ -306,17 +310,14 @@ in { ProtectControlGroups = true; # Make Control Group hierarchies read-only # Network access control - RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; # Allow only standard IP protocols - CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; # Allow binding to ports < 1024 if needed + RestrictAddressFamilies = ["AF_INET" "AF_INET6"]; + + CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"]; AmbientCapabilities = ["CAP_NET_BIND_SERVICE"]; - # System call filtering (adjust based on Eris's needs) # Start with a reasonable baseline for network services SystemCallFilter = ["@system-service" "@network-io" "@file-system"]; - # TODO: Consider adding more specific filters or removing groups if issues arise - # e.g., SystemCallArchitectures=native. This probably will not be enough - # Other hardening RestrictNamespaces = true; # Prevent creation of new namespaces LockPersonality = true; # Lock down legacy personality settings @@ -326,8 +327,8 @@ in { RestrictSUIDSGID = true; # Ignore SUID/SGID bits on execution # Directories managed by systemd - StateDirectory = lib.baseNameOf cfg.stateDir; # e.g., "eris" - CacheDirectory = lib.baseNameOf cfg.cacheDir; # e.g., "eris" + StateDirectory = "eris"; + CacheDirectory = "eris"; StateDirectoryMode = "0750"; CacheDirectoryMode = "0750"; @@ -340,13 +341,11 @@ in { preStart = let corporaDir = "${cfg.dataDir}/corpora"; scriptsDir = "${cfg.dataDir}/scripts"; - chownCmd = "${pkgs.coreutils}/bin/chown ${cfg.user}:${cfg.group}"; # Create commands to copy corpora files copyCorporaCmds = lib.mapAttrsToList (name: path: '' cp -vf ${path} ${corporaDir}/${name} - ${chownCmd} ${corporaDir}/${name} '') cfg.corpora; @@ -354,23 +353,12 @@ in { copyLuaScriptCmds = lib.mapAttrsToList (name: path: '' cp -vf ${path} ${scriptsDir}/${name} - ${chownCmd} ${scriptsDir}/${name} '') cfg.luaScripts; in '' - # Systemd creates StateDirectory and CacheDirectory, but we need subdirs - mkdir -p ${cfg.stateDir}/conf ${cfg.dataDir} ${corporaDir} ${scriptsDir} - - # Ensure ownership is correct for all relevant dirs managed by systemd or created here - ${chownCmd} /var/lib/${lib.baseNameOf cfg.stateDir} \ - /var/cache/${lib.baseNameOf cfg.cacheDir} \ - ${cfg.stateDir}/conf \ - ${cfg.dataDir} \ - ${corporaDir} \ - ${scriptsDir} # Copy declarative files - ${lib.toString copyCorporaCmds} - ${lib.toString copyLuaScriptCmds} + ${lib.optionalString (cfg.corpora != {}) (toString copyCorporaCmds)} + ${lib.optionalString (cfg.luaScripts != {}) (toString copyLuaScriptCmds)} ''; }; }; diff --git a/nix/package.nix b/nix/package.nix index b63886d..b227e1a 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -18,6 +18,7 @@ in root = s; fileset = fs.unions [ (fs.fileFilter (file: builtins.any file.hasExt ["rs"]) (s + /src)) + (s + /contrib) lockfile cargoToml ]; @@ -25,8 +26,8 @@ in postInstall = '' mkdir -p $out/share/contrib - cp -r ${../contrib}/corpus $out/share/contrib/ - cp -r ${../contrib}/lua $out/share/contrib/ + cp -rv $src/contrib/corpus $out/share/contrib + cp -rv $src/contrib/lua $out/share/contrib ''; cargoLock.lockFile = lockfile;