The Complete Computing Environment

Matrix Synapse

LifeTechEmacsTopicsArcology

I've been in the Matrix.org Ecosystem for a while and use some bridging software to Illegally integrate other chat networks in to a single client which syncs between my phone and desktops and etc.

Synapse on NixOS

This is an Arroyo NixOS module used in My Wobserver Configuration.

{ ... }:

let useSSL = false; # for VM testing... should make this an option...
    clientConfig."m.homeserver".base_url = "https://matrix.fontkeming.fail/";
    serverConfig."m.server" = "matrix.fontkeming.fail:443";
    mkWellKnown = data: ''
      # 
      add_header Content-Type application/json;
      add_header Access-Control-Allow-Origin *;
      return 200 '${builtins.toJSON data}';
    '';
in {
  imports = [
    <arroyo/nixos/matrix-puppet-discord.nix>
    <arroyo/nixos/heisenbridge.nix>
    <arroyo/nixos/matrix-prometheus.nix>
  ];

  services.postgresql.ensureDatabases = ["matrix-synapse"];
  services.postgresql.ensureUsers = [
    {
      name = "matrix-synapse";
      ensurePermissions = {
        "DATABASE synapse" = "ALL PRIVILEGES";
      };
    }
  ];

  users.users.matrix-synapse = {
    isSystemUser = true;
    createHome = true;
    home = "/srv/matrix-synapse";
    group = "matrix-synapse";
  };

  services.nginx.virtualHosts."matrix.fontkeming.fail" = {
    listen = [
      { addr = "0.0.0.0"; port = 8448; }
      { addr = "0.0.0.0"; port = 80; }
    ];
    forceSSL = useSSL;

    locations."/_synapse/client".proxyPass = "http://127.0.0.1:8008";

    locations."/_matrix".proxyPass = "http://127.0.0.1:8008";
    locations."/_matrix".extraConfig = ''
      client_max_body_size 16m;
      access_log off;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $host;
      proxy_connect_timeout 600s;
      proxy_read_timeout 600s;
    '';

    locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
    locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
  };

  services.matrix-synapse = {
    enable = true;
    dataDir = "/srv/matrix-synapse";
    settings = {
      server_name = "kickass.systems";
      public_baseurl = "https://matrix.fontkeming.fail";

      enable_registration = false;

      enable_metrics = true;
      report_stats = true;

      url_preview_enabled = true;

      database.name = "psycopg2";
      database.args.user = "matrix-synapse";
      database.args.database = "synapse";
      # god damnit ensureDatabases gives me a utf8
      database.allow_unsafe_locale = true;

      secondary_directory_servers = [
        "matrix.org"
        "cybre.space"
      ];

      retention = {
        default_policy = {
          min_lifetime = "1d";
          max_lifetime = "26w";
        };
        allowed_liftetime_min = "1d";
        allowed_liftetime_max = "1y";
      };

      presence.enabled = false;

      thumbnail_sizes = [
        { width = 24;
          height = 24;
          method = "crop"; }
        { width = 32;
          height = 32;
          method = "crop"; }
        { width = 96;
          height = 96;
          method = "crop"; }
        { width = 320;
          height = 240;
          method = "scale"; }
        { width = 640;
          height = 480;
          method = "scale"; }
        { width = 800;
          height = 600;
          method = "scale"; }
      ];

      listeners = [
        { bind_addresses = [ "127.0.0.1" ] ;
          port = 8008;
          resources = [
            { compress = true;
              names = [ "client" "metrics" ]; }
            { compress = false;
              names = [ "federation" ]; } ];
          tls = false;
          type = "http";
          x_forwarded = true;
        } 
      ];
    };
  };
}

mx-puppet-discord

mx-puppet-discord allows a savvy Discord user to log in to their discord guilds and chat in them through a Matrix client. Definitely don't do a crimes with it, I'm sure I'll be banned for this indiscretion some day but this bridging is the core value proposition of Matrix for me.

It's primarily operated via chat commands. I am mostly trusting the default nixpkgs configuration.

One thing I had to do to make this configuration work is to manually move that app_service_config_file from /var/lib/mx-puppet-discord/discord-registration.yaml. Since it's written by a SystemD DynamicUser, it's not clear to me how to write this file with a group ID that Synapse shares..

{ ... }:

{
  services.mx-puppet-discord.enable = true;
  # services.matrix-synapse.extraConfig = ''
  # '';
  services.matrix-synapse.settings.app_service_config_files = ["/srv/matrix-synapse/discord-registration.yaml"];
  services.mx-puppet-discord.settings = {
    bridge = {
      port = 8091;
      bindAddress = "0.0.0.0";
      domain = "kickass.systems";
      homeserverUrl = "http://127.0.0.1:8008";
    };
    provisioning.whitelist = ["@rrix:kickass\\.systems"];
  };
}

Heisenbridge

Heisenbridge is a Matrix app-service designed to be used as a single-user "bouncer" style IRC client rather than a "room mirror" like matrix-appservice-irc.

It's primarily operated via chat commands. I'm basically trusting the nixpkgs configuration.

{ ... }:

{
  services.matrix-synapse.settings.app_service_config_files = ["/var/lib/heisenbridge/registration.yml"];
  users.users.matrix-synapse.extraGroups = ["heisenbridge"]; # to access registration file

  services.heisenbridge = {
    enable = true;
    debug = true;
    homeserver = "http://localhost:8008";
    owner = "@rrix:kickass.systems";
  };
}

Synapse Prometheus Recording Rules

{ ... }:

{
  services.prometheus.ruleFiles = [
    <arroyo/files/synapse.rules>
  ];
}
groups:
- name: synapse_federation_transaction_queue_pendingEdus:total
  rules:
  - record: synapse_federation_transaction_queue_pendingEdus:total
    expr:  sum(synapse_federation_transaction_queue_pendingEdus or absent(synapse_federation_transaction_queue_pendingEdus)*0)

- name: synapse_federation_transaction_queue_pendingPdus:total
  rules:
  - record: synapse_federation_transaction_queue_pendingPdus:total
    expr:  sum(synapse_federation_transaction_queue_pendingPdus or absent(synapse_federation_transaction_queue_pendingPdus)*0)

- name: synapse_http_server_requests:methodservlet
  rules:
  - record: synapse_http_server_requests:method
    expr: sum(synapse_http_server_requests) by (method)
    labels:
      servlet: ""

- name: synapse_http_server_requests:servletmethod
  rules:
  - record: synapse_http_server_requests:servlet
    expr:  sum(synapse_http_server_requests) by (servlet)
    labels:
      method: ""


- name: synapse_http_server_requests:totalservlet
  rules:
  - record: synapse_http_server_requests:total
    expr:  sum(synapse_http_server_requests:by_method) by (servlet)
    labels:
      servlet: ""


- name: synapse_cache:hit_ratio_5m
  rules:
  - record: synapse_cache:hit_ratio_5m
    expr:  rate(synapse_util_caches_cache:hits[5m]) / rate(synapse_util_caches_cache:total[5m])

- name: synapse_cache:hit_ratio_30s
  rules:
  - record: synapse_cache:hit_ratio_30s
    expr:  rate(synapse_util_caches_cache:hits[30s]) / rate(synapse_util_caches_cache:total[30s])


- name: synapse_federation_client_senttypeEDU
  rules:
  - record: synapse_federation_client_sent
    expr:  synapse_federation_client_sent_edus + 0
    labels:
      type: EDU

- name: synapse_federation_client_senttypePDU
  rules:
  - record: synapse_federation_client_sent
    expr:  synapse_federation_client_sent_pdu_destinations:count + 0
    labels:
      type: PDU

- name: synapse_federation_client_senttypeQuery
  rules:
  - record: synapse_federation_client_sent
    expr:  sum(synapse_federation_client_sent_queries) by (job)
    labels:
      type: Query


- name: synapse_federation_server_receivedtypeEDU
  rules:
  - record: synapse_federation_server_received
    expr:  synapse_federation_server_received_edus + 0
    labels:
      type: EDU

- name: synapse_federation_server_receivedtypePDU
  rules:
  - record: synapse_federation_server_received
    expr:  synapse_federation_server_received_pdus + 0
    labels:
      type: PDU

- name: synapse_federation_server_receivedtypeQuery
  rules:
  - record: synapse_federation_server_received
    expr:  sum(synapse_federation_server_received_queries) by (job)
    labels:
      type: Query


- name: synapse_federation_transaction_queue_pendingtypeEDU
  rules:
  - record: synapse_federation_transaction_queue_pending
    expr:  synapse_federation_transaction_queue_pending_edus + 0
    labels:
      type: EDU

- name: synapse_federation_transaction_queue_pendingtypePDU
  rules:
  - record: synapse_federation_transaction_queue_pending
    expr:  synapse_federation_transaction_queue_pending_pdus + 0
    labels:
      type: PDU

NEXT matrix-dimension

NEXT mx-puppet-slack

NEXT validate database setup

NEXT evaluate mautrix services?

NEXT evaluate matrix-homeserver

https://github.com/queezle42/matrix-homeserver

This seems nice maybe