{ lib, config, pkgs, name, ... }: { config = { security.acme.certs."${name}".extraDomainNames = ["synapse.immae.eu"]; services.nginx = { virtualHosts = { "synapse.immae.eu" = { acmeRoot = config.security.acme.defaults.webroot; useACMEHost = name; forceSSL = true; locations."~ ^/admin(?:/(.*))?$" = { alias = let synapse-admin = pkgs.fetchzip { url = "https://github.com/Awesome-Technologies/synapse-admin/releases/download/0.10.1/synapse-admin-0.10.1.tar.gz"; sha256 = "sha256-M2AYNrnpNoDm20ZTH1OZBHVcjOrHAlqyq5iTQ/At/Xk="; postFetch = '' sed -i -e 's@"/assets@"./assets@g' $out/index.html ''; }; in "${synapse-admin}/$1"; }; locations."/sliding-sync-client/" = { # some svg urls are hardcoded to /client :shrug: alias = "${pkgs.matrix-sliding-sync.src}/client/"; tryFiles = "$uri $uri/ /sliding-sync-client/index.html"; }; locations."~ ^/_matrix/client/unstable/org.matrix.msc3575/sync" = { proxyPass = "http://unix:/run/matrix-synapse/sliding_sync.sock:"; }; locations."~ ^(/_matrix|/_synapse/client|/_synapse/admin)" = { proxyPass = "http://unix:/run/matrix-synapse/main_client_federation.sock:"; extraConfig = '' client_max_body_size 50M; ''; }; }; }; }; systemd.services.postgresql.postStart = lib.mkAfter '' $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'matrix-synapse'" | grep -q 1 || $PSQL -tAc "CREATE DATABASE \"matrix-synapse\" LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0" $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'matrix-sliding-sync'" | grep -q 1 || $PSQL -tAc "CREATE DATABASE \"matrix-sliding-sync\" LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0" $PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname='matrix-synapse'" | grep -q 1 || $PSQL -tAc 'CREATE USER "matrix-synapse"' $PSQL -tAc 'ALTER DATABASE "matrix-synapse" OWNER TO "matrix-synapse";' $PSQL -tAc 'ALTER DATABASE "matrix-sliding-sync" OWNER TO "matrix-synapse";' ''; disko.devices.zpool.zfast.datasets."root/persist/var/lib/matrix-sliding-sync" = { type = "zfs_fs"; mountpoint = "/persist/zfast/var/lib/matrix-sliding-sync"; options.mountpoint = "legacy"; }; disko.devices.zpool.zfast.datasets."root/persist/var/lib/matrix-synapse" = { type = "zfs_fs"; mountpoint = "/persist/zfast/var/lib/matrix-synapse"; options.mountpoint = "legacy"; }; environment.persistence."/persist/zfast".directories = [ { directory = "/var/lib/matrix-synapse"; user = "matrix-synapse"; group = "matrix-synapse"; mode = "0700"; } { directory = "/var/lib/matrix-sliding-sync"; user = "matrix-synapse"; group = "matrix-synapse"; mode = "0700"; } ]; users.users.matrix-synapse.extraGroups = [ "keys" ]; users.users.nginx.extraGroups = [ "matrix-synapse" ]; services.matrix-synapse = { enable = true; log.root.level = "WARNING"; plugins = [ config.services.matrix-synapse.package.plugins.matrix-synapse-ldap3 ]; extraConfigFiles = [ config.secrets.fullPaths."matrix/homeserver_secrets.yaml" ]; settings.modules = [ { module = "ldap_auth_provider.LdapAuthProviderModule"; config = { enabled = true; uri = "ldaps://${config.myEnv.tools.matrix.ldap.host}:636"; start_tls = false; base = config.myEnv.tools.matrix.ldap.base; attributes = { uid = "uid"; mail = "mail"; name = "cn"; }; bind_dn = config.myEnv.tools.matrix.ldap.dn; bind_password_file = config.secrets.fullPaths."matrix/ldap_password"; filter = config.myEnv.tools.matrix.ldap.filter; }; } ]; settings.server_name = "immae.eu"; settings.signing_key_path = config.secrets.fullPaths."matrix/signing.key"; settings.listeners = [ { port = 8008; bind_addresses = [ "127.0.0.1" ]; type = "http"; tls = false; x_forwarded = true; resources = [ { names = [ "client" ]; compress = true; } ]; } { path = "/run/matrix-synapse/main_client_federation.sock"; resources = [ { compress = true; names = [ "client" ]; } { compress = false; names = [ "federation" ]; } ]; type = "http"; x_forwarded = true; } ]; }; services.matrix-sliding-sync = { enable = true; createDatabase = false; settings.SYNCV3_SERVER = "/run/matrix-synapse/main_client_federation.sock"; settings.SYNCV3_BINDADDR = "/run/matrix-synapse/sliding_sync.sock"; environmentFile = config.secrets.fullPaths."matrix/sliding-sync"; }; systemd.services.matrix-synapse = { after = [ "postgresql.service" "persist-zfast-var-lib-matrix\\x2dsynapse.mount" "var-lib-matrix\\x2dsynapse.mount" ]; unitConfig = { BindsTo = [ "var-lib-matrix\\x2dsynapse.mount" "persist-zfast-var-lib-matrix\\x2dsynapse.mount" ]; }; serviceConfig.SupplementaryGroups = [ "keys" ]; }; systemd.services.matrix-sliding-sync = { serviceConfig = { DynamicUser = lib.mkForce false; User = "matrix-synapse"; Group = "matrix-synapse"; RuntimeDirectory = lib.mkForce "matrix-synapse"; SupplementaryGroups = [ "keys" ]; }; unitConfig = { BindsTo = [ "persist-zfast-var-lib-matrix\\x2dsliding\\x2dsync.mount" "var-lib-matrix\\x2dsliding\\x2dsync.mount" ]; After = lib.mkForce [ "matrix-synapse.service" "postgresql.service" "var-lib-matrix\\x2dsliding\\x2dsync.mount" "persist-zfast-var-lib-matrix\\x2dsliding\\x2dsync.mount" ]; }; }; secrets.keys."matrix/ldap_password" = { permissions = "0400"; user = "matrix-synapse"; group = "matrix-synapse"; text = config.myEnv.tools.matrix.ldap.password; }; secrets.keys."matrix/signing.key" = { permissions = "0400"; user = "matrix-synapse"; group = "matrix-synapse"; text = "{{ .matrix.signing_key }}"; }; secrets.keys."matrix/homeserver_secrets.yaml" = { permissions = "0400"; user = "matrix-synapse"; group = "matrix-synapse"; # Beware, yaml keys are merged at top level, not deep text = '' password_config: enabled: true pepper: "{{ .matrix.password_pepper }}" macaroon_secret_key: "{{ .matrix.macaroon_secret_key }}" ''; }; secrets.keys."matrix/sliding-sync" = { permissions = "0400"; user = "matrix-synapse"; group = "matrix-synapse"; text = '' SYNCV3_SECRET={{ .matrix.sliding_sync_secret }} ''; }; }; }