Matrix

From CSCWiki
Revision as of 21:50, 17 September 2025 by K95ma (talk | contribs) (+)
Jump to navigation Jump to search

We are currently setting up a test server for Matrix. We use Synapse. If everything goes well, we will set up a production Matrix server.

Server Setup

We are currently running Matrix on a Proxmox LXE container on citric-acid. Ask Siracha for the credentials to access Proxmox and the VM.

Matrix Installation

We are using NixOS, so use the following config (might be a bit messy) to setup both Synapse, Nginx, and PostgreSQL:

Note: We could have used recommendedProxySettings = true which sets most of the X-Forwarded-For headers correctly. However, this is a reverse proxy behind a reverse proxy (Nginx on citric acid -> Nginx on the container -> Synapse) so X-Forwarded-Proto has to be always set to https. I'm sure there is a better way to do this.

{ pkgs, lib, config, ... }:
let
  fqdn = "matrix.${config.networking.domain}";
  clientConfig = {
    "m.homeserver".base_url = "https://${fqdn}";
    "m.identity_server" = {};
  };
  serverConfig."m.server" = "${fqdn}:443";
  mkWellKnown = data: ''
    add_header Content-Type application/json;
    add_header Access-Control-Allow-Origin *;
    return 200 '${builtins.toJSON data}';
  '';
  extraCfg = pkgs.writeText "synapse-extra-config.yaml" ''
  '';
in {
  networking.firewall = {
    enable = true;
    allowedTCPPorts = [ 80 8008 ];
  };
  networking.domain = "csclub.uwaterloo.ca";

  services.postgresql = {
    enable = true;
    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";
    '';
    dataDir = "/data/postgresql";
  };

  services.nginx = {
    enable = true;
    # recommendedProxySettings = true;
    virtualHosts = {
      "csclub.uwaterloo.ca" = {
        locations."/".extraConfig = ''
          return 404;
        '';
        locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
        locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
      };
      "${fqdn}" = {
        locations."/".extraConfig = ''
          return 404;
        '';
        locations."/_matrix".proxyPass = "http://[::1]:8008";
        locations."/_matrix".extraConfig = ''
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto https;
    proxy_set_header        X-Forwarded-Host $host;
    proxy_set_header        X-Forwarded-Server $host;
        '';
        locations."/_synapse/client".proxyPass = "http://[::1]:8008";
        locations."/_synapse/client".extraConfig = ''
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto https;
    proxy_set_header        X-Forwarded-Host $host;
    proxy_set_header        X-Forwarded-Server $host;
        '';
      };
    };
  };

  services.matrix-synapse = {
    enable = true;
    extraConfigFiles = [ extraCfg ];
    dataDir = "/data/matrix-synapse";
    settings = {
      server_name = config.networking.domain;
      public_baseurl = "https://matrix.csclub.uwaterloo.ca/";
      listeners = [
        {
          port = 8008;
          bind_addresses = [ "::1" ];
          type = "http";
          tls = false;
          x_forwarded = true;
          resources = [
            {
                names = [ "client" ]; # no federation
                compress = true;
            }
          ];
        }
      ];

      oidc_providers = [
        {
           idp_id = "keycloak";
           idp_name = "CSC";
           issuer = "https://keycloak.csclub.uwaterloo.ca/realms/csc";
           client_id = "synapse";
           client_secret = "xxxx"; # fill the client secret from keycloak here
           scopes = [ "openid" "profile" ];
           user_mapping_provider.config = {
                localpart_template = "{{ user.preferred_username }}";
                display_name_template = "{{ user.name }}";
           };

        }
      ];
      registration_shared_secret = "xxxxx";
      enable_registration = true;
      enable_registration_captcha = false;
      registration_requires_token = true;
    };
  };
}

Testing

Go to https://app.cinny.in/login/matrix.csclub.uwaterloo.ca, and click "Continue with CSC".