blob: ec10a0359222e856b6aa2630c11de350fdc5cf23 [file] [log] [blame]
Skyler Greya78aa672023-05-20 13:48:18 +02001{ base, config, lib, pkgs, ... }:
Skyler Grey19f9fa22023-05-24 17:51:24 +02002lib.recursiveUpdate
Skyler Greya78aa672023-05-20 13:48:18 +02003{
Skyler Grey8e32c832023-05-20 22:54:30 +02004 services.matrix-synapse = {
Skyler Greya78aa672023-05-20 13:48:18 +02005 enable = true;
Skyler Grey8e32c832023-05-20 22:54:30 +02006 withJemalloc = true;
Skyler Greya78aa672023-05-20 13:48:18 +02007
Skyler Grey874a2a82023-06-08 12:29:28 +02008 plugins = with config.services.matrix-synapse.package.plugins; [
9 matrix-synapse-mjolnir-antispam
10 ];
11
Skyler Grey1144d002023-05-21 00:17:29 +020012 settings = rec {
Skyler Grey8e32c832023-05-20 22:54:30 +020013 server_name = "coded.codes";
Skyler Grey1144d002023-05-21 00:17:29 +020014 auto_join_rooms = [ "#general:${server_name}" ];
Skyler Grey8e32c832023-05-20 22:54:30 +020015 enable_registration = true;
16 registration_requires_token = true;
17 registration_shared_secret = "!!registration_shared_secret!!";
18 public_baseurl = "https://matrix-backend.coded.codes/";
19 max_upload_size = "100M";
20 listeners = [{
21 x_forwarded = true;
22 tls = false;
23 resources = [{
24 names = [
25 "client"
26 "federation"
27 ];
28 compress = true;
29 }];
30 port = 4527;
31 }];
32 enable_metrics = true;
33 database.args.database = "synapse";
Skyler Greya78aa672023-05-20 13:48:18 +020034 };
35 };
36
Skyler Grey874a2a82023-06-08 12:29:28 +020037 services.mjolnir = {
38 enable = true;
39
40 settings = {
41 autojoinOnlyIfManager = true;
42 automaticallyRedactForReasons = [ "nsfw" "gore" "spam" "harassment" "hate" ];
43 recordIgnoredInvites = true;
44 admin.enableMakeRoomAdminCommand = true;
45 allowNoPrefix = true;
46 protections.wordlist.words = [ ];
47 };
48
49 pantalaimon = {
50 enable = true;
51 username = "system";
52 passwordFile = config.sops.secrets.mjolnir_password.path;
53 options = {
54 ssl = false;
55 listenAddress = "127.0.0.1";
56 };
57 };
58
59 homeserverUrl = "http://localhost:4527";
60
61 managementRoom = "#moderation-commands:coded.codes";
62 };
63
Skyler Grey8e32c832023-05-20 22:54:30 +020064 sops.secrets = {
65 registration_shared_secret = {
Skyler Greya78aa672023-05-20 13:48:18 +020066 mode = "0400";
Skyler Grey8e32c832023-05-20 22:54:30 +020067 owner = config.users.users.root.name;
68 group = config.users.users.nobody.group;
69 sopsFile = ../secrets/matrix.json;
70 format = "json";
71 };
72 matrix_private_key = {
73 mode = "0600";
74 owner = config.users.users.matrix-synapse.name;
75 group = config.users.users.matrix-synapse.group;
Skyler Greya78aa672023-05-20 13:48:18 +020076 sopsFile = ../secrets/matrix_private_key.pem;
77 format = "binary";
Skyler Grey8e32c832023-05-20 22:54:30 +020078 path = config.services.matrix-synapse.settings.signing_key_path;
Skyler Greya78aa672023-05-20 13:48:18 +020079 };
Skyler Grey874a2a82023-06-08 12:29:28 +020080 mjolnir_password = {
81 mode = "0600";
82 owner = config.users.users.mjolnir.name;
83 group = config.users.users.mjolnir.group;
84 sopsFile = ../secrets/matrix.json;
85 format = "json";
86 };
Skyler Greya78aa672023-05-20 13:48:18 +020087 };
Skyler Grey874a2a82023-06-08 12:29:28 +020088}
89 (
Skyler Greya78aa672023-05-20 13:48:18 +020090 let
Skyler Grey874a2a82023-06-08 12:29:28 +020091 isDerived = base != null;
Skyler Greya78aa672023-05-20 13:48:18 +020092 in
Skyler Grey874a2a82023-06-08 12:29:28 +020093 if isDerived
94 # We cannot use mkIf as both sides are evaluated no matter the condition value
95 # Given we use base as an attrset, mkIf will error if base is null in here
96 then
97 let
98 synapse_cfgfile = config.services.matrix-synapse.configFile;
99 in
100 {
101 scalpel.trafos."synapse.yaml" = {
102 source = toString synapse_cfgfile;
103 matchers."registration_shared_secret".secret =
104 config.sops.secrets.registration_shared_secret.path;
105 owner = config.users.users.matrix-synapse.name;
106 group = config.users.users.matrix-synapse.group;
107 mode = "0400";
108 };
Skyler Greya78aa672023-05-20 13:48:18 +0200109
Skyler Grey874a2a82023-06-08 12:29:28 +0200110 systemd.services.matrix-synapse.serviceConfig.ExecStart = lib.mkForce (
111 builtins.replaceStrings
112 [ "${synapse_cfgfile}" ]
113 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
114 "${base.config.systemd.services.matrix-synapse.serviceConfig.ExecStart}"
115 );
Skyler Grey8e32c832023-05-20 22:54:30 +0200116
Skyler Grey874a2a82023-06-08 12:29:28 +0200117 systemd.services.matrix-synapse.preStart = lib.mkForce (
118 builtins.replaceStrings
119 [ "${synapse_cfgfile}" ]
120 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
121 "${base.config.systemd.services.matrix-synapse.preStart}"
122 );
Skyler Grey8e32c832023-05-20 22:54:30 +0200123
Skyler Grey874a2a82023-06-08 12:29:28 +0200124 systemd.services.matrix-synapse.restartTriggers = [ synapse_cfgfile ];
Skyler Greyb3516c22023-05-24 19:17:11 +0200125
Skyler Grey874a2a82023-06-08 12:29:28 +0200126 environment.systemPackages =
127 with lib; let
128 cfg = config.services.matrix-synapse;
129 registerNewMatrixUser =
130 let
131 isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
132 listener =
133 lib.findFirst
134 (
135 listener: lib.any
136 (
137 resource: lib.any
138 (
139 name: name == "client"
140 )
141 resource.names
142 )
143 listener.resources
144 )
145 (lib.last cfg.settings.listeners)
146 cfg.settings.listeners;
147 # FIXME: Handle cases with missing client listener properly,
148 # don't rely on lib.last, this will not work.
Skyler Grey8e32c832023-05-20 22:54:30 +0200149
Skyler Grey874a2a82023-06-08 12:29:28 +0200150 # add a tail, so that without any bind_addresses we still have a useable address
151 bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]);
152 listenerProtocol =
153 if listener.tls
154 then "https"
155 else "http";
156 in
157 pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
158 exec ${cfg.package}/bin/register_new_matrix_user \
159 $@ \
160 ${lib.concatMapStringsSep " " (x: "-c ${x}") ([
161 config.scalpel.trafos."synapse.yaml".destination ] ++ cfg.extraConfigFiles)} \
162 "${listenerProtocol}://${
163 if (isIpv6 bindAddress) then
164 "[${bindAddress}]"
165 else
166 "${bindAddress}"
167 }:${builtins.toString listener.port}/"
168 '';
169 in
170 [ (lib.meta.hiPrio registerNewMatrixUser) ];
171 }
172 else { }
173 )