Skip to content
Snippets Groups Projects
spending.nix 5.27 KiB
Newer Older
  • Learn to ignore specific revisions
  • # A NixOS module which can run a Ristretto-based issuer for PrivateStorage
    # ZKAPs.
    { lib, pkgs, config, ourpkgs, ... }@args: let
      cfg = config.services.private-storage-spending;
    in
    {
      options = {
        services.private-storage-spending = {
          enable = lib.mkEnableOption "PrivateStorage Spending Service";
          package = lib.mkOption {
            default = ourpkgs.zkap-spending-service;
            type = lib.types.package;
            example = lib.literalExample "ourpkgs.zkap-spending-service";
            description = ''
              The package to use for the spending service.
            '';
          };
          unixSocket = lib.mkOption {
            default = "/run/zkap-spending-service/api.socket";
            type = lib.types.path;
            description = ''
              The unix socket that the spending service API listens on.
            '';
          };
        };
        services.private-storage-spending.domain = lib.mkOption {
          default = config.networking.fqdn;
          type = lib.types.str;
          example = lib.literalExample [ "spending.example.com" ];
          description = ''
            The domain name at which the spending service is reachable.
          '';
        };
      };
    
      config =
        lib.mkIf cfg.enable {
          systemd.sockets.zkap-spending-service = {
            enable = true;
            wantedBy = [ "sockets.target" ];
            listenStreams = [ cfg.unixSocket ];
          };
          # Add a systemd service to run zkap-spending-service.
          systemd.services.zkap-spending-service = {
            enable = true;
            description = "ZKAP Spending Service";
            wantedBy = [ "multi-user.target" ];
    
            serviceConfig.NonBlocking = true;
    
            # It really shouldn't ever exit on its own!  If it does, it's a bug
            # we'll have to fix.  Restart it and hope it doesn't happen too much
            # before we can fix whatever the issue is.
            serviceConfig.Restart = "always";
            serviceConfig.Type = "simple";
    
    
    Tom Prince's avatar
    Tom Prince committed
            # Use a unnamed user.
            serviceConfig.DynamicUser = true;
    
            serviceConfig = {
              # Work around https://twistedmatrix.com/trac/ticket/10261
              # Create a runtime directory so that the service has permission
              # to change the mode on the socket.
              RuntimeDirectory = "zkap-spending-service";
    
              # This set of restrictions is mostly dervied from
              # - running `systemd-analyze security zkap-spending-service.service
              # - Looking at the restrictions from the nixos nginx config.
              AmbientCapabilities = "";
              CapabilityBoundingSet = "";
              LockPersonality = true;
              MemoryDenyWriteExecute = true;
              NoNewPrivileges = true;
              PrivateDevices = true;
              PrivateMounts = true;
              PrivateNetwork = true;
              PrivateTmp = true;
              PrivateUsers = true;
              ProcSubset = "pid";
              ProtectClock = true;
              ProtectControlGroups = true;
              ProtectHome = true;
              ProtectHostname = true;
              ProtectKernelLogs = true;
              ProtectKernelModules = true;
              ProtectKernelTunables = true;
              ProtectProc = "invisible";
              ProtectSystem = "strict";
              RemoveIPC = true;
              RestrictAddressFamilies = "AF_UNIX";
              RestrictNamespaces = true;
              RestrictRealtime = true;
              RestrictSUIDSGID = true;
              SystemCallArchitectures = "native";
              # Lines starting with "~" are deny-list the others are allow-list
              # Since the first line is allow, that bounds the set of allowed syscalls
              # and the further lines restrict it.
              SystemCallFilter = [
                # From systemd.exec(5), @system-service is "A reasonable set of
                # system calls used by common system [...]"
                "@system-service"
                # This is from the nginx config, except that `@ipc` is not removed,
                # since twisted uses a self-pipe.
                "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid"
              ];
              Umask = "0077";
            };
    
    
            script = let
              httpArgs = "--http-endpoint systemd:domain=UNIX:index=0";
            in
              "exec ${cfg.package}/bin/${cfg.package.meta.mainProgram} run ${httpArgs}";
          };
    
          services.nginx = {
            enable = true;
    
            recommendedGzipSettings = true;
            recommendedOptimisation = true;
            recommendedProxySettings = true;
            recommendedTlsSettings = true;
    
            virtualHosts."${cfg.domain}" = {
              locations."/v1/" = {
                # Only forward requests beginning with /v1/ so
                # we pass less scanning spam on to our backend
                # Want a regex instead? try locations."~ /v\d+/"
                proxyPass = "http://unix:${cfg.unixSocket}";
              };
    
              locations."/metrics" = {
                proxyPass = "http://unix:${cfg.unixSocket}";
                # Only allow our monitoringvpn subnet
                extraConfig = ''
                  allow 172.23.23.0/24;
                  allow 127.0.0.1;
                  allow ::1;
                  deny all;
                '';
              };
    
              locations."/" = {
                # Return a 404 error for any paths not specified above.
                extraConfig = ''
                  return 404;
                '';
              };
            };
          };
    
    
          # Open 80 and 443 for nginx
          networking.firewall.allowedTCPPorts = [
            80
            443
          ];