{ config, lib, pkgs, ... }: with config.var; let ### Element (Riot) configuration conf = with config.var; { default_server_config."m.homeserver" = { base_url = "https://${hostname}"; server_name = "Maxwell"; }; default_server_config."m.identity_server" = { base_url = "https://matrix.org"; }; roomDirectory.servers = [ "matrix.org" hostname ]; brand = "Maxwell matrix"; defaultCountryCode = "IT"; showLabsSettings = true; # Use a trusted Jitsi instance jitsi.preferredDomain = "jitsi.openspeed.org"; jitsi.externalApiUrl = "https://jitsi.openspeed.org/libs/external_api.min.js"; }; in { ### Reverse proxy locations services.nginx.virtualHosts."${config.var.hostname}" = let client = { "m.homeserver" = { "base_url" = "https://${config.var.hostname}"; }; "m.identity_server" = { "base_url" = "https://matrix.org"; }; }; server = { "m.server" = "${config.var.hostname}:443"; }; in { # Needed for matrix federation locations."/.well-known/matrix/server".extraConfig = '' add_header Content-Type application/json; return 200 '${builtins.toJSON server}'; ''; # Needed for automatic homeserver # setup of matrix clients locations."/.well-known/matrix/client".extraConfig = '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; return 200 '${builtins.toJSON client}'; ''; # Forward matrix/admin API calls to synapse locations."/_matrix".proxyPass = "http://localhost:8448"; locations."/_synapse".proxyPass = "http://localhost:8448"; }; ### Element/Riot static location services.nginx.virtualHosts."riot.${config.var.hostname}" = { enableACME = true; forceSSL = true; locations."/" = { index = "index.html"; alias = (pkgs.element-web.override { inherit conf; }) + "/"; }; }; ### Homeserver services.matrix-synapse = { enable = true; server_name = config.var.hostname; # Tell users about our TURN server turn_uris = [ "turn:${config.var.hostname}:5349?transport=udp" "turn:${config.var.hostname}:5350?transport=udp" "turn:${config.var.hostname}:5349?transport=tcp" "turn:${config.var.hostname}:5350?transport=tcp" ]; # Bind on localhost and used a reverse proxy listeners = [ { bind_address = "localhost"; port = 8448; type = "http"; tls = false; resources = [ { compress = true; names = [ "client" ] ; } { compress = false; names = [ "federation" ]; } ]; x_forwarded = true; } ]; # Connect to Postrges database_type = "psycopg2"; database_args = { user = "matrix-synapse"; database = "matrix-synapse"; }; # Make logging less verbose logConfig = '' version: 1 formatters: journal_fmt: format: '%(name)s: [%(request)s] %(message)s' filters: context: (): synapse.util.logcontext.LoggingContextFilter request: "" handlers: journal: class: systemd.journal.JournalHandler formatter: journal_fmt filters: [context] SYSLOG_IDENTIFIER: synapse root: level: WARN handlers: [journal] disable_existing_loggers: False ''; allow_guest_access = true; expire_access_token = true; event_cache_size = "2K"; max_upload_size = "1000M"; turn_user_lifetime = "1d"; # Needed to restrict access to the TURN # server to only our matrix users. turn_shared_secret = config.secrets.matrix.turn; # Needed by the register_new_matrix_user script registration_shared_secret = config.secrets.matrix.registration; }; ### Database services.postgresql.enable = true; # Create database on the first run services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; ''; # Handles users behind a NAT, # needed for reliable VoIP. services.coturn = { enable = true; # Only allow users vouched for # by the Matrix server. lt-cred-mech = true; use-auth-secret = true; static-auth-secret = config.secrets.matrix.turn; # Use maxwell certificate for TLS realm = config.var.hostname; cert = "/var/lib/acme/${config.var.hostname}/fullchain.pem"; pkey = "/var/lib/acme/${config.var.hostname}/key.pem"; # Port range for TURN relaying min-port = 49152; max-port = 49999; # Enable TLS secure-stun = true; no-tcp-relay = false; extraConfig = '' external-ip=${config.var.ipAddress} cipher-list=HIGH no-loopback-peers no-multicast-peers denied-peer-ip=10.0.0.0-10.255.255.255 denied-peer-ip=192.168.0.0-192.168.255.255 allowed-peer-ip=192.168.1.5 user-quota=12 total-quota=1200 verbose=true ''; }; }