feat(conduit): Refactor matrix appservices and add matrix-hookshot
This commit is contained in:
parent
08ff591117
commit
c495d165df
9 changed files with 303 additions and 91 deletions
configuration
|
@ -17,7 +17,7 @@
|
|||
|
||||
./services/backups.nix
|
||||
./services/battery-manager.nix
|
||||
./services/conduit.nix
|
||||
./services/conduit
|
||||
./services/crowdsec.nix
|
||||
./services/foundryvtt.nix
|
||||
./services/gitea.nix
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
|
@ -12,6 +11,11 @@ let
|
|||
turn-realm = "turn.${config.services.nginx.domain}";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./heisenbridge.nix
|
||||
./matrix-hookshot.nix
|
||||
];
|
||||
|
||||
services.matrix-conduit = {
|
||||
enable = true;
|
||||
settings.global = {
|
||||
|
@ -40,91 +44,6 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
systemd.services.heisenbridge =
|
||||
let
|
||||
replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
|
||||
registrationFile = builtins.toFile "heisenbridge-registration.yaml" (
|
||||
builtins.toJSON {
|
||||
id = "heisenbridge";
|
||||
url = "http://127.0.0.1:9898";
|
||||
as_token = "@AS_TOKEN@";
|
||||
hs_token = "@HS_TOKEN@";
|
||||
rate_limited = false;
|
||||
sender_localpart = "heisenbridge";
|
||||
namespaces = {
|
||||
users = [
|
||||
{
|
||||
regex = "@irc_.*";
|
||||
exclusive = true;
|
||||
}
|
||||
{
|
||||
regex = "@heisenbridge:.*";
|
||||
exclusive = true;
|
||||
}
|
||||
];
|
||||
aliases = [ ];
|
||||
rooms = [ ];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
# TODO(tlater): Starting with systemd 253 it will become possible
|
||||
# to do the credential setup as part of ExecStartPre/preStart
|
||||
# instead.
|
||||
#
|
||||
# This will also make it possible to actually set caps on the
|
||||
# heisenbridge process using systemd, so that we can run the
|
||||
# identd process.
|
||||
execScript = pkgs.writeShellScript "heisenbridge" ''
|
||||
cp ${registrationFile} "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
|
||||
chmod 600 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
|
||||
${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_as-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
|
||||
${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/heisenbridge_hs-token" "$RUNTIME_DIRECTORY/heisenbridge-registration.yaml"
|
||||
chmod 400 $RUNTIME_DIRECTORY/heisenbridge-registration.yaml
|
||||
|
||||
${pkgs.heisenbridge}/bin/heisenbridge \
|
||||
--config $RUNTIME_DIRECTORY/heisenbridge-registration.yaml \
|
||||
--owner @tlater:matrix.tlater.net \
|
||||
'http://localhost:${toString cfg.settings.global.port}'
|
||||
'';
|
||||
in
|
||||
{
|
||||
description = "Matrix<->IRC bridge";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "conduit.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
|
||||
LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
|
||||
|
||||
ExecStart = execScript;
|
||||
|
||||
DynamicUser = true;
|
||||
RuntimeDirectory = "heisenbridge";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
|
||||
RestrictNamespaces = true;
|
||||
PrivateUsers = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
UMask = 77;
|
||||
|
||||
# For the identd port
|
||||
# CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE"];
|
||||
# AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
|
||||
};
|
||||
};
|
||||
|
||||
# Pass in the TURN secret via EnvironmentFile, not supported by
|
||||
# upstream module currently.
|
||||
#
|
78
configuration/services/conduit/heisenbridge.nix
Normal file
78
configuration/services/conduit/heisenbridge.nix
Normal file
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
conduitCfg = config.services.matrix-conduit;
|
||||
matrixLib = pkgs.callPackage ./lib.nix { };
|
||||
in
|
||||
{
|
||||
systemd.services.heisenbridge =
|
||||
let
|
||||
registration = matrixLib.writeRegistrationScript {
|
||||
id = "heisenbridge";
|
||||
url = "http://127.0.0.1:9898";
|
||||
sender_localpart = "heisenbridge";
|
||||
|
||||
namespaces = {
|
||||
users = [
|
||||
{
|
||||
regex = "@irc_.*";
|
||||
exclusive = true;
|
||||
}
|
||||
{
|
||||
regex = "@heisenbridge:.*";
|
||||
exclusive = true;
|
||||
}
|
||||
];
|
||||
|
||||
aliases = [ ];
|
||||
rooms = [ ];
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
description = "Matrix<->IRC bridge";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "conduit.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
|
||||
LoadCredential = "heisenbridge:/run/secrets/heisenbridge";
|
||||
|
||||
inherit (registration) ExecStartPre;
|
||||
ExecStart = lib.concatStringsSep " " [
|
||||
"${lib.getExe pkgs.heisenbridge}"
|
||||
"--config \${RUNTIME_DIRECTORY}/heisenbridge-registration.yaml"
|
||||
"--owner @tlater:matrix.tlater.net"
|
||||
"http://localhost:${toString conduitCfg.settings.global.port}"
|
||||
];
|
||||
|
||||
DynamicUser = true;
|
||||
RuntimeDirectory = "heisenbridge";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
|
||||
RestrictNamespaces = true;
|
||||
PrivateUsers = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
UMask = 77;
|
||||
|
||||
# For the identd port
|
||||
# CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
||||
# AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
};
|
||||
};
|
||||
}
|
67
configuration/services/conduit/lib.nix
Normal file
67
configuration/services/conduit/lib.nix
Normal file
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
lib,
|
||||
writeShellScript,
|
||||
formats,
|
||||
replace-secret,
|
||||
}:
|
||||
let
|
||||
replaceSecretBin = "${lib.getExe replace-secret}";
|
||||
in
|
||||
{
|
||||
# Write a script that will set up the service's registration.yaml
|
||||
# with secrets from systemd credentials.
|
||||
#
|
||||
# The credentials should be named `${id}_as-token` and
|
||||
# `${id}_hs-token`.
|
||||
#
|
||||
# This registration file needs to be manually added to conduit by
|
||||
# messaging the admin with the yaml file.
|
||||
#
|
||||
# TODO(tlater): Conduwuit seems to support a CLI interface for this,
|
||||
# may want to migrate to that sometime.
|
||||
writeRegistrationScript =
|
||||
{
|
||||
id, # Must be unique among all registered appservices/bots
|
||||
url, # The URL on which the service listens
|
||||
sender_localpart,
|
||||
rate_limited ? false,
|
||||
namespaces ? {
|
||||
aliases = [ ];
|
||||
rooms = [ ];
|
||||
users = [ ];
|
||||
},
|
||||
extraSettings ? { },
|
||||
# The location to place the file; assumes systemd runtime dir
|
||||
runtimeRegistration ? "$RUNTIME_DIRECTORY/${id}-registration.yaml",
|
||||
}:
|
||||
let
|
||||
registrationFile = (formats.yaml { }).generate "${id}-registration.yaml" (
|
||||
{
|
||||
inherit
|
||||
id
|
||||
url
|
||||
sender_localpart
|
||||
rate_limited
|
||||
namespaces
|
||||
;
|
||||
|
||||
as_token = "@AS_TOKEN@";
|
||||
hs_token = "@HS_TOKEN@";
|
||||
}
|
||||
// extraSettings
|
||||
);
|
||||
in
|
||||
{
|
||||
inherit runtimeRegistration;
|
||||
ExecStartPre = writeShellScript "${id}-registration-setup.sh" ''
|
||||
cp -f ${registrationFile} "${runtimeRegistration}"
|
||||
chmod 600 "${runtimeRegistration}"
|
||||
|
||||
# Write actual secrets into config
|
||||
${replaceSecretBin} '@AS_TOKEN@' "$CREDENTIALS_DIRECTORY/${id}_as-token" "${runtimeRegistration}"
|
||||
${replaceSecretBin} '@HS_TOKEN@' "$CREDENTIALS_DIRECTORY/${id}_hs-token" "${runtimeRegistration}"
|
||||
|
||||
chmod 400 "${runtimeRegistration}"
|
||||
'';
|
||||
};
|
||||
}
|
134
configuration/services/conduit/matrix-hookshot.nix
Normal file
134
configuration/services/conduit/matrix-hookshot.nix
Normal file
|
@ -0,0 +1,134 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
matrixLib = pkgs.callPackage ./lib.nix { };
|
||||
|
||||
cfg = config.services.matrix-hookshot;
|
||||
conduitCfg = config.services.matrix-conduit;
|
||||
|
||||
domain = conduitCfg.settings.global.server_name;
|
||||
|
||||
registration = matrixLib.writeRegistrationScript {
|
||||
id = "matrix-hookshot";
|
||||
url = "http://127.0.0.1:9993";
|
||||
sender_localpart = "hookshot";
|
||||
|
||||
namespaces = {
|
||||
aliases = [ ];
|
||||
rooms = [ ];
|
||||
users = [
|
||||
{
|
||||
regex = "@${cfg.settings.generic.userIdPrefix}.*:${domain}";
|
||||
exclusive = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
runtimeRegistration = "${cfg.registrationFile}";
|
||||
};
|
||||
in
|
||||
{
|
||||
systemd.services.matrix-hookshot = {
|
||||
serviceConfig = {
|
||||
Type = lib.mkForce "exec";
|
||||
|
||||
LoadCredential = "matrix-hookshot:/run/secrets/matrix-hookshot";
|
||||
inherit (registration) ExecStartPre;
|
||||
|
||||
# Some library in matrix-hookshot wants a home directory
|
||||
Environment = [ "HOME=/run/matrix-hookshot" ];
|
||||
|
||||
DynamicUser = true;
|
||||
StateDirectory = "matrix-hookshot";
|
||||
RuntimeDirectory = "matrix-hookshot";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
|
||||
RestrictNamespaces = true;
|
||||
PrivateUsers = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
UMask = 77;
|
||||
};
|
||||
};
|
||||
|
||||
services.matrix-hookshot = {
|
||||
enable = true;
|
||||
|
||||
serviceDependencies = [
|
||||
"conduit.service"
|
||||
];
|
||||
|
||||
registrationFile = "/run/matrix-hookshot/registration.yaml";
|
||||
|
||||
settings = {
|
||||
bridge = {
|
||||
inherit domain;
|
||||
url = "http://localhost:${toString conduitCfg.settings.global.port}";
|
||||
mediaUrl = conduitCfg.settings.global.well_known.client;
|
||||
port = 9993;
|
||||
bindAddress = "127.0.0.1";
|
||||
};
|
||||
|
||||
bot.displayname = "Hookshot";
|
||||
|
||||
generic = {
|
||||
enabled = true;
|
||||
outbound = false;
|
||||
# Only allow webhooks from localhost for the moment
|
||||
urlPrefix = "http://127.0.0.1:9000/webhook";
|
||||
userIdPrefix = "_webhooks_";
|
||||
};
|
||||
|
||||
permissions = [
|
||||
{
|
||||
actor = "matrix.tlater.net";
|
||||
services = [
|
||||
{
|
||||
service = "*";
|
||||
level = "notifications";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
actor = "@tlater:matrix.tlater.net";
|
||||
services = [
|
||||
{
|
||||
service = "*";
|
||||
level = "admin";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
listeners = [
|
||||
{
|
||||
port = 9000;
|
||||
resources = [
|
||||
"webhooks"
|
||||
];
|
||||
}
|
||||
{
|
||||
port = 9001;
|
||||
resources = [
|
||||
"metrics"
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
metrics.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -26,6 +26,10 @@
|
|||
config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_port;
|
||||
in
|
||||
[ "${address}:${toString port}" ];
|
||||
|
||||
# Configured in the hookshot listeners, but it's hard to filter
|
||||
# the correct values out of that config.
|
||||
matrixHookshot.targets = [ "127.0.0.1:9001" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
"heisenbridge/as-token" = { };
|
||||
"heisenbridge/hs-token" = { };
|
||||
|
||||
# Matrix-hookshot
|
||||
"matrix-hookshot/as-token" = { };
|
||||
"matrix-hookshot/hs-token" = { };
|
||||
|
||||
# Nextcloud
|
||||
"nextcloud/tlater" = {
|
||||
owner = "nextcloud";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue