# A NixOS module which can run a service tracking spending of ZKAPs. # 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 = "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 = [ "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 = (import ./restricted-service.nix) // { 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. Restart = "always"; Type = "simple"; # 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"; }; 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 ]; }; }