diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index 4ba61c8baadb..f531ff61af86 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -140,6 +140,8 @@ - [nostr-rs-relay](https://git.sr.ht/~gheartsfield/nostr-rs-relay/), This is a nostr relay, written in Rust. Available as [services.nostr-rs-relay](options.html#opt-services.nostr-rs-relay.enable). +- [haven](https://github.com/bitvora/haven), is a high availability vault for events on nostr. Available as [services.haven](options.html#opt-services.haven.enable). + - [strfry](https://github.com/hoytech/strfry), a relay for the nostr protocol. Available as [services.strfry](options.html#opt-services.strfry.enable). - [Prometheus Node Cert Exporter](https://github.com/amimof/node-cert-exporter), a prometheus exporter to check for SSL cert expiry. Available under [services.prometheus.exporters.node-cert](#opt-services.prometheus.exporters.node-cert.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2bcd9b90c178..6a3be1eb100f 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1537,6 +1537,7 @@ ./services/web-apps/guacamole-client.nix ./services/web-apps/guacamole-server.nix ./services/web-apps/hatsu.nix + ./services/web-apps/haven.nix ./services/web-apps/healthchecks.nix ./services/web-apps/hedgedoc.nix ./services/web-apps/hledger-web.nix diff --git a/nixos/modules/services/web-apps/haven.nix b/nixos/modules/services/web-apps/haven.nix new file mode 100644 index 000000000000..b5417ffb3c06 --- /dev/null +++ b/nixos/modules/services/web-apps/haven.nix @@ -0,0 +1,137 @@ +{ + config, + pkgs, + lib, + ... +}: +let + # Load default values from package. See https://github.com/bitvora/haven/blob/master/.env.example + defaultSettings = builtins.fromTOML (builtins.readFile "${cfg.package}/share/haven/.env.example"); + + import_relays_file = "${pkgs.writeText "import_relays.json" (builtins.toJSON cfg.importRelays)}"; + blastr_relays_file = "${pkgs.writeText "blastr_relays.json" (builtins.toJSON cfg.blastrRelays)}"; + + mergedSettings = cfg.settings // { + IMPORT_SEED_RELAYS_FILE = import_relays_file; + BLASTR_RELAYS_FILE = blastr_relays_file; + }; + + cfg = config.services.haven; +in +{ + options.services.haven = { + enable = lib.mkEnableOption "haven"; + + package = lib.mkPackageOption pkgs "haven" { }; + + blastrRelays = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "List of relay configurations for blastr"; + example = lib.literalExpression '' + [ + "relay.example.com" + ] + ''; + }; + + importRelays = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "List of relay configurations for importing historical events"; + example = lib.literalExpression '' + [ + "relay.example.com" + ] + ''; + }; + + settings = lib.mkOption { + default = defaultSettings; + defaultText = "See https://github.com/bitvora/haven/blob/master/.env.example"; + apply = lib.recursiveUpdate defaultSettings; + description = "See https://github.com/bitvora/haven for documentation."; + example = lib.literalExpression '' + { + RELAY_URL = "relay.example.com"; + OWNER_NPUB = "npub1..."; + } + ''; + }; + + environmentFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + Path to a file containing sensitive environment variables. See https://github.com/bitvora/haven for documentation. + The file should contain environment-variable assignments like: + S3_SECRET_KEY=mysecretkey + S3_ACCESS_KEY_ID=myaccesskey + ''; + example = "/var/lib/haven/secrets.env"; + }; + }; + + config = lib.mkIf cfg.enable { + users.users.haven = { + description = "Haven daemon user"; + group = "haven"; + isSystemUser = true; + }; + + users.groups.haven = { }; + + systemd.services.haven = { + description = "haven"; + wants = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment = lib.attrsets.mapAttrs ( + name: value: if builtins.isBool value then if value then "true" else "false" else toString value + ) mergedSettings; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/haven"; + EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; + User = "haven"; + Group = "haven"; + Restart = "on-failure"; + + RuntimeDirectory = "haven"; + StateDirectory = "haven"; + WorkingDirectory = "/var/lib/haven"; + + # Create symlink to templates in the working directory + ExecStartPre = "+${pkgs.coreutils}/bin/ln -sfT ${cfg.package}/share/haven/templates /var/lib/haven/templates"; + + PrivateTmp = true; + PrivateUsers = true; + PrivateDevices = true; + ProtectSystem = "strict"; + ProtectHome = true; + NoNewPrivileges = true; + MemoryDenyWriteExecute = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectClock = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + ProtectControlGroups = true; + LockPersonality = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + RestrictRealtime = true; + ProtectHostname = true; + CapabilityBoundingSet = ""; + SystemCallFilter = [ + "@system-service" + ]; + SystemCallArchitectures = "native"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ + felixzieger + ]; +} diff --git a/pkgs/by-name/ha/haven/package.nix b/pkgs/by-name/ha/haven/package.nix new file mode 100644 index 000000000000..94576cfe985d --- /dev/null +++ b/pkgs/by-name/ha/haven/package.nix @@ -0,0 +1,34 @@ +{ + lib, + buildGoModule, + fetchFromGitHub, +}: + +buildGoModule rec { + pname = "haven"; + version = "1.0.5"; + + src = fetchFromGitHub { + owner = "bitvora"; + repo = "haven"; + tag = "v${version}"; + hash = "sha256-rSycrHW53TgqbsfgaRn3492EWtpu440GtbegozqnzMQ="; + }; + + vendorHash = "sha256-5d6C2sNG8aCaC+z+hyLgOiEPWP/NmAcRRbRVC4KuCEw="; + + postInstall = '' + mkdir -p $out/share/haven + cp -r $src/templates $out/share/haven/ + cp $src/.env.example $out/share/haven/.env.example + ''; + + meta = { + description = "High Availability Vault for Events on Nostr"; + homepage = "https://github.com/bitvora/haven"; + changelog = "https://github.com/bitvora/haven/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ felixzieger ]; + mainProgram = "haven"; + }; +}