506 lines
16 KiB
Nix
506 lines
16 KiB
Nix
{ pkgs, lib, config, ... }:
|
|
let
|
|
hostname = "matrix";
|
|
fqdn = "${hostname}.cloonar.com";
|
|
baseUrl = "https://${fqdn}";
|
|
clientConfig."m.homeserver".base_url = baseUrl;
|
|
serverConfig."m.server" = "${fqdn}:443";
|
|
mkWellKnown = data: ''
|
|
default_type application/json;
|
|
add_header Access-Control-Allow-Origin *;
|
|
return 200 '${builtins.toJSON data}';
|
|
'';
|
|
in {
|
|
sops.secrets.matrix-shared-secret = {
|
|
};
|
|
sops.secrets.dendrite-private-key = {
|
|
};
|
|
|
|
services.postgresql = {
|
|
enable = true;
|
|
ensureDatabases = [ "dendrite" ];
|
|
ensureUsers = [
|
|
{
|
|
name = "dendrite";
|
|
}
|
|
];
|
|
};
|
|
|
|
services.nginx.virtualHosts."element.cloonar.com" = {
|
|
forceSSL = true;
|
|
enableACME = true;
|
|
acmeRoot = null;
|
|
root = pkgs.element-web.override {
|
|
conf = {
|
|
default_theme = "dark";
|
|
default_server_config = {
|
|
"m.homeserver" = {
|
|
base_url = "https://matrix.cloonar.com";
|
|
server_name = "cloonar.com";
|
|
};
|
|
};
|
|
disable_custom_urls = true;
|
|
disable_3pid_login = true;
|
|
default_country_code = "AT";
|
|
};
|
|
};
|
|
};
|
|
|
|
services.postgresqlBackup.enable = true;
|
|
services.postgresqlBackup.databases = [ "dendrite" ];
|
|
|
|
services.nginx.virtualHosts."${fqdn}" = {
|
|
forceSSL = true;
|
|
enableACME = true;
|
|
acmeRoot = null;
|
|
locations."/".extraConfig = ''
|
|
return 404;
|
|
'';
|
|
locations."/_dendrite".proxyPass = "http://[::1]:8008";
|
|
locations."/_matrix".proxyPass = "http://[::1]:8008";
|
|
locations."/_synapse/client".proxyPass = "http://[::1]:8008";
|
|
};
|
|
|
|
|
|
services.dendrite = {
|
|
enable = true;
|
|
settings = {
|
|
global = {
|
|
server_name = "cloonar.com";
|
|
private_key = "$CREDENTIALS_DIRECTORY/private_key";
|
|
database.connection_string = "postgresql:///dendrite?host=/run/postgresql";
|
|
};
|
|
client_api.registration_shared_secret = "$REGISTRATION_SHARED_SECRET";
|
|
app_service_api.config_files = [
|
|
"$CREDENTIALS_DIRECTORY/whatsapp_registration"
|
|
"$CREDENTIALS_DIRECTORY/signal_registration"
|
|
"$CREDENTIALS_DIRECTORY/discord_registration"
|
|
];
|
|
app_service_api.database.connection_string = "";
|
|
federation_api.database.connection_string = "";
|
|
key_server.database.connection_string = "";
|
|
relay_api.database.connection_string = "";
|
|
media_api.database.connection_string = "";
|
|
room_server.database.connection_string = "";
|
|
sync_api.database.connection_string = "";
|
|
user_api.account_database.connection_string = "";
|
|
user_api.device_database.connection_string = "";
|
|
mscs.database.connection_string = "";
|
|
};
|
|
loadCredential = [
|
|
"private_key:${config.sops.secrets.dendrite-private-key.path}"
|
|
"whatsapp_registration:/var/lib/mautrix-whatsapp/whatsapp-registration.yaml"
|
|
"signal_registration:/var/lib/mautrix-signal/signal-registration.yaml"
|
|
"discord_registration:/var/lib/mautrix-discord/discord-registration.yaml"
|
|
];
|
|
environmentFile = config.sops.secrets.matrix-shared-secret.path;
|
|
};
|
|
|
|
users.users.mautrix-whatsapp = {
|
|
isSystemUser = true;
|
|
group = "mautrix-whatsapp";
|
|
home = "/var/lib/mautrix-whatsapp";
|
|
description = "Mautrix-WhatsApp bridge user";
|
|
};
|
|
|
|
users.groups.mautrix-whatsapp = {};
|
|
systemd.services.mautrix-whatsapp = let
|
|
dataDir = "/var/lib/mautrix-whatsapp";
|
|
registrationFile = "${dataDir}/whatsapp-registration.yaml";
|
|
settingsFile = "${dataDir}/config.json";
|
|
settingsFileUnsubstituted = settingsFormat.generate "mautrix-whatsapp-config-unsubstituted.json" defaultConfig;
|
|
settingsFormat = pkgs.formats.json {};
|
|
appservicePort = 29318;
|
|
defaultConfig = {
|
|
homeserver = {
|
|
address = "http://[::1]:8008";
|
|
domain = "cloonar.com";
|
|
};
|
|
appservice = {
|
|
hostname = "[::]";
|
|
port = appservicePort;
|
|
database.type = "sqlite3";
|
|
database.uri = "${dataDir}/mautrix-whatsapp.db";
|
|
id = "whatsapp";
|
|
bot.username = "whatsappbot";
|
|
bot.displayname = "WhatsApp Bridge Bot";
|
|
as_token = "";
|
|
hs_token = "";
|
|
};
|
|
bridge = {
|
|
username_template = "whatsapp_{{.}}";
|
|
displayname_template = "{{if .BusinessName}}{{.BusinessName}}{{else if .PushName}}{{.PushName}}{{else}}{{.JID}}{{end}} (WA)";
|
|
double_puppet_server_map = {};
|
|
login_shared_secret_map = {};
|
|
command_prefix = "!wa";
|
|
permissions."*" = "relay";
|
|
permissions."cloonar.com" = "user";
|
|
relay.enabled = true;
|
|
history_sync.request_full_sync = false;
|
|
encryption = {
|
|
allow = true;
|
|
default = true;
|
|
require = true;
|
|
};
|
|
};
|
|
logging = {
|
|
min_level = "info";
|
|
writers = lib.singleton {
|
|
type = "stdout";
|
|
format = "pretty-colored";
|
|
time_format = " ";
|
|
};
|
|
};
|
|
};
|
|
in {
|
|
description = "Mautrix-WhatsApp Service - A WhatsApp bridge for Matrix";
|
|
|
|
wantedBy = ["multi-user.target"];
|
|
wants = ["network-online.target"];
|
|
after = ["network-online.target"];
|
|
|
|
preStart = ''
|
|
test -f '${settingsFile}' && rm -f '${settingsFile}'
|
|
old_umask=$(umask)
|
|
umask 0177
|
|
${pkgs.envsubst}/bin/envsubst \
|
|
-o '${settingsFile}' \
|
|
-i '${settingsFileUnsubstituted}'
|
|
umask $old_umask
|
|
|
|
# generate the appservice's registration file if absent
|
|
if [ ! -f '${registrationFile}' ]; then
|
|
${pkgs.mautrix-whatsapp}/bin/mautrix-whatsapp \
|
|
--generate-registration \
|
|
--config='${settingsFile}' \
|
|
--registration='${registrationFile}'
|
|
fi
|
|
chmod 640 ${registrationFile}
|
|
|
|
umask 0177
|
|
${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token
|
|
| .[0].appservice.hs_token = .[1].hs_token
|
|
| .[0]' '${settingsFile}' '${registrationFile}' \
|
|
> '${settingsFile}.tmp'
|
|
mv '${settingsFile}.tmp' '${settingsFile}'
|
|
umask $old_umask
|
|
'';
|
|
|
|
serviceConfig = {
|
|
User = "mautrix-whatsapp";
|
|
Group = "mautrix-whatsapp";
|
|
# EnvironmentFile = cfg.environmentFile;
|
|
StateDirectory = baseNameOf dataDir;
|
|
WorkingDirectory = dataDir;
|
|
ExecStart = ''
|
|
${pkgs.mautrix-whatsapp}/bin/mautrix-whatsapp \
|
|
--config='${settingsFile}' \
|
|
--registration='${registrationFile}' \
|
|
--ignore-unsupported-server
|
|
'';
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
NoNewPrivileges = true;
|
|
PrivateDevices = true;
|
|
PrivateTmp = true;
|
|
PrivateUsers = true;
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectSystem = "strict";
|
|
Restart = "on-failure";
|
|
RestartSec = "30s";
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
SystemCallArchitectures = "native";
|
|
SystemCallErrorNumber = "EPERM";
|
|
SystemCallFilter = ["@system-service"];
|
|
Type = "simple";
|
|
UMask = 0027;
|
|
};
|
|
restartTriggers = [settingsFileUnsubstituted];
|
|
};
|
|
|
|
users.users.mautrix-signal = {
|
|
isSystemUser = true;
|
|
group = "mautrix-signal";
|
|
home = "/var/lib/mautrix-signal";
|
|
description = "Mautrix-Signal bridge user";
|
|
};
|
|
|
|
users.groups.mautrix-signal = {};
|
|
systemd.services.mautrix-signal = let
|
|
pkgswithsignal = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/fd698a4ab779fb7fb95425f1b56974ba9c2fa16c.tar.gz") {
|
|
config = {
|
|
permittedInsecurePackages = [
|
|
# needed for matrix
|
|
"olm-3.2.16"
|
|
];
|
|
};
|
|
};
|
|
dataDir = "/var/lib/mautrix-signal";
|
|
registrationFile = "${dataDir}/signal-registration.yaml";
|
|
settingsFile = "${dataDir}/config.json";
|
|
settingsFileUnsubstituted = settingsFormat.generate "mautrix-signal-config-unsubstituted.json" defaultConfig;
|
|
settingsFormat = pkgs.formats.json {};
|
|
appservicePort = 29328;
|
|
defaultConfig = {
|
|
homeserver = {
|
|
address = "http://[::1]:8008";
|
|
domain = "cloonar.com";
|
|
};
|
|
appservice = {
|
|
hostname = "[::]";
|
|
port = appservicePort;
|
|
database.type = "sqlite3";
|
|
database.uri = "file:${dataDir}/mautrix-signal.db?_txlock=immediate";
|
|
id = "signal";
|
|
bot = {
|
|
username = "signalbot";
|
|
displayname = "Signal Bridge Bot";
|
|
};
|
|
as_token = "";
|
|
hs_token = "";
|
|
};
|
|
bridge = {
|
|
username_template = "signal_{{.}}";
|
|
displayname_template = "{{or .ProfileName .PhoneNumber \"Unknown user\"}}";
|
|
double_puppet_server_map = { };
|
|
login_shared_secret_map = { };
|
|
command_prefix = "!signal";
|
|
permissions."*" = "relay";
|
|
permissions."cloonar.com" = "user";
|
|
relay.enabled = true;
|
|
encryption = {
|
|
allow = true;
|
|
default = true;
|
|
require = true;
|
|
};
|
|
};
|
|
logging = {
|
|
min_level = "info";
|
|
writers = lib.singleton {
|
|
type = "stdout";
|
|
format = "pretty-colored";
|
|
time_format = " ";
|
|
};
|
|
};
|
|
};
|
|
in {
|
|
description = "Mautrix-Signal Service - A Signal bridge for Matrix";
|
|
|
|
wantedBy = ["multi-user.target"];
|
|
wants = ["network-online.target"];
|
|
after = ["network-online.target"];
|
|
|
|
preStart = ''
|
|
test -f '${settingsFile}' && rm -f '${settingsFile}'
|
|
old_umask=$(umask)
|
|
umask 0177
|
|
${pkgs.envsubst}/bin/envsubst \
|
|
-o '${settingsFile}' \
|
|
-i '${settingsFileUnsubstituted}'
|
|
umask $old_umask
|
|
|
|
# generate the appservice's registration file if absent
|
|
if [ ! -f '${registrationFile}' ]; then
|
|
${pkgswithsignal.mautrix-signal}/bin/mautrix-signal \
|
|
--generate-registration \
|
|
--config='${settingsFile}' \
|
|
--registration='${registrationFile}'
|
|
fi
|
|
chmod 640 ${registrationFile}
|
|
|
|
umask 0177
|
|
${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token
|
|
| .[0].appservice.hs_token = .[1].hs_token
|
|
| .[0]
|
|
| if env.MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET then .bridge.login_shared_secret_map.[.homeserver.domain] = env.MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET else . end' \
|
|
'${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
|
|
mv '${settingsFile}.tmp' '${settingsFile}'
|
|
umask $old_umask
|
|
'';
|
|
|
|
serviceConfig = {
|
|
User = "mautrix-signal";
|
|
Group = "mautrix-signal";
|
|
# EnvironmentFile = cfg.environmentFile;
|
|
StateDirectory = baseNameOf dataDir;
|
|
WorkingDirectory = dataDir;
|
|
ExecStart = ''
|
|
${pkgswithsignal.mautrix-signal}/bin/mautrix-signal \
|
|
--config='${settingsFile}' \
|
|
--registration='${registrationFile}' \
|
|
--ignore-unsupported-server
|
|
'';
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
NoNewPrivileges = true;
|
|
PrivateDevices = true;
|
|
PrivateTmp = true;
|
|
PrivateUsers = true;
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectSystem = "strict";
|
|
Restart = "on-failure";
|
|
RestartSec = "30s";
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
SystemCallArchitectures = "native";
|
|
SystemCallErrorNumber = "EPERM";
|
|
SystemCallFilter = ["@system-service"];
|
|
Type = "simple";
|
|
UMask = 0027;
|
|
};
|
|
restartTriggers = [settingsFileUnsubstituted];
|
|
};
|
|
|
|
|
|
users.users.mautrix-discord = {
|
|
isSystemUser = true;
|
|
group = "mautrix-discord";
|
|
home = "/var/lib/mautrix-discord";
|
|
description = "Mautrix-Discord bridge user";
|
|
};
|
|
|
|
users.groups.mautrix-discord = {};
|
|
systemd.services.mautrix-discord = let
|
|
pkgswithdiscord = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/5ed627539ac84809c78b2dd6d26a5cebeb5ae269.tar.gz") {
|
|
config = {
|
|
permittedInsecurePackages = [
|
|
# needed for matrix
|
|
"olm-3.2.16"
|
|
];
|
|
};
|
|
};
|
|
dataDir = "/var/lib/mautrix-discord";
|
|
registrationFile = "${dataDir}/discord-registration.yaml";
|
|
settingsFile = "${dataDir}/config.json";
|
|
settingsFileUnsubstituted = settingsFormat.generate "mautrix-discord-config-unsubstituted.json" defaultConfig;
|
|
settingsFormat = pkgs.formats.json {};
|
|
appservicePort = 29329;
|
|
defaultConfig = {
|
|
homeserver = {
|
|
address = "http://[::1]:8008";
|
|
domain = "cloonar.com";
|
|
};
|
|
appservice = {
|
|
hostname = "[::]";
|
|
port = appservicePort;
|
|
database.type = "sqlite3";
|
|
database.uri = "file:${dataDir}/mautrix-discord.db?_txlock=immediate";
|
|
id = "discord";
|
|
bot = {
|
|
username = "discordbot";
|
|
displayname = "Discord Bridge Bot";
|
|
};
|
|
as_token = "";
|
|
hs_token = "";
|
|
};
|
|
bridge = {
|
|
username_template = "discord_{{.}}";
|
|
displayname_template = "{{or .ProfileName .PhoneNumber \"Unknown user\"}}";
|
|
double_puppet_server_map = { };
|
|
login_shared_secret_map = { };
|
|
command_prefix = "!discord";
|
|
permissions."*" = "relay";
|
|
permissions."cloonar.com" = "user";
|
|
relay.enabled = true;
|
|
encryption = {
|
|
allow = true;
|
|
default = true;
|
|
require = true;
|
|
};
|
|
};
|
|
logging = {
|
|
min_level = "info";
|
|
writers = lib.singleton {
|
|
type = "stdout";
|
|
format = "pretty-colored";
|
|
time_format = " ";
|
|
};
|
|
};
|
|
};
|
|
in {
|
|
description = "Mautrix-Discord Service - A Discord bridge for Matrix";
|
|
|
|
wantedBy = ["multi-user.target"];
|
|
wants = ["network-online.target"];
|
|
after = ["network-online.target"];
|
|
|
|
preStart = ''
|
|
test -f '${settingsFile}' && rm -f '${settingsFile}'
|
|
old_umask=$(umask)
|
|
umask 0177
|
|
${pkgs.envsubst}/bin/envsubst \
|
|
-o '${settingsFile}' \
|
|
-i '${settingsFileUnsubstituted}'
|
|
umask $old_umask
|
|
|
|
# generate the appservice's registration file if absent
|
|
if [ ! -f '${registrationFile}' ]; then
|
|
${pkgswithdiscord.mautrix-discord}/bin/mautrix-discord \
|
|
--generate-registration \
|
|
--config='${settingsFile}' \
|
|
--registration='${registrationFile}'
|
|
fi
|
|
chmod 640 ${registrationFile}
|
|
|
|
umask 0177
|
|
${pkgs.yq}/bin/yq -s '.[0].appservice.as_token = .[1].as_token
|
|
| .[0].appservice.hs_token = .[1].hs_token
|
|
| .[0]
|
|
| if env.MAUTRIX_DISCORD_BRIDGE_LOGIN_SHARED_SECRET then .bridge.login_shared_secret_map.[.homeserver.domain] = env.MAUTRIX_DISCORD_BRIDGE_LOGIN_SHARED_SECRET else . end' \
|
|
'${settingsFile}' '${registrationFile}' > '${settingsFile}.tmp'
|
|
mv '${settingsFile}.tmp' '${settingsFile}'
|
|
umask $old_umask
|
|
'';
|
|
|
|
serviceConfig = {
|
|
User = "mautrix-discord";
|
|
Group = "mautrix-discord";
|
|
# EnvironmentFile = cfg.environmentFile;
|
|
StateDirectory = baseNameOf dataDir;
|
|
WorkingDirectory = dataDir;
|
|
ExecStart = ''
|
|
${pkgswithdiscord.mautrix-discord}/bin/mautrix-discord \
|
|
--config='${settingsFile}' \
|
|
--registration='${registrationFile}'
|
|
'';
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
NoNewPrivileges = true;
|
|
PrivateDevices = true;
|
|
PrivateTmp = true;
|
|
PrivateUsers = true;
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectSystem = "strict";
|
|
Restart = "on-failure";
|
|
RestartSec = "30s";
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
SystemCallArchitectures = "native";
|
|
SystemCallErrorNumber = "EPERM";
|
|
SystemCallFilter = ["@system-service"];
|
|
Type = "simple";
|
|
UMask = 0027;
|
|
};
|
|
restartTriggers = [settingsFileUnsubstituted];
|
|
};
|
|
}
|