From f9cf99dadbe366182061b67ba16e9dd49947eb21 Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Wed, 26 Aug 2026 17:53:53 +0800 Subject: [PATCH] security: add conservative systemd hardening to aquamarine services --- hosts/idols-aquamarine/service-hardening.nix | 38 +++++++++++++++++++ .../security-service-hardening/expected.nix | 12 ++++++ .../tests/security-service-hardening/expr.nix | 18 +++++++++ 3 files changed, 68 insertions(+) create mode 100644 hosts/idols-aquamarine/service-hardening.nix create mode 100644 outputs/x86_64-linux/tests/security-service-hardening/expected.nix create mode 100644 outputs/x86_64-linux/tests/security-service-hardening/expr.nix diff --git a/hosts/idols-aquamarine/service-hardening.nix b/hosts/idols-aquamarine/service-hardening.nix new file mode 100644 index 00000000..ac755ce2 --- /dev/null +++ b/hosts/idols-aquamarine/service-hardening.nix @@ -0,0 +1,38 @@ +{ lib, ... }: +let + # Universally-safe systemd sandboxing for network-facing services: no + # filesystem-write impact and cannot break a well-behaved service. + # ProtectSystem/ProtectHome/ReadWritePaths are intentionally EXCLUDED + # (they risk breaking services; fix upstream in nixpkgs instead). + safe = { + NoNewPrivileges = true; + PrivateTmp = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectKernelReadonly = true; + ProtectKernelIntegrity = true; + ProtectKernelDevelopment = true; + ProtectControlGroups = true; + ProtectClock = true; + ProtectHostname = true; + RestrictRealtime = true; + SystemCallArchitectures = [ "native" ]; + }; + services = [ + "caddy" + "postgresql" + "gitea" + "sftpgo" + "v2ray" + "transmission" + ]; +in +{ + systemd.services = lib.listToAttrs ( + map (s: { + name = s; + value.serviceConfig = safe; + }) services + ); +} diff --git a/outputs/x86_64-linux/tests/security-service-hardening/expected.nix b/outputs/x86_64-linux/tests/security-service-hardening/expected.nix new file mode 100644 index 00000000..a3921473 --- /dev/null +++ b/outputs/x86_64-linux/tests/security-service-hardening/expected.nix @@ -0,0 +1,12 @@ +{ + lib, + outputs, +}: +{ + caddy = true; + postgresql = true; + gitea = true; + sftpgo = true; + v2ray = true; + transmission = true; +} diff --git a/outputs/x86_64-linux/tests/security-service-hardening/expr.nix b/outputs/x86_64-linux/tests/security-service-hardening/expr.nix new file mode 100644 index 00000000..1335ca63 --- /dev/null +++ b/outputs/x86_64-linux/tests/security-service-hardening/expr.nix @@ -0,0 +1,18 @@ +{ + lib, + outputs, +}: +let + cfg = outputs.nixosConfigurations.aquamarine.config; + # NoNewPrivileges on a service (all six exist on aquamarine). Note: the + # `? name` exists-check misbehaves on systemd.services here, so access directly. + svc = name: (cfg.systemd.services.${name}.serviceConfig or { }).NoNewPrivileges or false; +in +{ + caddy = svc "caddy"; + postgresql = svc "postgresql"; + gitea = svc "gitea"; + sftpgo = svc "sftpgo"; + v2ray = svc "v2ray"; + transmission = svc "transmission"; +}