{ config, pkgs, lib, ... }: let federationSenders = lib.range 0 63; 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; # 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"; }; 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 = "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 = false; } ]; } { #port = 8009; #bind_addresses = [ "127.0.0.1" ]; type = "http"; #tls = false; #x_forwarded = true; 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 = { 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 = 10; #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"; }; 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; }; 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; }; ## 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 = [ ]; }; }) 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" ]; }