Unverified Commit be53df72 authored by Martin Weinelt's avatar Martin Weinelt Committed by Sandro Jäckel
Browse files

nixos/vaultwarden: harden systemd unit

Drops the capability to bind to privileged ports.
parent d8c8faf8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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.

+34 −5
Original line number Diff line number Diff line
@@ -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" ];
    };
+9 −6
Original line number Diff line number Diff line
@@ -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")