{ config, ... }: let database = { connection_string = "postgres:///dendrite?host=/run/postgresql"; max_open_conns = 97; max_idle_conns = 5; conn_max_lifetime = -1; }; in { # Adapted from Mic92/dotfiles, (C) 2021 Jörg Thalheim (MIT) sops.secrets.matrix-server-key = { }; services.dendrite = { enable = true; settings = { global = { server_name = "sefidel.com"; # `private_key` has the type `path` # prefix a `/` to make `path` happy private_key = "/$CREDENTIALS_DIRECTORY/matrix-server-key"; trusted_third_party_id_servers = [ "matrix.org" "vector.im" ]; metrics.enable = true; }; logging = [ { type = "std"; level = "warn"; } ]; app_service_api = { inherit database; config_files = [ ]; }; client_api = { registration_disabled = true; rate_limiting.enabled = false; # registration_shared_secret = ""; # Initially set this option to configure the admin user. }; 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"; }; 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; }; }; loadCredential = [ "matrix-server-key:${config.sops.secrets.matrix-server-key.path}" ]; }; environment.persistence."/persist".directories = [ "/var/lib/private/dendrite" ]; services.postgresql.enable = true; services.postgresql.ensureDatabases = [ "dendrite" ]; services.postgresql.ensureUsers = [ { name = "dendrite"; ensurePermissions."DATABASE dendrite" = "ALL PRIVILEGES"; } ]; services.nginx.virtualHosts."matrix.sefidel.com" = { forceSSL = true; useACMEHost = "sefidel.com"; listen = [ { addr = "0.0.0.0"; port = 443; ssl = true; } { addr = "[::]"; port = 443; ssl = true; } { addr = "0.0.0.0"; port = 8448; ssl = true; } { addr = "[::]"; port = 8448; ssl = true; } ]; extraConfig = '' proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; 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}"; # TODO: web client }; services.nginx.virtualHosts."sefidel.com" = let server-hello = { "m.server" = "matrix.sefidel.com:443"; }; client-hello = { "m.homeserver"."base_url" = "https://matrix.sefidel.com"; "m.identity_server"."base_url" = "https://vector.im"; }; in { forceSSL = true; useACMEHost = "sefidel.com"; locations = { "/.well-known/matrix/server" = { extraConfig = '' add_header Content-Type application/json; return 200 '${builtins.toJSON server-hello}'; ''; }; "/.well-known/matrix/client" = { extraConfig = '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; return 200 '${builtins.toJSON client-hello}'; ''; }; }; }; networking.firewall.allowedTCPPorts = [ 8448 ]; }