diff --git a/checks/flake-module.nix b/checks/flake-module.nix index b792a1f9..b0a2eb4e 100644 --- a/checks/flake-module.nix +++ b/checks/flake-module.nix @@ -27,6 +27,7 @@ secrets = import ./secrets nixosTestArgs; container = import ./container nixosTestArgs; deltachat = import ./deltachat nixosTestArgs; + matrix-synapse = import ./matrix-synapse nixosTestArgs; zt-tcp-relay = import ./zt-tcp-relay nixosTestArgs; borgbackup = import ./borgbackup nixosTestArgs; syncthing = import ./syncthing nixosTestArgs; diff --git a/checks/matrix-synapse/default.nix b/checks/matrix-synapse/default.nix new file mode 100644 index 00000000..ec43209c --- /dev/null +++ b/checks/matrix-synapse/default.nix @@ -0,0 +1,37 @@ +(import ../lib/container-test.nix) ( + { pkgs, ... }: + { + name = "matrix-synapse"; + + nodes.machine = + { self, lib, ... }: + { + imports = [ + self.clanModules.matrix-synapse + self.nixosModules.clanCore + { + clanCore.machineName = "machine"; + clanCore.clanDir = ./.; + clan.matrix-synapse = { + enable = true; + domain = "clan.test"; + }; + } + { + # secret override + clanCore.secrets.matrix-synapse.secrets.synapse-registration_shared_secret.path = "${./synapse-registration_shared_secret}"; + services.nginx.virtualHosts."matrix.clan.test" = { + enableACME = lib.mkForce false; + forceSSL = lib.mkForce false; + }; + } + ]; + }; + testScript = '' + start_all() + machine.wait_for_unit("matrix-synapse") + machine.succeed("${pkgs.netcat}/bin/nc -z -v ::1 8008") + machine.succeed("${pkgs.curl}/bin/curl -Ssf -L http://localhost/_matrix/static/ -H 'Host: matrix.clan.test'") + ''; + } +) diff --git a/checks/matrix-synapse/synapse-registration_shared_secret b/checks/matrix-synapse/synapse-registration_shared_secret new file mode 100644 index 00000000..82a3b081 --- /dev/null +++ b/checks/matrix-synapse/synapse-registration_shared_secret @@ -0,0 +1 @@ +registration_shared_secret: supersecret diff --git a/clanModules/flake-module.nix b/clanModules/flake-module.nix index d2895e70..b519b4ef 100644 --- a/clanModules/flake-module.nix +++ b/clanModules/flake-module.nix @@ -9,6 +9,7 @@ }; borgbackup = ./borgbackup.nix; deltachat = ./deltachat.nix; + matrix-synapse = ./matrix-synapse.nix; moonlight = ./moonlight.nix; sunshine = ./sunshine.nix; syncthing = ./syncthing.nix; diff --git a/clanModules/matrix-synapse.nix b/clanModules/matrix-synapse.nix new file mode 100644 index 00000000..161908be --- /dev/null +++ b/clanModules/matrix-synapse.nix @@ -0,0 +1,127 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.clan.matrix-synapse; +in +{ + options.clan.matrix-synapse = { + enable = lib.mkEnableOption "Enable matrix-synapse"; + domain = lib.mkOption { + type = lib.types.str; + description = "The domain name of the matrix server"; + }; + }; + config = lib.mkIf cfg.enable { + services.matrix-synapse = { + enable = true; + settings = { + server_name = cfg.domain; + database = { + args.user = "matrix-synapse"; + args.database = "matrix-synapse"; + name = "psycopg2"; + }; + turn_uris = [ + "turn:turn.matrix.org?transport=udp" + "turn:turn.matrix.org?transport=tcp" + ]; + listeners = [ + { + port = 8008; + bind_addresses = [ "::1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ "client" ]; + compress = true; + } + { + names = [ "federation" ]; + compress = false; + } + ]; + } + ]; + }; + extraConfigFiles = [ "/var/lib/matrix-synapse/registration_shared_secret.yaml" ]; + }; + systemd.services.matrix-synapse.serviceConfig.ExecStartPre = [ + "+${pkgs.writeScript "copy_registration_shared_secret" '' + #!/bin/sh + cp ${config.clanCore.secrets.matrix-synapse.secrets.synapse-registration_shared_secret.path} /var/lib/matrix-synapse/registration_shared_secret.yaml + chown matrix-synapse:matrix-synapse /var/lib/matrix-synapse/registration_shared_secret.yaml + chmod 600 /var/lib/matrix-synapse/registration_shared_secret.yaml + ''}" + ]; + + clanCore.secrets."matrix-synapse" = { + secrets."synapse-registration_shared_secret" = { }; + generator.path = with pkgs; [ + coreutils + pwgen + ]; + generator.script = '' + echo "registration_shared_secret: $(pwgen -s 32 1)" > "$secrets"/synapse-registration_shared_secret + ''; + }; + + services.postgresql.enable = true; + # we need to use both ensusureDatabases and initialScript, because the former runs everytime but with the wrong collation + services.postgresql = { + ensureDatabases = [ "matrix-synapse" ]; + ensureUsers = [ + { + name = "matrix-synapse"; + ensureDBOwnership = true; + } + ]; + initialScript = pkgs.writeText "synapse-init.sql" '' + CREATE DATABASE "matrix-synapse" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + ''; + }; + services.nginx = { + enable = true; + virtualHosts = { + ${cfg.domain} = { + locations."= /.well-known/matrix/server".extraConfig = '' + add_header Content-Type application/json; + return 200 '${builtins.toJSON { "m.server" = "matrix.${cfg.domain}:443"; }}'; + ''; + locations."= /.well-known/matrix/client".extraConfig = '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${ + builtins.toJSON { + "m.homeserver" = { + "base_url" = "https://matrix.${cfg.domain}"; + }; + "m.identity_server" = { + "base_url" = "https://vector.im"; + }; + } + }'; + ''; + }; + "matrix.${cfg.domain}" = { + forceSSL = true; + enableACME = true; + locations."/_matrix" = { + proxyPass = "http://localhost:8008"; + }; + locations."/test".extraConfig = '' + return 200 "Hello, world!"; + ''; + }; + }; + }; + }; +}