blob: d3d46f5870e29370436859ada0d23abc0eabaa22 [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 Greyb64b5e92023-08-20 21:53:37 +000034 turn_uris = [
35
36 /* "turn:turn.coded.codes:3478?transport=udp"
37 "turn:turn.coded.codes:3478?transport=tcp"
38 "turns:turn.coded.codes:5349?transport=udp"
39 "turns:turn.coded.codes:5349?transport=tcp" */
40 ]; # Please use matrix.org turn
41 # turn_shared_secret = "!!turn_shared_secret!!";
Skyler Greya78aa672023-05-20 13:48:18 +020042 };
43 };
44
Skyler Greyb64b5e92023-08-20 21:53:37 +000045 networking.firewall.allowedTCPPorts = [ 3478 5349 ];
46 networking.firewall.allowedUDPPorts = [ 3478 5349 ];
47
Skyler Grey874a2a82023-06-08 12:29:28 +020048 services.mjolnir = {
49 enable = true;
50
51 settings = {
52 autojoinOnlyIfManager = true;
53 automaticallyRedactForReasons = [ "nsfw" "gore" "spam" "harassment" "hate" ];
54 recordIgnoredInvites = true;
55 admin.enableMakeRoomAdminCommand = true;
56 allowNoPrefix = true;
57 protections.wordlist.words = [ ];
Skyler Greyaaed7b12023-06-14 22:45:49 +020058 protectedRooms = [ "https://matrix.to/#/#global:coded.codes" ];
Skyler Grey874a2a82023-06-08 12:29:28 +020059 };
60
61 pantalaimon = {
62 enable = true;
63 username = "system";
64 passwordFile = config.sops.secrets.mjolnir_password.path;
65 options = {
66 ssl = false;
67 listenAddress = "127.0.0.1";
68 };
69 };
70
71 homeserverUrl = "http://localhost:4527";
72
73 managementRoom = "#moderation-commands:coded.codes";
74 };
75
Skyler Greyb64b5e92023-08-20 21:53:37 +000076 services.coturn = {
77 enable = false;
78
79 use-auth-secret = true;
80 # static-auth-secret-file = config.sops.secrets.turn_shared_secret.path;
81
82 realm = "turn.coded.codes";
83
84 no-tcp-relay = true;
85
86 no-cli = true;
87
88 extraConfig = ''
89 external-ip=turn.coded.codes
90 '';
91 };
92
Skyler Grey8e32c832023-05-20 22:54:30 +020093 sops.secrets = {
Skyler Greyb64b5e92023-08-20 21:53:37 +000094 #turn_shared_secret = {
95 # mode = "0440";
96 # owner = "turnserver";
97 # group = "matrix-synapse";
98 # sopsFile = ../secrets/matrix.json;
99 # format = "json";
100 #};
Skyler Grey8e32c832023-05-20 22:54:30 +0200101 registration_shared_secret = {
Skyler Greya78aa672023-05-20 13:48:18 +0200102 mode = "0400";
Skyler Grey8e32c832023-05-20 22:54:30 +0200103 owner = config.users.users.root.name;
104 group = config.users.users.nobody.group;
105 sopsFile = ../secrets/matrix.json;
106 format = "json";
107 };
108 matrix_private_key = {
109 mode = "0600";
110 owner = config.users.users.matrix-synapse.name;
111 group = config.users.users.matrix-synapse.group;
Skyler Greya78aa672023-05-20 13:48:18 +0200112 sopsFile = ../secrets/matrix_private_key.pem;
113 format = "binary";
Skyler Grey8e32c832023-05-20 22:54:30 +0200114 path = config.services.matrix-synapse.settings.signing_key_path;
Skyler Greya78aa672023-05-20 13:48:18 +0200115 };
Skyler Grey874a2a82023-06-08 12:29:28 +0200116 mjolnir_password = {
117 mode = "0600";
118 owner = config.users.users.mjolnir.name;
119 group = config.users.users.mjolnir.group;
120 sopsFile = ../secrets/matrix.json;
121 format = "json";
122 };
Skyler Greya78aa672023-05-20 13:48:18 +0200123 };
Skyler Grey874a2a82023-06-08 12:29:28 +0200124}
125 (
Skyler Greya78aa672023-05-20 13:48:18 +0200126 let
Skyler Grey874a2a82023-06-08 12:29:28 +0200127 isDerived = base != null;
Skyler Greya78aa672023-05-20 13:48:18 +0200128 in
Skyler Grey874a2a82023-06-08 12:29:28 +0200129 if isDerived
130 # We cannot use mkIf as both sides are evaluated no matter the condition value
131 # Given we use base as an attrset, mkIf will error if base is null in here
132 then
133 let
134 synapse_cfgfile = config.services.matrix-synapse.configFile;
135 in
136 {
137 scalpel.trafos."synapse.yaml" = {
138 source = toString synapse_cfgfile;
139 matchers."registration_shared_secret".secret =
140 config.sops.secrets.registration_shared_secret.path;
Skyler Greyb64b5e92023-08-20 21:53:37 +0000141 # matchers."turn_shared_secret".secret =
142 # config.sops.secrets.turn_shared_secret.path;
Skyler Grey874a2a82023-06-08 12:29:28 +0200143 owner = config.users.users.matrix-synapse.name;
144 group = config.users.users.matrix-synapse.group;
145 mode = "0400";
146 };
Skyler Greya78aa672023-05-20 13:48:18 +0200147
Skyler Grey874a2a82023-06-08 12:29:28 +0200148 systemd.services.matrix-synapse.serviceConfig.ExecStart = lib.mkForce (
149 builtins.replaceStrings
150 [ "${synapse_cfgfile}" ]
151 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
152 "${base.config.systemd.services.matrix-synapse.serviceConfig.ExecStart}"
153 );
Skyler Grey8e32c832023-05-20 22:54:30 +0200154
Skyler Grey874a2a82023-06-08 12:29:28 +0200155 systemd.services.matrix-synapse.preStart = lib.mkForce (
156 builtins.replaceStrings
157 [ "${synapse_cfgfile}" ]
158 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
159 "${base.config.systemd.services.matrix-synapse.preStart}"
160 );
Skyler Grey8e32c832023-05-20 22:54:30 +0200161
Skyler Grey874a2a82023-06-08 12:29:28 +0200162 systemd.services.matrix-synapse.restartTriggers = [ synapse_cfgfile ];
Skyler Greyb3516c22023-05-24 19:17:11 +0200163
Skyler Grey874a2a82023-06-08 12:29:28 +0200164 environment.systemPackages =
165 with lib; let
166 cfg = config.services.matrix-synapse;
167 registerNewMatrixUser =
168 let
169 isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
170 listener =
171 lib.findFirst
172 (
173 listener: lib.any
174 (
175 resource: lib.any
176 (
177 name: name == "client"
178 )
179 resource.names
180 )
181 listener.resources
182 )
183 (lib.last cfg.settings.listeners)
184 cfg.settings.listeners;
185 # FIXME: Handle cases with missing client listener properly,
186 # don't rely on lib.last, this will not work.
Skyler Grey8e32c832023-05-20 22:54:30 +0200187
Skyler Grey874a2a82023-06-08 12:29:28 +0200188 # add a tail, so that without any bind_addresses we still have a useable address
189 bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]);
190 listenerProtocol =
191 if listener.tls
192 then "https"
193 else "http";
194 in
195 pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
196 exec ${cfg.package}/bin/register_new_matrix_user \
197 $@ \
198 ${lib.concatMapStringsSep " " (x: "-c ${x}") ([
199 config.scalpel.trafos."synapse.yaml".destination ] ++ cfg.extraConfigFiles)} \
200 "${listenerProtocol}://${
201 if (isIpv6 bindAddress) then
202 "[${bindAddress}]"
203 else
204 "${bindAddress}"
205 }:${builtins.toString listener.port}/"
206 '';
207 in
208 [ (lib.meta.hiPrio registerNewMatrixUser) ];
209 }
210 else { }
211 )