troutbot/nix/modules/nixos.nix
NotAShelf e854522ebe
nix: harden Systemd service in NixOS module
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I086cdbfcd0a0d1d87173a2cf97f5b5416a6a6964
2026-02-07 16:28:44 +03:00

119 lines
2.9 KiB
Nix

self: {
config,
pkgs,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) nullOr str port package;
defaultPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.troutbot;
cfg = config.services.troutbot;
in {
options.services.troutbot = {
enable = mkEnableOption "troutbot";
package = mkOption {
type = nullOr package;
default = defaultPackage;
defaultText = literalExpression "inputs.troutbot.packages.${pkgs.stdenv.hostPlatform.system}.troutbot";
description = ''
The Troutbot package to use.
By default, this option will use the `packages.default` as exposed by this flake.
'';
};
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 = {
groups.${cfg.settings.group} = {};
users.${cfg.settings.user} = {
isSystemUser = true;
inherit (cfg.settings) group;
};
};
systemd.services.troutbot = {
description = "Troutbot";
after = ["network-online.target"];
wants = ["network-online.target"];
wantedBy = ["multi-user.target"];
environment = {
NODE_ENV = "production";
CONFIG_PATH = cfg.configPath;
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;
};
};
};
}