{ self, config, lib, pkgs, ... }: { imports = [ ./mautrix-telegram.nix ./mautrix-services.nix # ./mautrix-discord.nix # ./mautrix-whatsapp.nix # ./mautrix-slack.nix # ./mautrix-signal.nix ./mjolnir.nix ./heisenbridge.nix ./compress-state-service.nix ]; age.secrets.synapse-database-password.file = "${self}/secrets/synapse-database-password.age"; age.secrets.synapse-database-password.owner = "matrix-synapse"; age.secrets.synapse-config.file = "${self}/secrets/synapse-config.age"; age.secrets.synapse-config.owner = "matrix-synapse"; services.matrix-synapse = { enable = true; settings = { max_upload_size = "100M"; server_name = "sealight.xyz"; listeners = [ { port = 8448; tls = false; resources = [{ compress = true; names = [ "client" "federation" ]; }]; } { port = 9090; type = "metrics"; bind_addresses = [ "0.0.0.0" ]; resources = [{ compress = false; names = [ ]; }]; tls = false; } ]; app_service_config_files = [ # The registration file is automatically generated after starting the appservice for the first time. # cp /var/lib/matrix-appservice-discord/discord-registration.yaml /var/lib/matrix-synapse/ # chown matrix-synapse:matrix-synapse /var/lib/matrix-synapse/discord-registration.yaml "/var/lib/matrix-synapse/telegram-registration.yaml" "/var/lib/matrix-synapse/signal-registration.yaml" "/var/lib/matrix-as-whatsapp/whatsapp-registration.yaml" "/var/lib/matrix-as-discord/discord-registration.yaml" # "/var/lib/matrix-synapse/slack-registration.yaml" # "/var/lib/matrix-synapse/discord-registration.yaml" # "/var/lib/matrix-synapse/whatsapp-registration.yaml" ]; turn_uris = [ "turn:turn.sealight.xyz:3478?transport=udp" "turn:turn.sealight.xyz:3478?transport=tcp" ]; # turn_shared_secret = config.services.coturn.static-auth-secret; # Example config (saved as secret??) # '' # max_upload_size: "50M" # use_presence: false # registration_shared_secret: "hD9HQGTTDxp0mQsQ5JDsfudWMDiubmZENOgPchIvfBvUlPxlvQSvjoO4wn2L1seU"; # enable_registration_without_verification: true # ''; enable_metrics = true; enable_registration = false; database = { name = "psycopg2"; args.passfile = "/run/agenix/synapse-database-password"; }; }; extraConfigFiles = [ "/run/agenix/synapse-config" ]; ## coturn based TURN server integration (TURN server setup mentioned later), ## shared secret generated while configuring coturn ## and reused here (power of Nix being a real programming language) }; # services.coturn = { # enable = true; # use-auth-secret = true; # static-auth-secret = "jXW1ohIq6wM3NB00xeME3uBihY85xjpkhGoyzBIdwhOpj7gjyxXZu1fwp1lUiYwJ"; # TODO agenix # realm = "turn.sealight.xyz"; # min-port = 49111; # max-port = 51111; # no-cli = true; # no-tcp-relay = true; # no-tls = true; # cert = "${config.security.acme.certs."turn.sealight.xyz".directory}/full.pem"; # pkey = "${config.security.acme.certs."turn.sealight.xyz".directory}/key.pem"; # extraConfig = '' # verbose # user-quota=12 # total-quota=1200 # denied-peer-ip=10.0.0.0-10.255.255.255 # denied-peer-ip=192.168.0.0-192.168.255.255 # denied-peer-ip=172.16.0.0-172.31.255.255 # denied-peer-ip=0.0.0.0-0.255.255.255 # denied-peer-ip=100.64.0.0-100.127.255.255 # denied-peer-ip=127.0.0.0-127.255.255.255 # denied-peer-ip=169.254.0.0-169.254.255.255 # denied-peer-ip=192.0.0.0-192.0.0.255 # denied-peer-ip=192.0.2.0-192.0.2.255 # denied-peer-ip=192.88.99.0-192.88.99.255 # denied-peer-ip=198.18.0.0-198.19.255.255 # denied-peer-ip=198.51.100.0-198.51.100.255 # denied-peer-ip=203.0.113.0-203.0.113.255 # denied-peer-ip=240.0.0.0-255.255.255.255 # ''; # }; # security.acme.certs.${config.services.coturn.realm} = { # /* insert here the right configuration to obtain a certificate */ # webroot = "/var/lib/acme/acme-challenge/"; # email = "anish+acme@lakhwara.com"; # postRun = "systemctl restart coturn.service"; # group = "turnserver"; # }; # TODO fix up jitsi bridge stuff ## services.jitsi-meet = { ## enable = true; ## hostName = "jitsi.sealight.xyz"; ## }; ## services.jitsi-videobridge.enable = true; services.postgresql = { enable = true; package = pkgs.postgresql_14; ## postgresql user and db name remains in the ## service.matrix-synapse.database_args setting which ## by default is matrix-synapse # TODO agenix initialScript = pkgs.writeText "synapse-init.sql" '' CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD "s0m3s3cur3p455w0rdth4tisch4ng3d"; CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; ''; authentication = '' local matrix-synapse all ident map=matrix-synapse-users ''; identMap = # Map the matrix-synapse user to postgresql '' matrix-synapse-users matrix-synapse matrix-synapse ''; }; networking.firewall = let range = with config.services.coturn; [{ from = min-port; to = max-port; }]; in { enable = true; allowedUDPPortRanges = range; # coturn allowedTCPPortRanges = range; allowedTCPPorts = [ 22 # SSH 8448 # Matrix federation 8008 80 443 3478 # Coturn service 5349 # Coturn service 9090 # Synapse Metrics ]; allowedUDPPorts = [ 3478 5349 # Coturn service ]; }; nixpkgs.overlays = [ (self: super: { element-web = super.element-web.override { conf = { default_server_config = { "m.homeserver" = { "base_url" = "https://chat.sealight.xyz"; "server_name" = "sealight.xyz"; }; "m.identity_server" = { "base_url" = "https://vector.im"; }; }; ## jitsi will be setup later, ## but we need to add to Riot configuration jitsi.preferredDomain = "jitsi.sealight.xyz"; }; }; }) ]; services.nginx = { enable = true; virtualHosts = { "sealight.xyz" = { forceSSL = true; enableACME = true; locations."/" = { root = "/var/www/sealight.xyz"; }; locations."/_matrix" = { proxyPass = "http://localhost:8448"; }; # locations."/slackbridge" = { # proxyPass = "http://localhost:9899"; # }; }; ## virtual host for Synapse "chat.sealight.xyz" = { forceSSL = true; enableACME = true; locations."/" = { proxyPass = "http://localhost:8448"; }; }; ## virtual host for Riot/Web "element.sealight.xyz" = { forceSSL = true; enableACME = true; ## root points to the element-web package content, also configured via Nix locations."/" = { root = pkgs.element-web; }; }; # ${config.services.jitsi-meet.hostName} = { # enableACME = true; # TODO # forceSSL = true; # TODO # }; }; ## other nginx specific best practices recommendedGzipSettings = true; recommendedOptimisation = true; recommendedTlsSettings = true; }; }