about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--modules/services/matrix-homeserver.nix216
-rw-r--r--systems/cobalt/default.nix6
-rw-r--r--systems/cobalt/secrets/secrets.yaml13
3 files changed, 103 insertions, 132 deletions
diff --git a/modules/services/matrix-homeserver.nix b/modules/services/matrix-homeserver.nix
index 6af8f7f..6089b12 100644
--- a/modules/services/matrix-homeserver.nix
+++ b/modules/services/matrix-homeserver.nix
@@ -1,15 +1,12 @@
-{ config, lib, ... }:
+{ config, lib, pkgs, ... }:
 
 with lib;
 let
   cfg = config.modules.services.matrix-homeserver;
 
-  database = {
-    connection_string = "postgres:///dendrite?host=/run/postgresql";
-    max_open_conns = 100;
-    max_idle_conns = 5;
-    conn_max_lifetime = -1;
-  };
+  httpPort = 8008;
+  slidingSyncPort = 8009;
+  metricsPort = 8010;
 in
 {
   imports = [
@@ -28,148 +25,116 @@ in
     };
     secrets = {
       matrix-server-key = mkOption { type = types.str; description = "path to the server key"; };
+      matrix-shared-secret = mkOption { type = types.str; description = "path to the registration shared secret"; };
       dendrite-envs = mkOption { type = types.nullOr types.str; description = "path for the environment file to source"; };
+      extra-config-path = mkOption { type = types.nullOr types.str; description = "path to the extra configuration file to source"; };
       sliding-sync-secret = mkOption { type = types.nullOr types.str; description = "path to the sliding sync secret"; };
     };
   };
 
   config = mkIf cfg.enable {
-    # Adapted from Mic92/dotfiles, (C) 2021 Jörg Thalheim (MIT)
-    services.dendrite = {
+    services.matrix-synapse = {
       enable = true;
+      withJemalloc = true;
+      dataDir = "/var/lib/matrix-synapse";
       settings = {
-        global = {
-          server_name = cfg.domain;
-          # `private_key` has the type `path`
-          # prefix a `/` to make `path` happy
-          private_key = "/$CREDENTIALS_DIRECTORY/matrix-server-key";
-          jetstream.storage_path = "/var/lib/dendrite/jetstream";
-          trusted_third_party_id_servers = [
-            "matrix.org"
-            "vector.im"
-          ];
-          metrics.enabled = true;
+        server_name = cfg.domain;
+        public_baseurl = "https://${cfg.realHost}";
+
+        signing_key_path = cfg.secrets.matrix-server-key;
+
+        allow_guest_access = false;
+        enable_registration = false;
+        # registration_requires_token = true;
+        registration_shared_secret_path = cfg.secrets.matrix-shared-secret;
+
+        enable_metrics = true;
+        url_preview_enabled = true;
+
+        database = {
+          name = "psycopg2";
+          args.password = "synapse";
         };
-        logging = [
+
+        listeners = [
+          {
+            port = httpPort;
+            resources = [
+              {
+                compress = true;
+                names = [ "client" ];
+              }
+              {
+                compress = false;
+                names = [ "federation" ];
+              }
+            ];
+            type = "http";
+            tls = false;
+            x_forwarded = true;
+          }
           {
-            type = "std";
-            level = "info"; # "warn" on public release
+            port = metricsPort;
+            resources = [{
+              compress = false;
+              names = [ "metrics" ];
+            }];
+            type = "metrics";
+            tls = false;
           }
         ];
-        app_service_api = {
-          inherit database;
-          config_files = [ ];
-        };
-        client_api = {
-          registration_disabled = true;
-          rate_limiting.enabled = false;
-          rate_limiting.exempt_user_ids = [
-            "@abuse:${cfg.domain}"
-          ];
-          # registration_shared_secret = ""; # Initially set this option to configure the admin user.
-        } // optionalAttrs cfg.turn.enable {
-          turn = {
-            turn_user_lifetime = "24h";
-            turn_uris = [
-              "turns:${cfg.turn.domain}?transport=udp"
-              "turns:${cfg.turn.domain}?transport=tcp"
-              "turn:${cfg.turn.domain}?transport=udp"
-              "turn:${cfg.turn.domain}?transport=tcp"
-            ];
-            turn_shared_secret = cfg.turn.shared_secret;
+
+        trusted_key_servers = [{
+          server_name = "matrix.org";
+          verify_keys = {
+            "ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
           };
+        }];
+        # Yes, we want to use matrix.org as our trusted key server
+        suppress_key_server_warning = true;
+      } // optionalAttrs (cfg.turn.enable) {
+        turn_uris = [
+          "turns:${cfg.turn.domain}?transport=udp"
+          "turns:${cfg.turn.domain}?transport=tcp"
+          "turn:${cfg.turn.domain}?transport=udp"
+          "turn:${cfg.turn.domain}?transport=tcp"
+        ];
+      };
+
+      sliding-sync = {
+        enable = true;
+        createDatabase = true;
+        settings = {
+          SYNCV3_SERVER = "https://${cfg.realHost}";
+          SYNCV3_BINDADDR = "[::1]:${toString slidingSyncPort}";
         };
-        media_api = {
-          inherit database;
-          dynamic_thumbnails = true;
-        };
-        room_server = {
-          inherit database;
-        };
-        push_server = {
-          inherit database;
-        };
-        mscs = {
-          inherit database;
-          mscs = [ "msc2836" "msc2946" ];
-        };
-        sync_api = {
-          inherit database;
-          real_ip_header = "X-Real-IP";
-          # The NixOS option is 'enable', which doesn't exist in Dendrite.
-          search.enabled = true;
-        };
-        key_server = {
-          inherit database;
-        };
-        federation_api = {
-          inherit database;
-          key_perspectives = [
-            {
-              server_name = "matrix.org";
-              keys = [
-                {
-                  key_id = "ed25519:auto";
-                  public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
-                }
-                {
-                  key_id = "ed25519:a_RXGa";
-                  public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ";
-                }
-              ];
-            }
-          ];
-          prefer_direct_fetch = false;
-        };
-        user_api = {
-          account_database = database;
-          device_database = database;
-        };
+        environmentFile = cfg.secrets.sliding-sync-secret;
       };
-      loadCredential = [ "matrix-server-key:${cfg.secrets.matrix-server-key}" ];
-    } // optionalAttrs (cfg.secrets.dendrite-envs != null) {
-      environmentFile = cfg.secrets.dendrite-envs;
     };
-
+    ###################################### SYNAPSE END ##############################
+    # Adapted from Mic92/dotfiles, (C) 2021 Jörg Thalheim (MIT)
     services.prometheus.scrapeConfigs = [
       {
-        job_name = "dendrite";
+        job_name = "synapse";
+        metrics_path = "/_synapse/metrics";
         static_configs = [{
-          targets = [ "127.0.0.1:${toString config.services.dendrite.httpPort}" ];
+          targets = [ "127.0.0.1:${toString metricsPort}" ];
         }];
       }
     ];
 
-    systemd.services.dendrite = {
-      after = [ "postgresql.service" ];
-    };
-
     environment.persistence."/persist".directories = [
-      "/var/lib/private/dendrite"
+      "/var/lib/matrix-synapse"
     ];
 
-    services.sliding-sync = {
-      enable = true;
-      server = "https://${cfg.realHost}";
-      bindAddr = "[::1]:8009";
-      db = "postgres:///syncv3?host=/run/postgresql";
-      secret = cfg.secrets.sliding-sync-secret;
-      after = [ "dendrite.service" ];
-    };
-
     services.postgresql.enable = true;
-    services.postgresql.ensureDatabases = [ "dendrite" "syncv3" ];
-    services.postgresql.ensureUsers = [
-      {
-        name = "dendrite";
-        ensurePermissions."DATABASE dendrite" = "ALL PRIVILEGES";
-      }
-      {
-        name = "sliding-sync";
-        ensurePermissions."DATABASE syncv3" = "ALL PRIVILEGES";
-      }
-    ];
-
+    services.postgresql.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.nginx.virtualHosts.${cfg.realHost} = {
       forceSSL = true;
       useACMEHost = cfg.domain;
@@ -186,9 +151,8 @@ in
         proxy_read_timeout 600;
         client_max_body_size 50M;
       '';
-      locations."/_matrix".proxyPass = "http://[::1]:${toString config.services.dendrite.httpPort}";
-      locations."/_dendrite".proxyPass = "http://[::1]:${toString config.services.dendrite.httpPort}";
-      locations."/_synapse".proxyPass = "http://[::1]:${toString config.services.dendrite.httpPort}";
+      locations."/_matrix".proxyPass = "http://[::1]:${toString httpPort}";
+      locations."/_synapse".proxyPass = "http://[::1]:${toString httpPort}";
     };
 
     services.nginx.virtualHosts.${cfg.domain} =
@@ -223,7 +187,7 @@ in
     services.nginx.virtualHosts.${cfg.slidingSyncHost} = {
       forceSSL = true;
       useACMEHost = cfg.domain;
-      locations."/".proxyPass = "http://${config.services.sliding-sync.bindAddr}";
+      locations."/".proxyPass = "http://${config.services.matrix-synapse.sliding-sync.settings.SYNCV3_BINDADDR}";
     };
 
     networking.firewall.allowedTCPPorts = [ 443 8448 ];
diff --git a/systems/cobalt/default.nix b/systems/cobalt/default.nix
index bbd5261..3137581 100644
--- a/systems/cobalt/default.nix
+++ b/systems/cobalt/default.nix
@@ -157,7 +157,9 @@ in
   sops.secrets.acme-envs = {
     owner = "acme";
   };
-  sops.secrets.matrix-server-key = { };
+  sops.secrets.matrix-server-key = { owner = "matrix-synapse"; };
+  sops.secrets.matrix-shared-secret = { owner = "matrix-synapse"; };
+  sops.secrets.synapse-extra-config = { owner = "matrix-synapse"; };
   sops.secrets.dendrite-envs = { };
   sops.secrets.sliding-sync-secret = { };
   sops.secrets.mjolnir-password = { owner = "mjolnir"; };
@@ -266,6 +268,8 @@ in
       };
       secrets = {
         matrix-server-key = config.sops.secrets.matrix-server-key.path;
+        matrix-shared-secret = config.sops.secrets.matrix-shared-secret.path;
+        extra-config-path = config.sops.secrets.synapse-extra-config;
         dendrite-envs = config.sops.secrets.dendrite-envs.path;
         sliding-sync-secret = config.sops.secrets.sliding-sync-secret.path;
       };
diff --git a/systems/cobalt/secrets/secrets.yaml b/systems/cobalt/secrets/secrets.yaml
index b40573d..3079847 100644
--- a/systems/cobalt/secrets/secrets.yaml
+++ b/systems/cobalt/secrets/secrets.yaml
@@ -2,11 +2,14 @@ root-password: ENC[AES256_GCM,data:utvaJtoAN+9CSmnEd86OjdMB5QFWq/ICm0cv6F26QAdBa
 sefidel-password: ENC[AES256_GCM,data:i3fLsgHXIogbPh95k7EPXs9rzfrl617lDqwXktMd/buy5MhUfgl6lNftayeIhIihqmZP4Fu0r7m5s6DYvpfpyvK22Y/Yvib57w==,iv:u9iZ+261lh3ckJubH9iD2iFCAJhUB8ca2VhFYvrHwzA=,tag:4j7j61aOu9zFomU4AS5ThA==,type:str]
 borg-cobalt-rolling-pass: ENC[AES256_GCM,data:sR1V7JkNN5AmXINQYoqpdxFJ7wjcVeHKzYMV8/dAMQ==,iv:CXVMkN4wQi0khfxG8J0a8ZFCwn5Ynh4M1GIaKTY70Bw=,tag:8naCtTu3mlzPI5FKtVmDvg==,type:str]
 acme-envs: ENC[AES256_GCM,data:9IvoY1E2VLikZgPcNnEl2e33SMgLOJsX7aVTEbld1ggl8Z77a2iau17d/ZLWs0+u,iv:gr2iHuYmtZp2eWhX0E0OKolIn/Nm5+9hJqFTYZagV4c=,tag:9mqUFzqe8+3T+Nwbu5V0Fg==,type:str]
-matrix-server-key: ENC[AES256_GCM,data:MsPH8g0bc0cY+k5XvVIyi1hDpX2up7+noU9P4Dfm3Z9f1eXv7SaJhlRnR40qrk4sQN1uG0R/ro7S2z9EswX0iZx10PfjWF8Igrc9w9b2+EM/gb0O3dGskPAnDrm9JYh+gF6SsqmwJUEYh+Lx1EfuGMTWpnXZjLrimIWCfmz/1qxJECQds/aQwuA=,iv:B8yzXZ1IUVVvxFQ0MzzS5LSHZXQirnXiLoOru4S2H78=,tag:TNp1Y3C/iYgq5itqXGIt/g==,type:str]
+dendrite-matrix-server-key: ENC[AES256_GCM,data:ZzNjc/olciXQoXiYuHeZOeFP81GEb6FYIugHuPqCY5yXuJk+nQ4tNdk4nIBAkNXCeoMne4I7fBWraZnxz4PRGNLNutz2CGyutKsX54lFNJkEgl7JahVJGBI4mw+InwWEZwPliOEzs6jzZDjmd8IBuPklrj2z5UfGFHyMH2fXmMq8Yw5jXg4na0s=,iv:zE6zGfbN3V+kkkWxOf5XJgvROfL/bf25CARXVDGoK5A=,tag:ADM7BWbRp/rxMU/ikSZp+g==,type:str]
+matrix-server-key: ENC[AES256_GCM,data:gv1zTWRNqmpB/WtPGwYahm9BnCNNsuzKN5oMTnkv1x34jujznYFjgETL26SbSo68j1y2X712Mn9434Y=,iv:hYUo3VK8eDp873ddXB3LWjifM4oeqv/sDSZqPW8Ieq0=,tag:6OXja0TndNNwIeeGjhkJJA==,type:str]
+matrix-shared-secret: ENC[AES256_GCM,data:Xv9pOMA/kUJUrYxdXRA7NTrbkFvVsA==,iv:J3rZJGJ1cQPyhBK5lcd04dv2cGbhAvjg9IEQeXU+K/U=,tag:3YD3/MMUsVPnbW3ZUuf11Q==,type:str]
+synapse-extra-config: ENC[AES256_GCM,data:bJh9nMzZvP36Uwe7x03MLEk2N+FKq2V2YAFJT43vhMQ/XkvdN9yAeWhlxPGNEtl2wcMpCLnqbVAtfhJVI4VI5hGnue5HZz4Q51lbVQr2ZwzWuU6I25mY,iv:2qJuuyBlwgSWx5dkxGDbHhTW7ajI68lPgrvjdHmNTZ8=,tag:xRM6XGlitvcf+MrxBQ9GDw==,type:str]
 mjolnir-password: ENC[AES256_GCM,data:dyM2VVxn1PFRXy5dgfvq3EuWyGDhDZvJOd1sTnKE5q0Arv1y,iv:DD80um8QXLybj1w4ZsxPbv3+s2NrQfpPDAEpkztkMFo=,tag:3ZEJ7V+ICh2Ip5gZt06zjA==,type:str]
 mautrix-telegram-envs: ENC[AES256_GCM,data:hDfEI6tshgPHn/yPHkqO9/VZnB/vTnuyopVm2/0CKoWska66UXOHbXwvO6UXXUZldzkvKe6min3O9xjEGBC+SZdLWmfi6AxJvoKnmU2MzufNkrDG4k0turK7LwwVnm8ADZd9tEII+P3h42t78jhkgerailjP1rtVKleAZpr+ioRGhCTAE6tVWnhV4jveUwNkml+0AhMc3aY0N2PLvedw8p/jsX6Yujn2baKc7HOkvAasctqq/p8kdiTZCA+ASIVC15iR+KtGu2V7vXjDuzYU7Xv7+RbXN7rUTCBIJwyc3XxpwOmD46XR+/2iSZ3nL0PmDftbIEaA9LatjUap7mRFOwX5JruAl1XxAGdG965HZFyTHp1UggjjWvoHQmyb1xJXD5ZE+EU8obkFV0N1o7Q4XIF6/REz9+01JrOd1F5GxjoAo29JV+1lhdxGykrFcA63VLsXdsUgZflWH7Rxol2nOMI5t88+zohYJ5OpeLlRD0gVaX8dvgSzvzmZaNxASW+9tHOQBSzkZsM6jEon6ZXeAa0oh/ee+W82jHhe/ohlj0UV7TtpW/QWs3NR3mv1x41TMBawnVQ7sb9UH/sbdbajJYEAkSD/32ETSjXiQJsmhGEj5kRBNAQA16s1o0M24+UnpHo71jqQnRQpOUtFhLQqakOWvSdM4KgIXExc87Fkw+bQxLtpIup+T4WpJkCe5f5rB/jHvob33oitzjS1mam9UTtzwQjTuR/P4V8IORygDHlcq8W2PtDhWOdgtWI9cfIlqIIgu6+7Rg4+1dq5aw8j06eWrNH2NElPMji0opN+onT3VflgwGPXHlemId20Z2TXNuE6LlnUhyyxdh0rw3tVuCDcodzj4HfXk9mbjlTufyGKY41K/A6QTotiHANojizuTyulyjI3Gx1Wvzv8+Ib84SZGl9ZSsg7g6Ig5U12IJhNtZ/vMj8MHpRjxnyRmZ4jsQi9UctDKrhHjulD1WJyhBveoEv8L79c6e0xZYAwkSlxvdaOPK3OMGbbtbH8vy7WYXSwHZomwJ7BrsrQ/5lWav2xXzgM7ASnEg/rKBPr9YQYOBA==,iv:K2qdi99cjom4mzcNH26qqX3gQNSvZzuAh9QY4zmZv9I=,tag:e9/4biFz6mVsGHV/YOA1jg==,type:str]
 dendrite-envs: ENC[AES256_GCM,data:67FnrGQUZWFfHAoUM/idTZlBX7aek3fbPkswB9+3pjLNQuXpIWYoa2vpdGt7zec2n9o9z0V3LdlkookjS95aPpZmKYwPaKkH2L7Jaxw=,iv:c4lEReLizcQeTTiG7cJwd+2sBH+EKBGycKeoDgJ/394=,tag:zBBxIcXn+8Q90BkPidltfQ==,type:str]
-sliding-sync-secret: ENC[AES256_GCM,data:lNIlUtNbXw1/w44m7RwqmvOTmc4MYfag7Nvo0izTM6Al7eOZXjEXGgfr7b4PB3QNewghN4LEEj1ae8HqpivT/w==,iv:Qw2XLjYp3/78OuEakUDJ0Sp3fmjw36IJTg8UKTZ7UEU=,tag:tp3gACPEZNMzj+aDP3Ax4A==,type:str]
+sliding-sync-secret: ENC[AES256_GCM,data:mBgQZ/SVRpvELrqwCzjxJETxDSj5gw+CcIb3rk/vjQ3j8tvjt4Z2GbuE6fwQ1CXhHKRL7kYOLn8ec7rgaMTr6me2pRcI+Sz/40IKUvlE,iv:NQvkJ4gjmOtfOyb8ciOudNHBYOytizNg6K6IhVxhE28=,tag:LNhd6MgUOPBHY9qK/tDBjA==,type:str]
 turn-secret: ENC[AES256_GCM,data:JA5/BlGwH6yIjYsFZGa8Nm8XVbOBKpre+NFybniOtlmbSx89ldKBvuqF2ZoPltJS+vzQ/+wxM/VorhF7M+s4jA==,iv:rK5SFj4VOzgfaP/LIzWTVFyCBmklGMSyd9iWbet2CVc=,tag:QycYCHH72bMMX5UubDHTlg==,type:str]
 openldap-admin-key: ENC[AES256_GCM,data:WBBDPFDW6Q4sJ5+/pK8kAe6iFgJ8gGgi3eCVNvZB,iv:1rnmhu29UGsXLxD9Ptbv7P67EAYgKVk1dlkM6p0L4vA=,tag:yNRrHMI2yT8Oo7qkwxSeUg==,type:str]
 sefidel-imap-pass: ENC[AES256_GCM,data:rx9hZb+BARs9gB+XLLRMLWDSx67KqkKB1/4nOOtU9i56uagMprFEeDnh8pEaioZbNlqjJRO8kWTBBvWZ,iv:WxKLp0VmwfxVFZt9cnZUbp4wn5WEHubImp8fQy2bXyg=,tag:Vzh0Ntz8iFaSIEf2wjbOKg==,type:str]
@@ -38,8 +41,8 @@ sops:
             cUpBZ01CMEFjNnNuWjlYejVKajkwcGMKehqYCZP0zZHDTfJrC/5LYiE/3doa0OiM
             OKXhOuUX8HF8RfkyiOSMpntxuNX2jSvd9sQRYnHkUvgm793+IuQjrg==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2023-08-01T16:24:22Z"
-    mac: ENC[AES256_GCM,data:2kp7TYn1C+uo0gtnAvLglhhKxe3j/rmAZnN1GcKnA4/RTCunef6zlGup+g+Yogv8z+wktmN+WGsBFhuu51o027paTlExlMsFwuvb7FOVNGPxyksDnAHJc9SBQYYMKtqUrVqPKxm8cfVmKIV+vYoW+C3SFL11XyOCtxjaI+R4IXc=,iv:4uPxt+CzDyMwHSEGZncfOH+4wN7w20Pj2lV0cTBhGgk=,tag:Je2fzTGcrX93xNAFjdL1Lg==,type:str]
+    lastmodified: "2023-11-05T09:09:41Z"
+    mac: ENC[AES256_GCM,data:uniRzzxp0Yr999O9/z6plc59MRqDKyKpkORRgVD3HYRfXmMP8nKUrKej9Cttr9W81RRjzBSnse5/YWYLWROAhnxuLFpcJTiTRrDHDiH+NKcpgMwAkSnF8mS/qKCn4ewcXRCaA2blA71v0OiPoCrhmRbJvezNV85Fuzm2VMQZejU=,iv:23TwdmuNOR2Dt2mn4HeWm7izbJ5KQ6ODXFa+TZkPWyE=,tag:3gl5E52v4iRjOkvwfgp4cw==,type:str]
     pgp: []
     unencrypted_suffix: _unencrypted
-    version: 3.7.3
+    version: 3.8.1