nixos-configuration/nixosModules/servicepoint-tanks.nix
2025-10-12 15:16:44 +02:00

121 lines
3.2 KiB
Nix

{
pkgs,
config,
lib,
...
}:
let
cfg = config.services.servicepoint-tanks;
default-user-name = "servicepoint-tanks";
in
{
options.services.servicepoint-tanks = {
enable = lib.mkEnableOption "servicepoint-tanks";
package = lib.mkPackageOption pkgs "servicepoint-tanks" { };
urls = lib.mkOption {
default = [ "http://localhost:5000" ];
description = ''
Configures which protocol to bind on which host:port combination.
'';
type = lib.types.listOf lib.types.str;
example = [
"http://0.0.0.0"
"http://localhost:5000"
# TODO: allow HTTPS
];
};
user = lib.mkOption {
default = default-user-name;
description = ''
The user under which servicepoint-tanks is run.
This module utilizes systemd's DynamicUser feature. See the corresponding section in
{manpage}`systemd.exec(5)` for more details.
'';
type = lib.types.str;
};
group = lib.mkOption {
default = default-user-name;
description = ''
The group under which servicepoint-tanks is run.
This module utilizes systemd's DynamicUser feature. See the corresponding section in
{manpage}`systemd.exec(5)` for more details.
'';
type = lib.types.str;
};
};
config = lib.mkIf cfg.enable {
users = {
users = lib.mkIf (cfg.user == default-user-name) {
"${default-user-name}" = {
isSystemUser = true;
group = cfg.group;
};
};
groups = lib.mkIf (cfg.group == default-user-name) {
"${default-user-name}" = { };
};
};
systemd.services.sericepoint-tanks = {
description = "Run the servicepoint-tanks server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
environment = {
ASPNETCORE_URLS = "${lib.strings.concatStringsSep ";" cfg.urls}";
};
serviceConfig = {
User = cfg.user;
Group = cfg.group;
DynamicUser = true;
Type = "exec";
ExecStart = "${lib.getBin cfg.package}/bin/TanksServer";
# hardening
NoNewPrivileges = true;
CapabilityBoundingSet = null;
SystemCallFilter = [
"@system-service"
"~@privileged"
];
SystemCallArchitectures = "native";
AmbientCapabilities = "";
PrivateMounts = true;
PrivateUsers = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectHome = true;
ProtectClock = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
ProtectControlGroups = "strict";
LockPersonality = true;
RemoveIPC = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RestrictNamespaces = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
# TODO: enable unix domain socket bind
# "AF_UNIX"
];
# TODO: try fully AOT build with:
#MemoryDenyWriteExecute = true;
};
};
};
}