diff --git a/machines/fuuko/configuration.nix b/machines/fuuko/configuration.nix index 9e433d3..b35faac 100644 --- a/machines/fuuko/configuration.nix +++ b/machines/fuuko/configuration.nix @@ -10,6 +10,7 @@ ./services/gitea.nix ./services/grafana.nix ./services/hedgedoc.nix + ./services/matrix ./services/media.nix ./services/prometheus.nix ./services/scan.nix diff --git a/machines/fuuko/services/matrix/default.nix b/machines/fuuko/services/matrix/default.nix new file mode 100644 index 0000000..f342253 --- /dev/null +++ b/machines/fuuko/services/matrix/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./synapse.nix + ]; +} diff --git a/machines/fuuko/services/matrix/synapse.nix b/machines/fuuko/services/matrix/synapse.nix new file mode 100644 index 0000000..3cb45ef --- /dev/null +++ b/machines/fuuko/services/matrix/synapse.nix @@ -0,0 +1,139 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.matrix-synapse; + + fqdn = "matrix.sbruder.de"; + domain = "sbruder.de"; +in +{ + krops.secrets = { + synapse-registration-shared-secret.group = "matrix-synapse"; + synapse-turn-shared-secret.group = "matrix-synapse"; + }; + users.users.matrix-synapse.extraGroups = [ "keys" ]; + + services.matrix-synapse = { + enable = true; + server_name = domain; + public_baseurl = "https://${fqdn}"; + + listeners = lib.singleton { + port = 8008; + bind_address = "127.0.0.1"; + type = "http"; + tls = false; + x_forwarded = true; + resources = lib.singleton { + names = [ "client" "federation" "metrics" ]; + compress = false; + }; + }; + + dataDir = "/data/matrix/synapse"; + + turn_uris = [ + "turns:turn.sbruder.de:5349?transport=udp" + "turns:turn.sbruder.de:5349?transport=tcp" + ]; + turn_user_lifetime = "3600000"; # 1h + + enable_metrics = true; + + # adapted from https://github.com/NixOS/nixpkgs/blob/7e10bf4327491a6ebccbe1aaa8e6c6c0aca4663a/nixos/modules/services/misc/matrix-synapse-log_config.yaml + # - set root.level to WARNING instead of INFO + logConfig = builtins.toJSON { + 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 = "WARNING"; + handlers = [ "journal" ]; + }; + + disable_existing_loggers = false; + }; + + extraConfig = '' + # I’m okay with using matrix.org as trusted key server + suppress_key_server_warning: true + ''; + + extraConfigFiles = with config.krops.secrets; [ + synapse-registration-shared-secret.path + synapse-turn-shared-secret.path + ]; + }; + + services.postgresql = { + enable = true; + # synapse requires custom databse configuration: + # CREATE DATABASE "matrix-synapse" TEMPLATE template0 LC_COLLATE "C" LC_CTYPE "C"; + ensureUsers = lib.singleton { + name = "matrix-synapse"; + ensurePermissions = { + "DATABASE \"matrix-synapse\"" = "ALL PRIVILEGES"; + }; + }; + }; + + services.nginx.virtualHosts = { + "${fqdn}" = { + enableACME = true; + forceSSL = true; + + locations."/".return = "301 https://chat.sbruder.de"; + + locations."/_matrix" = + let + listenerCfg = (lib.elemAt cfg.listeners 0); + in + { + proxyPass = "http://${listenerCfg.bind_address}:${toString listenerCfg.port}"; + }; + }; + + "${domain}" = { + enableACME = true; + forceSSL = true; + + locations = + let + # workaround for nginx dropping parent headers + # see https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md + parentHeaders = lib.concatStringsSep "\n" (lib.filter + (lib.hasPrefix "add_header ") + (lib.splitString "\n" config.services.nginx.commonHttpConfig)); + in + { + "=/.well-known/matrix/server".extraConfig = '' + ${parentHeaders} + add_header Content-Type application/json; + return 200 '${builtins.toJSON { + "m.server" = "${fqdn}:443"; + }}'; + ''; + "=/.well-known/matrix/client".extraConfig = '' + ${parentHeaders} + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON { + "m.homeserver"."base_url" = "https://${fqdn}"; + }}'; + ''; + }; + }; + }; +} diff --git a/machines/fuuko/services/prometheus.nix b/machines/fuuko/services/prometheus.nix index a96c00b..6f267f0 100644 --- a/machines/fuuko/services/prometheus.nix +++ b/machines/fuuko/services/prometheus.nix @@ -82,6 +82,20 @@ in job_name = "fritzbox"; static_configs = mkStaticTarget "127.0.0.1:9133"; } + ( + let + listenerCfg = (lib.elemAt config.services.matrix-synapse.listeners 0); + in + { + job_name = "synapse"; + static_configs = mkStaticTarget "${listenerCfg.bind_address}:${toString listenerCfg.port}"; + metrics_path = "/_synapse/metrics"; + relabel_configs = lib.singleton { + target_label = "instance"; + replacement = "matrix.sbruder.de"; + }; + } + ) ]; rules =