complete-computing-environment/matrix.org

534 lines
16 KiB
Org Mode

:PROPERTIES:
:ID: cce/wobserver/matrix
:ROAM_ALIASES: "Matrix on the Wobserver" "Matrix Server"
:END:
#+TITLE: Matrix Synapse
#+FILETAGS: :Project:CCE:Wobserver:
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARCOLOGY_KEY: cce/wobserver/matrix
#+AUTO_TANGLE: t
I've been in the [[id:matrix_org_ecosystem][Matrix.org Ecosystem]] for a while and use some bridging software to [[roam:Illegally]] integrate other chat networks in to a single client which syncs between my phone and desktops and etc.
* Synapse on NixOS
:PROPERTIES:
:ID: 20220511T200359.639856
:END:
This is an [[id:arroyo/nixos][Arroyo NixOS]] module used in [[id:20211120T220054.226284][My Wobserver Configuration]].
#+ARROYO_NIXOS_MODULE: nixos/matrix.nix
#+ARROYO_SYSTEM_ROLE: server
#+begin_src nix :tangle ~/arroyo-nix/nixos/matrix.nix
{ ... }:
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 = [
./mautrix-discord-svc.nix
./matrix-puppet-discord.nix
./heisenbridge.nix
./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";
};
caches = {
sync_response_cache_duration = "60m";
cache_autotuning.max_cache_memory_usage = "2048M";
cache_autotuning.target_cache_memory_usage = "1024M";
cache_autotuning.min_cache_ttl = "15m";
};
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;
}
];
};
};
}
#+end_src
* CANCELLED mx-puppet-discord
:PROPERTIES:
:ID: 20220218T215648.615157
:ROAM_REFS: https://github.com/matrix-discord/mx-puppet-discord
:END:
:LOGBOOK:
- State "CANCELLED" from [2024-01-11 Thu 16:15]
:END:
=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 [[https://github.com/matrix-discord/mx-puppet-discord#linking-your-discord-account][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 [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][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 [[https://0pointer.net/blog/dynamic-users-with-systemd.html][SystemD =DynamicUser=]], it's not clear to me how to write this file with a group ID that Synapse shares..
This isn't used any more, see below.
#+begin_src nix
{ options, ... }:
{
services.mx-puppet-discord.enable = false;
# 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"];
# };
}
#+end_src
* =mautrix-discord=
:PROPERTIES:
:ID: 20240111T161523.732094
:ROAM_REFS: https://docs.mau.fi/bridges/go/discord/index.html
:END:
i'm using a different matrix-discord bridge now, the same one the beeper folks use. Still have to do the song-and-dance moving the registration file out of the private =/var/lib= state directory, but that's fine. Deploy this once, it'll fail to start but it'll write the =/var/lib/mautrix-discord/discord-registration.yaml= file which you'll just =cp /var/lib/mautrix-discord/discord-registration.yaml /var/lib/matrix-synapse/or/whatever/discord-registration.yaml= and make sure it makes the location below, and deploy again! Then just start a chat with =@discordbot:example.com= and set up the bridge.
#+begin_src nix :tangle ~/arroyo-nix/nixos/matrix-puppet-discord.nix
{ options, ... }:
{
services.mx-puppet-discord.enable = false;
services.mautrix-discord.enable = true;
services.mautrix-discord.settings = options.services.mautrix-discord.settings.default // {
homeserver.address = "http://localhost:8008";
homeserver.domain = "kickass.systems";
bridge.delivery_receipts = true;
bridge.federate_rooms = false;
bridge.permissions."*" = "relay";
bridge.permissions."kickass.systems" = "user";
bridge.permissions."@rrix:kickass.systems" = "admin";
};
services.matrix-synapse.settings.app_service_config_files = ["/srv/matrix-synapse/discord-registration.yaml"];
}
#+end_src
** This NixOS Module
:PROPERTIES:
:ID: 20240122T100247.845520
:END:
#+begin_src nix :tangle ~/arroyo-nix/nixos/mautrix-discord-svc.nix
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.mautrix-discord;
dataDir = "/var/lib/mautrix-discord";
registrationFile = "${dataDir}/discord-registration.yaml";
settingsFormat = pkgs.formats.yaml { };
settingsFile = settingsFormat.generate "mautrix-discord-config.yaml" cfg.settings;
runtimeSettingsFile = "${dataDir}/config.yaml";
in {
options = {
services.mautrix-discord = {
enable = mkEnableOption (mdDoc "Matrix to Discord hybrid puppeting/relaybot bridge");
package = mkOption {
type = types.package;
default = pkgs.mautrix-discord;
defaultText = literalExpression "pkgs.mautrix-discord";
description = mdDoc ''
The mautrix-discord package to use.
'';
};
settings = mkOption rec {
apply = recursiveUpdate default;
inherit (settingsFormat) type;
default = {
homeserver = {
software = "standard";
};
appservice = rec {
database = {
type = "sqlite3";
uri = "file:${dataDir}/mautrix-discord.db";
};
port = 8080;
address = "http://localhost:${toString port}";
};
bridge = {
permissions."*" = "relay";
double_puppet_server_map = {};
login_shared_secret_map = {};
};
logging = {
directory = "";
file_name_format = ""; # Disable file logging
file_date_format = "2006-01-02";
file_mode = 384;
timestamp_format = "Jan _2, 2006 15:04:05";
print_level = "warn";
print_json = false;
file_json = false;
};
};
description = mdDoc ''
Bridge configuration as a Nix attribute set.
Configuration options should match those described in
[example-config.yaml](https://github.com/mautrix/discord/blob/main/example-config.yaml).
'';
};
serviceDependencies = mkOption {
type = with types; listOf str;
default = optional config.services.matrix-synapse.enable "matrix-synapse.service";
defaultText = literalExpression ''
optional config.services.matrix-synapse.enable "matrix-synapse.service"
'';
description = mdDoc ''
List of Systemd services to require and wait for when starting the application service.
'';
};
};
};
config = mkIf cfg.enable {
systemd.services.mautrix-discord = {
description = "Matrix to Discord hybrid puppeting/relaybot bridge";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
after = [ "network-online.target" ] ++ cfg.serviceDependencies;
preStart = ''
# Generate the appservice's registration file if absent
if [ ! -f '${registrationFile}' ]; then
${cfg.package}/bin/mautrix-discord \
--config '${settingsFile}' \
--registration '${registrationFile}' \
--generate-registration
fi
old_umask=$(umask)
umask 0177
# Extract the AS and HS tokens from the registration and add them to the settings file
${pkgs.yq}/bin/yq -y ".appservice.as_token = $(${pkgs.yq}/bin/yq .as_token ${registrationFile}) | .appservice.hs_token = $(${pkgs.yq}/bin/yq .hs_token ${registrationFile})" ${settingsFile} > ${runtimeSettingsFile}
umask $old_umask
'';
serviceConfig = {
Type = "simple";
Restart = "always";
ProtectSystem = "strict";
ProtectHome = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
DynamicUser = true;
PrivateTmp = true;
WorkingDirectory = cfg.package;
StateDirectory = baseNameOf dataDir;
UMask = "0027";
ExecStart = ''
${cfg.package}/bin/mautrix-discord \
--config ${runtimeSettingsFile} \
--no-update
'';
};
};
};
meta.maintainers = with maintainers; [ robin ];
}
#+end_src
* Heisenbridge
:PROPERTIES:
:ID: 20220218T215521.617327
:ROAM_REFS: https://github.com/hifi/heisenbridge
:END:
Heisenbridge is a [[id:matrix_org_ecosystem][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 [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][nixpkgs]] configuration.
#+begin_src nix :tangle ~/arroyo-nix/nixos/heisenbridge.nix
{ ... }:
{
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";
};
}
#+end_src
* Synapse Prometheus Recording Rules
:PROPERTIES:
:END:
#+begin_src nix :tangle ~/arroyo-nix/nixos/matrix-prometheus.nix
{ ... }:
{
services.prometheus.ruleFiles = [
<arroyo/files/synapse.rules>
];
}
#+end_src
#+begin_src yaml :tangle ~/arroyo-nix/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
#+end_src
* NEXT mautrix-signal
* 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