diff --git a/configuration.nix b/configuration.nix index dbae0a4..cac7a49 100644 --- a/configuration.nix +++ b/configuration.nix @@ -75,6 +75,8 @@ useACME = true; domain = "monitoring.${config.networking.domain}"; }; + + matrix.enable = true; }; security.acme.acceptTerms = true; diff --git a/services/default.nix b/services/default.nix index 3b3fbef..db8eec4 100644 --- a/services/default.nix +++ b/services/default.nix @@ -2,6 +2,7 @@ { imports = [ + ./matrix.nix ./monitoring.nix ]; } diff --git a/services/matrix.nix b/services/matrix.nix new file mode 100644 index 0000000..434f2c1 --- /dev/null +++ b/services/matrix.nix @@ -0,0 +1,102 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.my.services.matrix; + + federationPort = { public = 8448; private = 11338; }; + clientPort = { public = 443; private = 11339; }; + domain = config.networking.domain; +in { + options.my.services.matrix = { + enable = lib.mkEnableOption "Matrix Synapse"; + }; + + config = lib.mkIf cfg.enable { + services.postgresql = { + enable = true; + package = pkgs.postgresql_12; + }; + + services.matrix-synapse = { + enable = true; + server_name = domain; + public_baseurl = "https://matrix.${domain}"; + + listeners = [ + # Federation + { + bind_address = "127.0.0.1"; + port = federationPort.private; + tls = false; # Terminated by nginx. + x_forwarded = true; + resources = [ { names = [ "federation" ]; compress = false; } ]; + } + + # Client + { + bind_address = "127.0.0.1"; + port = clientPort.private; + tls = false; # Terminated by nginx. + x_forwarded = true; + resources = [ { names = [ "client" ]; compress = false; } ]; + } + ]; + }; + + services.nginx = { + enable = true; + + recommendedGzipSettings = true; + recommendedTlsSettings = true; + recommendedProxySettings = true; + + virtualHosts = let + passToMatrix = port: { + proxyPass = "http://127.0.0.1:${toString port}"; + }; + in { + "matrix.${domain}" = { + forceSSL = true; + enableACME = true; + + locations."/" = passToMatrix clientPort.private; + }; + + "matrix.${domain}_federation" = rec { + onlySSL = true; + serverName = "matrix.${domain}"; + useACMEHost = serverName; + + listen = [ + { addr = "0.0.0.0"; port = federationPort.public; ssl = true; } + { addr = "[::]"; port = federationPort.public; ssl = true; } + ]; + + locations."/" = passToMatrix federationPort.private; + }; + + "${domain}" = { + onlySSL = true; + enableACME = true; + + listen = [ + { addr = "0.0.0.0"; port = federationPort.public; ssl = true; } + { addr = "[::]"; port = federationPort.public; ssl = true; } + ]; + + locations."/" = passToMatrix federationPort.private; + }; + }; + }; + + # For administration tools. + environment.systemPackages = [ pkgs.matrix-synapse ]; + + networking.firewall.allowedTCPPorts = [ + clientPort.public + federationPort.public + ]; + }; +}