nix: harden Systemd service in NixOS module

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I086cdbfcd0a0d1d87173a2cf97f5b5416a6a6964
This commit is contained in:
raf 2026-02-01 17:57:33 +03:00
commit e854522ebe
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
2 changed files with 64 additions and 28 deletions

View file

@ -25,58 +25,94 @@ in {
'';
};
user = mkOption {
type = str;
default = "troutbot";
};
group = mkOption {
type = str;
default = "troutbot";
};
port = mkOption {
type = port;
default = 3000;
};
environmentFile = mkOption {
type = nullOr str;
default = null;
description = ''
Environment file for specifying additional settings such as secrets.
'';
};
configPath = mkOption {
type = nullOr str;
default = null;
description = ''
File path containing the Troutbot Typescript config.
'';
};
settings = {
user = mkOption {
type = str;
default = "troutbot";
description = "User to run Troutbot under";
};
group = mkOption {
type = str;
default = "troutbot";
description = "Group to run Troutbot under";
};
port = mkOption {
type = port;
default = 3000;
description = "Port to bind to";
};
};
};
config = mkIf cfg.enable {
users.users.${cfg.user} = {
isSystemUser = true;
group = cfg.group;
users = {
groups.${cfg.settings.group} = {};
users.${cfg.settings.user} = {
isSystemUser = true;
inherit (cfg.settings) group;
};
};
users.groups.${cfg.group} = {};
systemd.services.troutbot = {
description = "Troutbot";
after = ["network.target"];
after = ["network-online.target"];
wants = ["network-online.target"];
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "simple";
User = cfg.user;
Group = cfg.group;
ExecStart = "${lib.getExe cfg.package}";
Restart = "on-failure";
EnvironmentFile = cfg.environmentFile;
environment = {
NODE_ENV = "production";
CONFIG_PATH = cfg.configPath;
PORT = toString cfg.port;
PORT = toString cfg.settings.port;
};
serviceConfig = {
Type = "simple";
User = cfg.settings.user;
Group = cfg.settings.group;
ExecStart = "${lib.getExe cfg.package}";
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
Restart = "on-failure";
RestartSec = "5s";
TimeoutStartSec = "10s";
TimeoutStopSec = "10s";
WorkingDirectory = "/var/lib/troutbot";
StateDirectory = "troutbot";
StateDirectoryMode = "0750";
# Hardening
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
NoNewPrivileges = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
ProtectClock = true;
LockPersonality = true;
};
};
};

View file

@ -35,7 +35,7 @@ stdenv.mkDerivation (finalAttrs: {
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
fetcherVersion = 3;
hash = "sha256-y8LV1D+EgGcZ79lmxS20dqYBPEfk4atma+RWf7pJI30=";
hash = "sha256-96VRuwKes2FrOUFrlKjFBhdD7xC0W3vNNhT2TJWeJGc=";
};
buildPhase = ''