blob: 74413900491a0b57ef77bdf6e28d759cf74d4a81 [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;
Skyler Greyd18587c2023-10-09 07:25:36 +000017 allow_public_rooms_over_federation = true;
18 allow_device_name_lookup_over_federation = true;
Skyler Grey8e32c832023-05-20 22:54:30 +020019 registration_shared_secret = "!!registration_shared_secret!!";
20 public_baseurl = "https://matrix-backend.coded.codes/";
21 max_upload_size = "100M";
22 listeners = [{
23 x_forwarded = true;
24 tls = false;
25 resources = [{
26 names = [
27 "client"
28 "federation"
29 ];
30 compress = true;
31 }];
32 port = 4527;
33 }];
34 enable_metrics = true;
35 database.args.database = "synapse";
Skyler Greyb64b5e92023-08-20 21:53:37 +000036 turn_uris = [
37
38 /* "turn:turn.coded.codes:3478?transport=udp"
39 "turn:turn.coded.codes:3478?transport=tcp"
40 "turns:turn.coded.codes:5349?transport=udp"
41 "turns:turn.coded.codes:5349?transport=tcp" */
42 ]; # Please use matrix.org turn
43 # turn_shared_secret = "!!turn_shared_secret!!";
Skyler Greyd18587c2023-10-09 07:25:36 +000044
45 log_config = lib.pipe {
46 version = 1;
47 formatters = {
48 precise = {
49 format =
50 "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
51 };
52 };
53 handlers = {
54 console = {
55 class = "logging.StreamHandler";
56 formatter = "precise";
57 };
58 };
59 loggers = { "synapse.storage.SQL" = { level = "WARNING"; }; };
60 root = {
61 level = "ERROR";
62 handlers = [ "console" ];
63 };
64 "disable_existing_loggers" = false;
65 } [
66 builtins.toJSON
67 (builtins.toFile "logcfg.yaml")
68 ];
Skyler Greya78aa672023-05-20 13:48:18 +020069 };
70 };
71
Skyler Greyb64b5e92023-08-20 21:53:37 +000072 networking.firewall.allowedTCPPorts = [ 3478 5349 ];
73 networking.firewall.allowedUDPPorts = [ 3478 5349 ];
74
Skyler Grey874a2a82023-06-08 12:29:28 +020075 services.mjolnir = {
76 enable = true;
77
78 settings = {
79 autojoinOnlyIfManager = true;
80 automaticallyRedactForReasons = [ "nsfw" "gore" "spam" "harassment" "hate" ];
81 recordIgnoredInvites = true;
82 admin.enableMakeRoomAdminCommand = true;
83 allowNoPrefix = true;
84 protections.wordlist.words = [ ];
Skyler Greyaaed7b12023-06-14 22:45:49 +020085 protectedRooms = [ "https://matrix.to/#/#global:coded.codes" ];
Skyler Grey874a2a82023-06-08 12:29:28 +020086 };
87
88 pantalaimon = {
89 enable = true;
90 username = "system";
91 passwordFile = config.sops.secrets.mjolnir_password.path;
92 options = {
93 ssl = false;
94 listenAddress = "127.0.0.1";
95 };
96 };
97
98 homeserverUrl = "http://localhost:4527";
99
100 managementRoom = "#moderation-commands:coded.codes";
101 };
102
Skyler Greyb64b5e92023-08-20 21:53:37 +0000103 services.coturn = {
104 enable = false;
105
106 use-auth-secret = true;
107 # static-auth-secret-file = config.sops.secrets.turn_shared_secret.path;
108
109 realm = "turn.coded.codes";
110
111 no-tcp-relay = true;
112
113 no-cli = true;
114
115 extraConfig = ''
116 external-ip=turn.coded.codes
117 '';
118 };
119
Skyler Grey8e32c832023-05-20 22:54:30 +0200120 sops.secrets = {
Skyler Greyb64b5e92023-08-20 21:53:37 +0000121 #turn_shared_secret = {
122 # mode = "0440";
123 # owner = "turnserver";
124 # group = "matrix-synapse";
125 # sopsFile = ../secrets/matrix.json;
126 # format = "json";
127 #};
Skyler Grey8e32c832023-05-20 22:54:30 +0200128 registration_shared_secret = {
Skyler Greya78aa672023-05-20 13:48:18 +0200129 mode = "0400";
Skyler Grey8e32c832023-05-20 22:54:30 +0200130 owner = config.users.users.root.name;
131 group = config.users.users.nobody.group;
132 sopsFile = ../secrets/matrix.json;
133 format = "json";
134 };
135 matrix_private_key = {
136 mode = "0600";
137 owner = config.users.users.matrix-synapse.name;
138 group = config.users.users.matrix-synapse.group;
Skyler Greya78aa672023-05-20 13:48:18 +0200139 sopsFile = ../secrets/matrix_private_key.pem;
140 format = "binary";
Skyler Grey8e32c832023-05-20 22:54:30 +0200141 path = config.services.matrix-synapse.settings.signing_key_path;
Skyler Greya78aa672023-05-20 13:48:18 +0200142 };
Skyler Grey874a2a82023-06-08 12:29:28 +0200143 mjolnir_password = {
144 mode = "0600";
145 owner = config.users.users.mjolnir.name;
146 group = config.users.users.mjolnir.group;
147 sopsFile = ../secrets/matrix.json;
148 format = "json";
149 };
Skyler Greya78aa672023-05-20 13:48:18 +0200150 };
Skyler Grey874a2a82023-06-08 12:29:28 +0200151}
152 (
Skyler Greya78aa672023-05-20 13:48:18 +0200153 let
Skyler Grey874a2a82023-06-08 12:29:28 +0200154 isDerived = base != null;
Skyler Greya78aa672023-05-20 13:48:18 +0200155 in
Skyler Grey874a2a82023-06-08 12:29:28 +0200156 if isDerived
157 # We cannot use mkIf as both sides are evaluated no matter the condition value
158 # Given we use base as an attrset, mkIf will error if base is null in here
159 then
160 let
161 synapse_cfgfile = config.services.matrix-synapse.configFile;
162 in
163 {
164 scalpel.trafos."synapse.yaml" = {
165 source = toString synapse_cfgfile;
166 matchers."registration_shared_secret".secret =
167 config.sops.secrets.registration_shared_secret.path;
Skyler Greyb64b5e92023-08-20 21:53:37 +0000168 # matchers."turn_shared_secret".secret =
169 # config.sops.secrets.turn_shared_secret.path;
Skyler Grey874a2a82023-06-08 12:29:28 +0200170 owner = config.users.users.matrix-synapse.name;
171 group = config.users.users.matrix-synapse.group;
172 mode = "0400";
173 };
Skyler Greya78aa672023-05-20 13:48:18 +0200174
Skyler Grey874a2a82023-06-08 12:29:28 +0200175 systemd.services.matrix-synapse.serviceConfig.ExecStart = lib.mkForce (
176 builtins.replaceStrings
177 [ "${synapse_cfgfile}" ]
178 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
179 "${base.config.systemd.services.matrix-synapse.serviceConfig.ExecStart}"
180 );
Skyler Grey8e32c832023-05-20 22:54:30 +0200181
Skyler Grey874a2a82023-06-08 12:29:28 +0200182 systemd.services.matrix-synapse.preStart = lib.mkForce (
183 builtins.replaceStrings
184 [ "${synapse_cfgfile}" ]
185 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
186 "${base.config.systemd.services.matrix-synapse.preStart}"
187 );
Skyler Grey8e32c832023-05-20 22:54:30 +0200188
Skyler Grey874a2a82023-06-08 12:29:28 +0200189 systemd.services.matrix-synapse.restartTriggers = [ synapse_cfgfile ];
Skyler Greyb3516c22023-05-24 19:17:11 +0200190
Skyler Grey874a2a82023-06-08 12:29:28 +0200191 environment.systemPackages =
192 with lib; let
193 cfg = config.services.matrix-synapse;
194 registerNewMatrixUser =
195 let
196 isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
197 listener =
198 lib.findFirst
199 (
200 listener: lib.any
201 (
202 resource: lib.any
203 (
204 name: name == "client"
205 )
206 resource.names
207 )
208 listener.resources
209 )
210 (lib.last cfg.settings.listeners)
211 cfg.settings.listeners;
212 # FIXME: Handle cases with missing client listener properly,
213 # don't rely on lib.last, this will not work.
Skyler Grey8e32c832023-05-20 22:54:30 +0200214
Skyler Grey874a2a82023-06-08 12:29:28 +0200215 # add a tail, so that without any bind_addresses we still have a useable address
216 bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]);
217 listenerProtocol =
218 if listener.tls
219 then "https"
220 else "http";
221 in
222 pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
223 exec ${cfg.package}/bin/register_new_matrix_user \
224 $@ \
225 ${lib.concatMapStringsSep " " (x: "-c ${x}") ([
226 config.scalpel.trafos."synapse.yaml".destination ] ++ cfg.extraConfigFiles)} \
227 "${listenerProtocol}://${
228 if (isIpv6 bindAddress) then
229 "[${bindAddress}]"
230 else
231 "${bindAddress}"
232 }:${builtins.toString listener.port}/"
233 '';
234 in
235 [ (lib.meta.hiPrio registerNewMatrixUser) ];
236 }
237 else { }
238 )