534 lines
16 KiB
Org Mode
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
|