nix-config/modules/activity-relay.nix

154 lines
4.3 KiB
Nix

{ lib, config, pkgs, ... }:
let
cfg = config.services.activity-relay;
configFile = pkgs.writeText "activity-relay.json" (
builtins.toJSON ({
ACTOR_PEM = cfg.actorPem.path;
REDIS_URL = cfg.redisUrl;
RELAY_BIND = cfg.relay.bind;
RELAY_SERVICENAME = cfg.relay.serviceName;
RELAY_DOMAIN = cfg.relay.domain;
RELAY_SUMMARY = cfg.relay.summary;
JOB_CONCURRENCY = cfg.jobConcurrency;
} // lib.optionalAttrs (cfg.relay.icon != null) {
RELAY_ICON = cfg.relay.icon;
} // lib.optionalAttrs (cfg.relay.image != null) {
RELAY_IMAGE = cfg.relay.image;
}));
in
{
options.services.activity-relay = {
enable = lib.mkEnableOption "Activity-Relay ActivityPub relay server";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.activity-relay;
};
user = lib.mkOption {
type = lib.types.str;
default = "relay";
};
group = lib.mkOption {
type = lib.types.str;
default = "relay";
};
actorPem.path = lib.mkOption {
type = lib.types.str;
default = "${config.users.users.${cfg.user}.home}/actor.pem";
};
actorPem.generate = lib.mkOption {
type = lib.types.bool;
default = true;
};
redisUrl = lib.mkOption {
type = lib.types.str;
default = "redis://127.0.0.1:6379";
};
relay = {
bind = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0:8080";
};
domain = lib.mkOption {
type = lib.types.str;
};
serviceName = lib.mkOption {
type = lib.types.str;
default = "NixOS Activity-Relay";
};
summary = lib.mkOption {
type = lib.types.str;
default = "";
};
icon = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
};
image = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
};
};
jobConcurrency = lib.mkOption {
type = lib.types.int;
default = 50;
};
};
config = lib.mkIf cfg.enable {
users = {
users.${cfg.user} = {
isSystemUser = true;
inherit (cfg) group;
home = "/var/lib/activity-relay";
};
groups.${cfg.group} = {};
};
systemd.services = {
relay-api = {
description = "Activity-Relay server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
StateDirectory = "activity-relay";
CapabilityBoundingSet = "";
PrivateDevices = true;
PrivateUsers = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
SystemCallArchitectures = "native";
# SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
Restart = lib.mkDefault "always";
RestartSec = 10;
};
script = ''
${lib.optionalString cfg.actorPem.generate ''
if ! [ -e "${cfg.actorPem.path}" ]; then
${lib.getExe pkgs.openssl} genrsa -traditional > "${cfg.actorPem.path}"
fi
''}
exec ${lib.getExe cfg.package} -c ${configFile} -v server
'';
};
relay-worker = {
description = "Activity-Relay worker";
after = [ "network.target" "relay-api.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
StateDirectory = "activity-relay";
CapabilityBoundingSet = "";
PrivateDevices = true;
PrivateUsers = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
SystemCallArchitectures = "native";
# SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
Restart = lib.mkDefault "always";
RestartSec = 10;
ExecStart = "${lib.getExe cfg.package} -c ${configFile} -v worker";
};
};
};
};
}