summary refs log tree commit diff
path: root/host/Rory-nginx/services/matrix/synapse
diff options
context:
space:
mode:
Diffstat (limited to 'host/Rory-nginx/services/matrix/synapse')
-rwxr-xr-xhost/Rory-nginx/services/matrix/synapse/_synapse.monolith.nix212
-rw-r--r--host/Rory-nginx/services/matrix/synapse/caches.nix16
-rw-r--r--host/Rory-nginx/services/matrix/synapse/db.nix21
-rw-r--r--host/Rory-nginx/services/matrix/synapse/ratelimits.nix56
-rwxr-xr-xhost/Rory-nginx/services/matrix/synapse/synapse-main.nix233
5 files changed, 538 insertions, 0 deletions
diff --git a/host/Rory-nginx/services/matrix/synapse/_synapse.monolith.nix b/host/Rory-nginx/services/matrix/synapse/_synapse.monolith.nix
new file mode 100755
index 0000000..26c61a1
--- /dev/null
+++ b/host/Rory-nginx/services/matrix/synapse/_synapse.monolith.nix
@@ -0,0 +1,212 @@
+{ config, pkgs, lib, ... }:
+
+{
+  services.matrix-synapse = {
+    enable = true;
+    withJemalloc = true;
+
+    # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
+    settings = {
+      server_name = "rory.gay";
+
+      enable_registration = true;
+      registration_requires_token = true;
+
+      require_membership_for_aliases = false;
+      redaction_retention_period = null;
+      user_ips_max_age = null;
+      allow_device_name_lookup_over_federation = true;
+
+      federation = {
+        client_timeout = "60s";
+        max_short_retries = 6;
+        max_short_retry_delay = "10s";
+        max_long_retries = 5;
+        max_long_retry_delay = "30s";
+      };
+
+      event_cache_size = "1200K"; #defaults to 10K
+      caches = {
+        global_factor = 5000.0;
+        cache_entry_ttl = "12h";
+        expire_caches = true;
+        sync_response_cache_duration = "6h";
+        cache_autotuning = {
+          max_cache_memory_usage = "65536M";
+          target_cache_memory_usage = "32768M";
+          min_cache_ttl = "6h";
+        };
+      };
+
+      # Alicia - figure this out later...
+      #registration_shared_secret = builtins.exec ["cat" "/dev/urandom" "|" "tr" "-dc" "a-zA-Z0-9" "|" "fold" "-w" "256" "|" "head" "-n" "1"];
+      registration_shared_secret_path = "/var/lib/matrix-synapse/registration_shared_secret.txt";
+      
+      listeners = [
+        { 
+          port = 8008;
+          bind_addresses = [ "192.168.1.2" "127.0.0.1" ];
+          type = "http";
+          tls = false;
+          x_forwarded = true;
+          resources = [ {
+            names = [ "client" "federation" ];
+            compress = true;
+          } ];
+        }
+      ];
+      dynamic_thumbnails = true;
+      presence = {
+        enable = true;
+        update_interval = 60;
+      };
+      url_preview_enabled = true;
+      database = {
+        name = "psycopg2";
+        args = {
+          user = "matrix-synapse-rory-gay";
+          #passwordFile = "/run/secrets/matrix-synapse-password";
+          password = "somepassword";
+          database = "matrix-synapse-rory-gay";
+          host = "127.0.0.1";
+          application_name = "matrix-synapse (rory.gay)";
+          cp_min = 5;
+          cp_max = 50;
+          #cp_reconnect_interval = "True";
+        };
+      };
+      app_service_config_files = [
+        #"/etc/matrix-synapse/appservice-registration.yaml"
+        "/var/lib/matrix-synapse/modas-registration.yaml"
+      ];
+
+      rc_message = {
+        per_second = 1000;
+        burst_count = 1000;
+      };
+      rc_login = {
+        address = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+        account = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+        failed_attempts = {
+          per_second = 0.1;
+          burst_count = 3;
+        };
+      };
+      rc_joins = {
+        local = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+        remote = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+      };
+      rc_joins_per_room = {
+        per_second = 1000;
+        burst_count = 1000;
+      };
+      rc_invites = {
+        per_room = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+        per_user = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+        per_issuer = {
+          per_second = 1000;
+          burst_count = 1000;
+        };
+      };
+      rc_federation = {
+        window_size = 10;
+        sleep_limit = 1000;
+        sleep_delay = 100;
+        reject_limit = 1000;
+        concurrent = 100;
+      };
+      federation_rr_transactions_per_room_per_second = 1;
+
+      max_image_pixels = "100M";
+
+      ui_auth = {
+        session_timeout = "1m";
+      };
+
+      login_via_existing_session = {
+        enabled = true;
+        require_ui_auth = true;
+        token_timeout = "1y";
+      };
+
+      #sentry = {
+      #  dsn = "https://77c8de07855d4e0c90dbcf0945a04f01@sentry.thearcanebrony.net/14";
+      #};
+
+      report_stats = false;
+
+      user_directory = {
+        enabled = true;
+        search_all_users = true;
+        prefer_local_users = true;
+      };
+
+      experimental_features = {
+        "org.matrix.msc3026.busy_presence" = true;
+        "fi.mau.msc2815" = true;
+        "org.matrix.msc3881" = true;
+        "org.matrix.msc3874" = true;
+        "org.matrix.msc3912" = true;
+      };
+    };
+
+    plugins = with pkgs.matrix-synapse-plugins; [
+      # Alicia - need to port draupnir...
+      #matrix-synapse-mjolnir-antispam
+#      matrix-synapse-pam
+    ];
+#    extraConfigFiles = [
+#        (pkgs.writeTextFile {
+#          name = "matrix-synapse-extra-config.yml";
+#          text = ''
+#            modules:
+#              - module: "pam_auth_provider.PAMAuthProvider"
+#                config:
+#                  create_users: true
+#                  skip_user_check: false
+#          '';
+#        })
+#      ];
+  };
+
+    systemd.services.matrix-synapse-reg-token = {
+      description = "Random registration token for Synapse.";
+      before = ["matrix-synapse.service"]; # So the registration can be used by Synapse
+      wantedBy = ["multi-user.target"];
+      after = ["network.target"];
+
+      script = ''
+
+        if [ ! -f "registration_shared_secret.txt" ]
+        then
+          cat /dev/urandom | tr -dc a-zA-Z0-9 | fold -w 256 | head -n 1 > registration_shared_secret.txt
+        else
+          echo Not generating key, key exists;
+        fi'';
+      serviceConfig = {
+        User = "matrix-synapse";
+        Group = "matrix-synapse";
+        WorkingDirectory = "/var/lib/matrix-synapse";
+      };
+    };
+
+}
+
diff --git a/host/Rory-nginx/services/matrix/synapse/caches.nix b/host/Rory-nginx/services/matrix/synapse/caches.nix
new file mode 100644
index 0000000..d129076
--- /dev/null
+++ b/host/Rory-nginx/services/matrix/synapse/caches.nix
@@ -0,0 +1,16 @@
+{
+  gc_min_interval = ["5m" "30m" "60m"];
+  gc_thresholds = [1000 500 250];
+  event_cache_size = "12000K"; #defaults to 10K
+  caches = {
+    global_factor = 50000.0;
+    cache_entry_ttl = "24h";
+    expire_caches = true;
+    sync_response_cache_duration = "15s"; #6h
+    cache_autotuning = {
+      max_cache_memory_usage = "65536M";
+      target_cache_memory_usage = "32768M";
+      min_cache_ttl = "6h";
+    };
+  };
+}
\ No newline at end of file
diff --git a/host/Rory-nginx/services/matrix/synapse/db.nix b/host/Rory-nginx/services/matrix/synapse/db.nix
new file mode 100644
index 0000000..c5edc51
--- /dev/null
+++ b/host/Rory-nginx/services/matrix/synapse/db.nix
@@ -0,0 +1,21 @@
+{ 
+  workerName ? null,
+  dbGroup ? null
+}: {
+  name = "psycopg2";
+  args = {
+    user = "matrix-synapse-rory-gay";
+    password = "somepassword";
+    database = "matrix-synapse-rory-gay";
+    host = "/run/postgresql";
+    application_name = "matrix-synapse (rory.gay) - ${if workerName == null then throw "synapse/db.nix: workerName unspecified" else workerName}";
+    cp_min = if dbGroup == "small" then 2
+      else if dbGroup == "medium" then 5
+      else if dbGroup == "large" then 10
+      else throw "synapse/db.nix: Invalid dbGroup: ${if dbGroup == null then "null" else dbGroup}";
+    cp_max = if dbGroup == "small" then 2
+      else if dbGroup == "medium" then 10
+      else if dbGroup == "large" then 10
+      else throw "synapse/db.nix: Invalid dbGroup: ${if dbGroup == null then "null" else dbGroup}";
+  };
+}
\ No newline at end of file
diff --git a/host/Rory-nginx/services/matrix/synapse/ratelimits.nix b/host/Rory-nginx/services/matrix/synapse/ratelimits.nix
new file mode 100644
index 0000000..8165fe4
--- /dev/null
+++ b/host/Rory-nginx/services/matrix/synapse/ratelimits.nix
@@ -0,0 +1,56 @@
+{
+  rc_message = {
+    per_second = 1000;
+    burst_count = 1000;
+  };
+  rc_login = {
+    address = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+    account = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+    failed_attempts = {
+      per_second = 0.1;
+      burst_count = 3;
+    };
+  };
+  rc_joins = {
+    local = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+    remote = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+  };
+  rc_joins_per_room = {
+    per_second = 1000;
+    burst_count = 1000;
+  };
+  rc_invites = {
+    per_room = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+    per_user = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+    per_issuer = {
+      per_second = 1000;
+      burst_count = 1000;
+    };
+  };
+  rc_federation = {
+    window_size = 10;
+    sleep_limit = 1000;
+    sleep_delay = 100;
+    reject_limit = 1000;
+    concurrent = 100;
+  };
+  federation_rr_transactions_per_room_per_second = 1;
+}
\ No newline at end of file
diff --git a/host/Rory-nginx/services/matrix/synapse/synapse-main.nix b/host/Rory-nginx/services/matrix/synapse/synapse-main.nix
new file mode 100755
index 0000000..f6b8077
--- /dev/null
+++ b/host/Rory-nginx/services/matrix/synapse/synapse-main.nix
@@ -0,0 +1,233 @@
+{ config, pkgs, lib, ... }:
+
+let
+  federationSenders = lib.range 0 31;
+  federationReceivers = lib.range 10000 10000;
+  initialSyncWorkers = lib.range 10100 10100;
+  syncWorkers = lib.range 10150 10150;
+  streamWriters = lib.range 10200 10200;
+in
+{
+  services.matrix-synapse = {
+    enable = true;
+    withJemalloc = true;
+
+    sliding-sync = {
+      enable = true;
+      settings = {
+        "SYNCV3_SERVER" = "http://localhost:8008";
+        "SYNCV3_DB" = "postgresql://%2Frun%2Fpostgresql/syncv3";
+        "SYNCV3_BINDADDR" = "0.0.0.0:8100";
+      };
+      environmentFile = "/etc/sliding-sync.env";
+    };
+
+    # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
+    settings = {
+      server_name = "rory.gay";
+
+      enable_registration = true;
+      registration_requires_token = true;
+
+      require_membership_for_aliases = false;
+      redaction_retention_period = null;
+      user_ips_max_age = null;
+      allow_device_name_lookup_over_federation = true;
+
+      federation = {
+        client_timeout = "60s";
+        max_short_retries = 12;
+        max_short_retry_delay = "5s";
+        max_long_retries = 5;
+        max_long_retry_delay = "30s";
+      };
+
+      # Alicia - figure this out later...
+      #registration_shared_secret = builtins.exec ["cat" "/dev/urandom" "|" "tr" "-dc" "a-zA-Z0-9" "|" "fold" "-w" "256" "|" "head" "-n" "1"];
+      registration_shared_secret_path = "/var/lib/matrix-synapse/registration_shared_secret.txt";
+      
+      listeners = [
+        { 
+          port = 8008;
+          bind_addresses = [ "192.168.1.2" "127.0.0.1" ];
+          type = "http";
+          tls = false;
+          x_forwarded = true;
+          resources = [ {
+            names = [ "client" "federation" ];
+            compress = false;
+          } ];
+        }
+        { 
+          type = "http";
+          path = "/run/synapse/replication-listener.sock";
+          resources = [ {
+            names = [ "replication" ];
+            compress = false;
+          } ];
+        }
+      ];
+      dynamic_thumbnails = true;
+      presence = {
+        enable = true;
+        update_interval = 60;
+      };
+      url_preview_enabled = true;
+      database = (import ./db.nix { workerName = "main"; dbGroup = "medium"; });
+      #database = {
+      #  name = "psycopg2";
+      #  args = {
+      #    user = "matrix-synapse-rory-gay";
+      #    #passwordFile = "/run/secrets/matrix-synapse-password";
+      #    password = "somepassword";
+      #    database = "matrix-synapse-rory-gay";
+      #    #host = "127.0.0.1";
+      #    host = "/run/postgresql";
+      #    application_name = "matrix-synapse (rory.gay)";
+      #    cp_min = 5;
+      #    cp_max = 10;
+      #    #cp_reconnect_interval = "True";
+      #  };
+      #};
+      app_service_config_files = [
+        #"/etc/matrix-synapse/appservice-registration.yaml"
+        "/var/lib/matrix-synapse/modas-registration.yaml"
+      ];
+
+      max_image_pixels = "100M";
+
+      ui_auth = {
+        session_timeout = "1m";
+      };
+
+      login_via_existing_session = {
+        enabled = true;
+        require_ui_auth = true;
+        token_timeout = "1y";
+      };
+
+      report_stats = false;
+
+      user_directory = {
+        enabled = true;
+        search_all_users = true;
+        prefer_local_users = true;
+      };
+
+      experimental_features = {
+        # These apparently arent valid...
+        #"org.matrix.msc3026.busy_presence" = true;
+        #"fi.mau.msc2815" = true;
+        #"org.matrix.msc3881" = true;
+        #"org.matrix.msc3874" = true;
+        #"org.matrix.msc3912" = true;
+
+        # These should be, looking at synapse's experimental.py
+        "msc2815_enabled" = true; # Redacted event content
+        "msc3026_enabled" = true; # Busy presence
+        "msc3266_enabled" = true; # Room summary API
+        "msc3916_authenticated_media_enabled" = true; # Authenticated media
+      };
+
+
+      redis = {
+        enabled = true;
+        path = "/run/redis-matrix-synapse/redis.sock";
+      };
+
+
+      instance_map = {
+        main = { # replication listener
+          #host = "127.0.0.1";
+          #port = 8009;
+          path = "/run/synapse/replication-listener.sock";
+        };
+      } // builtins.listToAttrs (map (port: {
+        name = "federation_sender-${toString port}";
+        value = {
+          path = "/run/synapse/federation_sender-${toString port}.sock";
+        };
+      }) federationSenders);
+      #} // builtins.listToAttrs (map (port: {
+      #  name = "federation_receiver-${toString port}";
+      #  value = {
+      #    path = "/run/synapse/federation_receiver-${toString port}.sock";
+      #  };
+      #}) federationReceivers);
+
+      # by type:
+      send_federation = false;
+      federation_sender_instances = map (port: "federation_sender-${toString port}") federationSenders;
+
+    }
+    // import ./ratelimits.nix
+    // import ./caches.nix;
+
+    ## TODO: INVESTIGATE
+    # worker_listeners:
+    # - type: metrics
+    #   bind_address: ''
+    #   port: 9101
+
+    workers = 
+    #builtins.listToAttrs (map (port: {
+    #  name = "federation_receiver-${toString port}";
+    #  value = {
+    #    worker_app = "synapse.app.generic_worker";
+    #    worker_listeners = [
+    #      { 
+    #        port = port;
+    #        type = "http";
+    #        resources = [ {
+    #          names = [ "federation" ];
+    #          compress = false;
+    #        } ];
+    #      }
+    #    ];
+    #  };
+    #}) federationReceivers)
+    builtins.listToAttrs (map (port: {
+      name = "federation_sender-${toString port}";
+      value = {
+        worker_app = "synapse.app.generic_worker";
+        worker_listeners = [ ];
+        database = (import ./db.nix { workerName = "federation sender ${toString port}"; dbGroup = "small"; });
+      };
+    }) federationSenders);
+  };
+
+  systemd.services.matrix-synapse-reg-token = {
+    description = "Random registration token for Synapse.";
+    before = ["matrix-synapse.service"]; # So the registration can be used by Synapse
+    wantedBy = ["multi-user.target"];
+    after = ["network.target"];
+
+    script = ''
+
+      if [ ! -f "registration_shared_secret.txt" ]
+      then
+        cat /dev/urandom | tr -dc a-zA-Z0-9 | fold -w 256 | head -n 1 > registration_shared_secret.txt
+      else
+        echo Not generating key, key exists;
+      fi'';
+    serviceConfig = {
+      User = "matrix-synapse";
+      Group = "matrix-synapse";
+      WorkingDirectory = "/var/lib/matrix-synapse";
+    };
+  };
+
+  services.redis = {
+    package = pkgs.keydb;
+    servers.matrix-synapse = {
+      enable = true;
+      user = "matrix-synapse";
+    };
+  };
+  
+  systemd.tmpfiles.rules = [
+    "D /run/redis-matrix-synapse 0755 matrix-synapse matrix-synapse"
+  ];
+
+}
+