{ config, lib, pkgs, ... }: { services.matrix-synapse = { enable = true; settings = { 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/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; extraConfig = '' max_upload_size: "50M" use_presence: false registration_shared_secret: "hD9HQGTTDxp0mQsQ5JDsfudWMDiubmZENOgPchIvfBvUlPxlvQSvjoO4wn2L1seU"; ''; enable_metrics = true; enable_registration = false; database = { name = "psycopg2"; args.password = "Da0?H*9i{x?,]|kq@iBwlIzu"; # TODO agenix }; }; ## 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"; 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; ## 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 "Da0?H*9i{x?,]|kq@iBwlIzu"; 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; # TODO #useACMEHost = "sealight.xyz"; locations."/" = { proxyPass = "http://localhost:8448"; }; }; ## virtual host for Riot/Web "element.sealight.xyz" = { forceSSL = true; enableACME = true; # TODO #useACMEHost = "sealight.xyz"; ## root points to the riot-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; }; services.mautrix-telegram = { enable = false; environmentFile = /etc/secrets/telegram.env; # file containing the appservice and telegram tokens # The appservice is pre-configured to use SQLite by default. It's also possible to use PostgreSQL. settings = { homeserver = { address = "https://sealight.xyz"; domain = "sealight.xyz"; }; appservice = { provisioning.enabled = false; id = "telegram"; bot_username = "telegrambridge"; public = { enabled = false; prefix = "/public"; external = "https://chat.sealight.xyz/public"; }; address = "http://localhost:18787"; port = 18787; # The service uses SQLite by default, but it's also possible to use PostgreSQL instead: #database = "postgresql:///mautrix-telegram?host=/run/postgresql"; }; bridge = { relaybot.authless_portals = false; permissions = { "@aynish:sealight.xyz" = "admin"; }; }; }; }; # services.heisenbridge = { # enable = true; # homeserver = "https://sealight.xyz"; # listenPort = 14456; # appServiceToken = "wyujLh8kjpmk2bfKeEE3sZ2gWOEUBKK5"; # homeserverToken = "yEHs7lthD2ZHUibJOAv1APaFhEjxN5PT"; # }; # environment.systemPackages = with pkgs; [ matrix-appservice-slack ]; #services.mx-puppet-slack= { #enable = false; #settings = { # bridge = { # bindAddress = "localhost"; # port = 16786; # domain = "sealight.xyz"; # homeserverUrl = "https://sealight.xyz"; # }; # provisioning = { # whitelist = [ "@aynish:sealight.xyz" ]; # }; # relay = { # whitelist = [ "@aynish:sealight.xyz" ]; # }; # namePatterns = { # group = ":name"; # room = ":name[:team? - :team,]"; # user = ":name (Slack)"; # userOverride = ":displayname"; # }; # presence = { # enabled = false; # }; # oauth = { # enabled = false; # }; #}; #serviceDependencies = ["matrix-synapse.service"]; #}; # services.mautrix-whatsapp = { # enable = false; # The appservice is pre-configured to use SQLite by default. It's also possible to use PostgreSQL. #configOptions = { # homeserver = { # address = "https://chat.sealight.xyz"; # domain = "sealight.xyz"; # }; # appservice = { # id = "whatsapp"; # address = http://localhost:9897; # hostname = "0.0.0.0"; # port = 9897; # database = { # type = "sqlite3"; # uri = "/var/lib/mautrix-whatsapp/mautrix-whatsapp.db"; # }; # state_store_path = "/var/lib/mautrix-whatsapp/mx-state.json"; # bot = { # username = "whatsappbot"; # displayname = "WhatsApp bridge bot"; # avatar = "mxc://maunium.net/NeXNQarUbrlYBiPCpprYsRqr"; # }; # as_token = ""; # hs_token = ""; # }; # bridge = { # username_template = "whatsapp_{{.}}"; # displayname_template = "{{if .Notify}}{{.Notify}}{{else}}{{.Jid}}{{end}} (WA)"; # command_prefix = "!wa"; # permissions = { # "@aynish:sealight.xyz" = 100; # }; # }; # logging = { # directory = "/var/lib/mautrix-whatsapp/logs"; # file_name_format = "{{.Date}}-{{.Index}}.log"; # file_date_format = "\"2006-01-02\""; # file_mode = 384; # timestamp_format = "Jan _2, 2006 15:04:05"; # print_level = "debug"; # }; # metrics = { # enabled = true; # listen = "http://localhost:5070"; # }; #}; # }; #services.mx-puppet-discord = { # enable = true; # settings = { # bridge = { # bindAddress = "localhost"; # port = 16785; # domain = "sealight.xyz"; # homeserverUrl = "https://sealight.xyz"; # avatarUrl = "https://discord.com/assets/2d20a45d79110dc5bf947137e9d99b66.svg"; # }; # provisioning = { # whitelist = [ "@aynish:sealight.xyz" ]; # }; # relay = { # whitelist = [ "@aynish:sealight.xyz" ]; # }; # namePatterns = { # group = ":name"; # room = ":name"; # user = ":name (Discord)"; # userOverride = ":displayname"; # }; # presence = { # enabled = false; # }; # }; # serviceDependencies = [ "matrix-synapse.service" ]; #}; }