nixos/vaultwarden: harden systemd unit

Drops the capability to bind to privileged ports.
This commit is contained in:
Martin Weinelt 2024-06-11 02:42:39 +02:00 committed by Sandro Jäckel
parent d8c8faf8c3
commit be53df7236
No known key found for this signature in database
GPG Key ID: 3AF5A43A3EECC2E5
3 changed files with 47 additions and 11 deletions

View File

@ -35,6 +35,10 @@
- `services.ddclient.use` has been deprecated: `ddclient` now supports separate IPv4 and IPv6 configuration. Use `services.ddclient.usev4` and `services.ddclient.usev6` instead.
- `vaultwarden` lost the capability to bind to privileged ports. If you rely on
this behavior, override the systemd unit to allow `CAP_NET_BIND_SERVICE` in
your local configuration.
- The Invoiceplane module now only accepts the structured `settings` option.
`extraConfig` is now removed.

View File

@ -178,16 +178,45 @@ in {
User = user;
Group = group;
EnvironmentFile = [ configFile ] ++ lib.optional (cfg.environmentFile != null) cfg.environmentFile;
ExecStart = "${vaultwarden}/bin/vaultwarden";
ExecStart = lib.getExe vaultwarden;
LimitNOFILE = "1048576";
PrivateTmp = "true";
PrivateDevices = "true";
ProtectHome = "true";
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
DevicePolicy = "closed";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "noaccess";
ProtectSystem = "strict";
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
inherit StateDirectory;
StateDirectoryMode = "0700";
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
Restart = "always";
UMask = "0077";
};
wantedBy = [ "multi-user.target" ];
};

View File

@ -34,7 +34,7 @@ let
driver = Firefox(options=options)
driver.implicitly_wait(20)
driver.get('http://localhost/#/register')
driver.get('http://localhost:8080/#/register')
wait = WebDriverWait(driver, 10)
@ -134,11 +134,11 @@ let
dbBackend = backend;
config = {
rocketAddress = "0.0.0.0";
rocketPort = 80;
rocketPort = 8080;
};
};
networking.firewall.allowedTCPPorts = [ 80 ];
networking.firewall.allowedTCPPorts = [ 8080 ];
environment.systemPackages = [ pkgs.firefox-unwrapped pkgs.geckodriver testRunner ];
}
@ -152,10 +152,10 @@ let
testScript = if testScript != null then testScript else ''
start_all()
server.wait_for_unit("vaultwarden.service")
server.wait_for_open_port(80)
server.wait_for_open_port(8080)
with subtest("configure the cli"):
client.succeed("bw --nointeraction config server http://server")
client.succeed("bw --nointeraction config server http://server:8080")
with subtest("can't login to nonexistent account"):
client.fail(
@ -179,6 +179,9 @@ let
timeout=60
)
assert password.strip() == "${storedPassword}"
with subtest("Check systemd unit hardening"):
server.log(server.succeed("systemd-analyze security vaultwarden.service | grep -v "))
'';
});
in
@ -193,7 +196,7 @@ builtins.mapAttrs (k: v: makeVaultwardenTest k v) {
testScript = ''
start_all()
server.wait_for_unit("vaultwarden.service")
server.wait_for_open_port(80)
server.wait_for_open_port(8080)
with subtest("Set up vaultwarden"):
server.succeed("PYTHONUNBUFFERED=1 test-runner | systemd-cat -t test-runner")