This commit is contained in:
commit
95a533c876
451 changed files with 18255 additions and 0 deletions
151
modules/nixos/matrix-synapse/bridges.nix
Normal file
151
modules/nixos/matrix-synapse/bridges.nix
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
|
||||
mkMautrixBridgeOptions = name: pkgName: {
|
||||
enable = mkEnableOption "Mautrix-${name} for your Matrix-Synapse instance.";
|
||||
package = mkPackageOption pkgs pkgName { };
|
||||
admin = mkOption {
|
||||
type = types.str;
|
||||
description = "The user to give admin permissions to.";
|
||||
example = "@admin:example.com";
|
||||
};
|
||||
};
|
||||
|
||||
mkMautrixBridge = name: port: {
|
||||
environment.systemPackages = [ cfg.bridges.${name}.package ];
|
||||
|
||||
services."mautrix-${name}" = {
|
||||
enable = true;
|
||||
package = cfg.bridges.${name}.package;
|
||||
environmentFile = mkIf cfg.sops config.sops.templates."mautrix-${name}/env-file".path;
|
||||
settings = {
|
||||
bridge = {
|
||||
permissions = {
|
||||
"*" = "relay";
|
||||
"${cfg.settings.server_name}" = "user";
|
||||
"${cfg.bridges.${name}.admin}" = "admin";
|
||||
};
|
||||
};
|
||||
homeserver = {
|
||||
address = "http://localhost:${toString cfg.port}";
|
||||
domain = cfg.settings.server_name;
|
||||
};
|
||||
appservice = {
|
||||
address = "http://localhost:${toString port}";
|
||||
public_address = cfg.settings.public_baseurl;
|
||||
hostname = "localhost";
|
||||
inherit port;
|
||||
};
|
||||
provisioning.shared_secret = "$MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET";
|
||||
public_media = {
|
||||
enabled = false;
|
||||
signing_key = "$MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY";
|
||||
};
|
||||
direct_media = {
|
||||
enabled = false;
|
||||
server_key = "$MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY";
|
||||
};
|
||||
backfill = {
|
||||
enabled = true;
|
||||
};
|
||||
encryption = {
|
||||
allow = true;
|
||||
default = true;
|
||||
require = false;
|
||||
pickle_key = "$MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sops = mkIf cfg.sops (
|
||||
let
|
||||
owner = "mautrix-${name}";
|
||||
group = "mautrix-${name}";
|
||||
mode = "0400";
|
||||
in
|
||||
{
|
||||
secrets."mautrix-${name}/encryption-pickle-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
secrets."mautrix-${name}/provisioning-shared-secret" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
secrets."mautrix-${name}/public-media-signing-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
secrets."mautrix-${name}/direct-media-server-key" = {
|
||||
inherit owner group mode;
|
||||
};
|
||||
templates."mautrix-${name}/env-file" = {
|
||||
inherit owner group mode;
|
||||
content = ''
|
||||
MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${
|
||||
config.sops.placeholder."mautrix-${name}/encryption-pickle-key"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET=${
|
||||
config.sops.placeholder."mautrix-${name}/provisioning-shared-secret"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${
|
||||
config.sops.placeholder."mautrix-${name}/public-media-signing-key"
|
||||
}
|
||||
MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${
|
||||
config.sops.placeholder."mautrix-${name}/direct-media-server-key"
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
mkPackageOption
|
||||
toUpper
|
||||
types
|
||||
;
|
||||
|
||||
inherit (builtins) toString;
|
||||
in
|
||||
{
|
||||
options.services.matrix-synapse = {
|
||||
bridges = {
|
||||
whatsapp = mkMautrixBridgeOptions "WhatsApp" "mautrix-whatsapp";
|
||||
signal = mkMautrixBridgeOptions "Signal" "mautrix-signal";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfg.bridges.whatsapp.enable (mkMautrixBridge "whatsapp" 29318))
|
||||
(mkIf cfg.bridges.whatsapp.enable {
|
||||
services.mautrix-whatsapp = {
|
||||
settings = {
|
||||
network = {
|
||||
displayname_template = "{{or .BusinessName .PushName .Phone}} (WA)";
|
||||
history_sync.request_full_sync = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
(mkIf cfg.bridges.signal.enable (mkMautrixBridge "signal" 29328))
|
||||
(mkIf cfg.bridges.signal.enable {
|
||||
services.mautrix-signal = {
|
||||
settings = {
|
||||
network = {
|
||||
displayname_template = "{{or .ProfileName .PhoneNumber \"Unknown user\" }} (S)";
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
189
modules/nixos/matrix-synapse/default.nix
Normal file
189
modules/nixos/matrix-synapse/default.nix
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
baseUrl = "https://${cfg.settings.server_name}";
|
||||
|
||||
baseClientConfig = {
|
||||
"m.homeserver".base_url = baseUrl;
|
||||
"m.identity_server".base_url = "https://vector.im";
|
||||
};
|
||||
|
||||
livekitConfig = optionalAttrs config.services.livekit.enable {
|
||||
"org.matrix.msc3575.proxy".url = baseUrl;
|
||||
"org.matrix.msc4143.rtc_foci" = [
|
||||
{
|
||||
type = "livekit";
|
||||
livekit_service_url = baseUrl + "/livekit/jwt";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
clientConfig = baseClientConfig // livekitConfig;
|
||||
|
||||
serverConfig."m.server" = "${cfg.settings.server_name}:443";
|
||||
|
||||
mkWellKnown = data: ''
|
||||
default_type application/json;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
return 200 '${builtins.toJSON data}';
|
||||
'';
|
||||
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
optionalAttrs
|
||||
types
|
||||
;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./bridges.nix
|
||||
./livekit.nix
|
||||
];
|
||||
|
||||
options.services.matrix-synapse = {
|
||||
port = mkOption {
|
||||
type = types.nullOr types.port;
|
||||
default = 8008;
|
||||
description = ''
|
||||
The port to listen for HTTP(S) requests on (will be applied to a listener).
|
||||
'';
|
||||
};
|
||||
coturn = {
|
||||
enable = mkEnableOption "Coturn integration for Matrix Synapse.";
|
||||
realm = mkOption {
|
||||
type = types.str;
|
||||
default = "turn.${config.networking.domain}";
|
||||
description = "Realm for the coturn server used by Matrix Synapse.";
|
||||
};
|
||||
listening-port = mkOption {
|
||||
type = types.port;
|
||||
default = 3478;
|
||||
};
|
||||
tls-listening-port = mkOption {
|
||||
type = types.port;
|
||||
default = 5349;
|
||||
};
|
||||
alt-listening-port = mkOption {
|
||||
type = types.port;
|
||||
default = 3479;
|
||||
};
|
||||
alt-tls-listening-port = mkOption {
|
||||
type = types.port;
|
||||
default = 5350;
|
||||
};
|
||||
};
|
||||
sops = mkEnableOption "SOPS integration";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
initialScript = pkgs.writeText "synapse-init.sql" ''
|
||||
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
|
||||
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
|
||||
TEMPLATE template0
|
||||
LC_COLLATE = 'C'
|
||||
LC_CTYPE = 'C';
|
||||
'';
|
||||
};
|
||||
|
||||
services.matrix-synapse = mkMerge [
|
||||
{
|
||||
settings = {
|
||||
registration_shared_secret_path =
|
||||
mkIf cfg.sops
|
||||
config.sops.secrets."matrix/registration-shared-secret".path;
|
||||
server_name = config.networking.domain;
|
||||
public_baseurl = baseUrl;
|
||||
listeners = [
|
||||
{
|
||||
inherit (cfg) port;
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
resources = [
|
||||
{
|
||||
compress = true;
|
||||
names = [ "client" ];
|
||||
}
|
||||
{
|
||||
compress = false;
|
||||
names = [ "federation" ];
|
||||
}
|
||||
];
|
||||
tls = false;
|
||||
type = "http";
|
||||
x_forwarded = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
(mkIf cfg.coturn.enable {
|
||||
settings = {
|
||||
turn_uris = with cfg.coturn; [
|
||||
"turn:${realm}:${toString listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString tls-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString alt-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
|
||||
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
|
||||
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
|
||||
];
|
||||
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
|
||||
turn_user_lifetime = "1h";
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
environment.shellAliases = mkIf cfg.sops {
|
||||
register_new_matrix_user = "${cfg.package}/bin/register_new_matrix_user -k $(sudo cat ${cfg.settings.registration_shared_secret_path})";
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${cfg.settings.server_name}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
|
||||
locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
|
||||
|
||||
locations."/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
locations."/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
};
|
||||
|
||||
sops = mkIf cfg.sops {
|
||||
secrets = mkMerge [
|
||||
{
|
||||
"matrix/registration-shared-secret" = {
|
||||
owner = "matrix-synapse";
|
||||
group = "matrix-synapse";
|
||||
mode = "0400";
|
||||
};
|
||||
}
|
||||
(mkIf cfg.coturn.enable {
|
||||
"coturn/static-auth-secret" = {
|
||||
owner = "turnserver";
|
||||
group = "turnserver";
|
||||
mode = "0400";
|
||||
};
|
||||
})
|
||||
];
|
||||
templates = mkIf cfg.coturn.enable {
|
||||
"coturn/static-auth-secret.env" = {
|
||||
owner = "matrix-synapse";
|
||||
group = "matrix-synapse";
|
||||
mode = "0400";
|
||||
content = ''
|
||||
static-auth-secret=${config.sops.placeholder."coturn/static-auth-secret"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
61
modules/nixos/matrix-synapse/livekit.nix
Normal file
61
modules/nixos/matrix-synapse/livekit.nix
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse;
|
||||
domain = config.networking.domain;
|
||||
|
||||
inherit (lib) mkIf mkDefault;
|
||||
in
|
||||
{
|
||||
config = mkIf cfg.enable {
|
||||
services.livekit = {
|
||||
enable = true;
|
||||
settings.port = mkDefault 7880;
|
||||
settings.room.auto_create = mkDefault false;
|
||||
openFirewall = mkDefault true;
|
||||
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
|
||||
};
|
||||
|
||||
services.lk-jwt-service = {
|
||||
enable = true;
|
||||
port = mkDefault 8080;
|
||||
livekitUrl = "wss://${domain}/livekit/sfu";
|
||||
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
|
||||
};
|
||||
|
||||
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain;
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
"${domain}".locations = {
|
||||
"^~ /livekit/jwt/" = {
|
||||
priority = 400;
|
||||
proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/";
|
||||
};
|
||||
"^~ /livekit/sfu/" = {
|
||||
priority = 400;
|
||||
proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_send_timeout 120;
|
||||
proxy_read_timeout 120;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Accept-Encoding gzip;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sops = mkIf cfg.sops {
|
||||
secrets."livekit/key" = { };
|
||||
templates."livekit/key".content = ''
|
||||
API Secret: ${config.sops.placeholder."livekit/key"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue