blob: 2d41da9fb20a2423d48d30dcf4daccec732137f7 [file] [log] [blame]
Skyler Greya78aa672023-05-20 13:48:18 +02001{ base, config, lib, pkgs, ... }:
Skyler Greyfe1740c2023-10-21 01:24:18 +00002lib.recursiveUpdate {
Skyler Grey8e32c832023-05-20 22:54:30 +02003 services.matrix-synapse = {
Skyler Greya78aa672023-05-20 13:48:18 +02004 enable = true;
Skyler Grey8e32c832023-05-20 22:54:30 +02005 withJemalloc = true;
Skyler Greya78aa672023-05-20 13:48:18 +02006
Skyler Greyfe1740c2023-10-21 01:24:18 +00007 plugins = with config.services.matrix-synapse.package.plugins;
8 [ matrix-synapse-mjolnir-antispam ];
Skyler Grey874a2a82023-06-08 12:29:28 +02009
Skyler Grey1144d002023-05-21 00:17:29 +020010 settings = rec {
Skyler Grey8e32c832023-05-20 22:54:30 +020011 server_name = "coded.codes";
Skyler Grey1144d002023-05-21 00:17:29 +020012 auto_join_rooms = [ "#general:${server_name}" ];
Skyler Grey8e32c832023-05-20 22:54:30 +020013 enable_registration = true;
14 registration_requires_token = true;
Skyler Greyd18587c2023-10-09 07:25:36 +000015 allow_public_rooms_over_federation = true;
16 allow_device_name_lookup_over_federation = true;
Skyler Grey8e32c832023-05-20 22:54:30 +020017 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 = [{
Skyler Greyfe1740c2023-10-21 01:24:18 +000024 names = [ "client" "federation" ];
Skyler Grey8e32c832023-05-20 22:54:30 +020025 compress = true;
26 }];
27 port = 4527;
28 }];
29 enable_metrics = true;
30 database.args.database = "synapse";
Skyler Greyb64b5e92023-08-20 21:53:37 +000031 turn_uris = [
32
33 /* "turn:turn.coded.codes:3478?transport=udp"
Skyler Greyfe1740c2023-10-21 01:24:18 +000034 "turn:turn.coded.codes:3478?transport=tcp"
35 "turns:turn.coded.codes:5349?transport=udp"
36 "turns:turn.coded.codes:5349?transport=tcp"
37 */
Skyler Greyb64b5e92023-08-20 21:53:37 +000038 ]; # Please use matrix.org turn
39 # turn_shared_secret = "!!turn_shared_secret!!";
Skyler Greyd18587c2023-10-09 07:25:36 +000040
41 log_config = lib.pipe {
42 version = 1;
43 formatters = {
44 precise = {
45 format =
46 "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
47 };
48 };
49 handlers = {
50 console = {
51 class = "logging.StreamHandler";
52 formatter = "precise";
53 };
54 };
55 loggers = { "synapse.storage.SQL" = { level = "WARNING"; }; };
56 root = {
57 level = "ERROR";
58 handlers = [ "console" ];
59 };
60 "disable_existing_loggers" = false;
Skyler Greyfe1740c2023-10-21 01:24:18 +000061 } [ builtins.toJSON (builtins.toFile "logcfg.yaml") ];
Skyler Greya78aa672023-05-20 13:48:18 +020062 };
63 };
64
Skyler Greyb64b5e92023-08-20 21:53:37 +000065 networking.firewall.allowedTCPPorts = [ 3478 5349 ];
66 networking.firewall.allowedUDPPorts = [ 3478 5349 ];
67
Skyler Grey874a2a82023-06-08 12:29:28 +020068 services.mjolnir = {
69 enable = true;
70
71 settings = {
72 autojoinOnlyIfManager = true;
Skyler Greyfe1740c2023-10-21 01:24:18 +000073 automaticallyRedactForReasons =
74 [ "nsfw" "gore" "spam" "harassment" "hate" ];
Skyler Grey874a2a82023-06-08 12:29:28 +020075 recordIgnoredInvites = true;
76 admin.enableMakeRoomAdminCommand = true;
77 allowNoPrefix = true;
78 protections.wordlist.words = [ ];
Skyler Greyaaed7b12023-06-14 22:45:49 +020079 protectedRooms = [ "https://matrix.to/#/#global:coded.codes" ];
Skyler Grey874a2a82023-06-08 12:29:28 +020080 };
81
82 pantalaimon = {
83 enable = true;
84 username = "system";
85 passwordFile = config.sops.secrets.mjolnir_password.path;
86 options = {
87 ssl = false;
88 listenAddress = "127.0.0.1";
89 };
90 };
91
92 homeserverUrl = "http://localhost:4527";
93
94 managementRoom = "#moderation-commands:coded.codes";
95 };
96
Skyler Greyb64b5e92023-08-20 21:53:37 +000097 services.coturn = {
98 enable = false;
99
100 use-auth-secret = true;
101 # static-auth-secret-file = config.sops.secrets.turn_shared_secret.path;
102
103 realm = "turn.coded.codes";
104
105 no-tcp-relay = true;
106
107 no-cli = true;
108
109 extraConfig = ''
110 external-ip=turn.coded.codes
111 '';
112 };
113
Skyler Grey8e32c832023-05-20 22:54:30 +0200114 sops.secrets = {
Skyler Greyb64b5e92023-08-20 21:53:37 +0000115 #turn_shared_secret = {
116 # mode = "0440";
117 # owner = "turnserver";
118 # group = "matrix-synapse";
119 # sopsFile = ../secrets/matrix.json;
120 # format = "json";
121 #};
Skyler Grey8e32c832023-05-20 22:54:30 +0200122 registration_shared_secret = {
Skyler Greya78aa672023-05-20 13:48:18 +0200123 mode = "0400";
Skyler Grey8e32c832023-05-20 22:54:30 +0200124 owner = config.users.users.root.name;
125 group = config.users.users.nobody.group;
126 sopsFile = ../secrets/matrix.json;
127 format = "json";
128 };
129 matrix_private_key = {
130 mode = "0600";
131 owner = config.users.users.matrix-synapse.name;
132 group = config.users.users.matrix-synapse.group;
Skyler Greya78aa672023-05-20 13:48:18 +0200133 sopsFile = ../secrets/matrix_private_key.pem;
134 format = "binary";
Skyler Grey8e32c832023-05-20 22:54:30 +0200135 path = config.services.matrix-synapse.settings.signing_key_path;
Skyler Greya78aa672023-05-20 13:48:18 +0200136 };
Skyler Grey874a2a82023-06-08 12:29:28 +0200137 mjolnir_password = {
138 mode = "0600";
139 owner = config.users.users.mjolnir.name;
140 group = config.users.users.mjolnir.group;
141 sopsFile = ../secrets/matrix.json;
142 format = "json";
143 };
Skyler Greya78aa672023-05-20 13:48:18 +0200144 };
Skyler Greyfe1740c2023-10-21 01:24:18 +0000145} (let isDerived = base != null;
146in if isDerived
147# We cannot use mkIf as both sides are evaluated no matter the condition value
148# Given we use base as an attrset, mkIf will error if base is null in here
149then
150 let synapse_cfgfile = config.services.matrix-synapse.configFile;
151 in {
152 scalpel.trafos."synapse.yaml" = {
153 source = toString synapse_cfgfile;
154 matchers."registration_shared_secret".secret =
155 config.sops.secrets.registration_shared_secret.path;
156 # matchers."turn_shared_secret".secret =
157 # config.sops.secrets.turn_shared_secret.path;
158 owner = config.users.users.matrix-synapse.name;
159 group = config.users.users.matrix-synapse.group;
160 mode = "0400";
161 };
162
163 systemd.services.matrix-synapse.serviceConfig.ExecStart = lib.mkForce
164 (builtins.replaceStrings [ "${synapse_cfgfile}" ]
165 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
166 "${base.config.systemd.services.matrix-synapse.serviceConfig.ExecStart}");
167
168 systemd.services.matrix-synapse.preStart = lib.mkForce
169 (builtins.replaceStrings [ "${synapse_cfgfile}" ]
170 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
171 "${base.config.systemd.services.matrix-synapse.preStart}");
172
173 systemd.services.matrix-synapse.restartTriggers = [ synapse_cfgfile ];
174
175 environment.systemPackages = with lib;
Skyler Grey874a2a82023-06-08 12:29:28 +0200176 let
Skyler Greyfe1740c2023-10-21 01:24:18 +0000177 cfg = config.services.matrix-synapse;
178 registerNewMatrixUser = let
179 isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
180 listener = lib.findFirst (listener:
181 lib.any (resource: lib.any (name: name == "client") resource.names)
182 listener.resources) (lib.last cfg.settings.listeners)
183 cfg.settings.listeners;
184 # FIXME: Handle cases with missing client listener properly,
185 # don't rely on lib.last, this will not work.
Skyler Greya78aa672023-05-20 13:48:18 +0200186
Skyler Greyfe1740c2023-10-21 01:24:18 +0000187 # add a tail, so that without any bind_addresses we still have a useable address
188 bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]);
189 listenerProtocol = if listener.tls then "https" else "http";
190 in pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
191 exec ${cfg.package}/bin/register_new_matrix_user \
192 $@ \
193 ${
194 lib.concatMapStringsSep " " (x: "-c ${x}")
195 ([ config.scalpel.trafos."synapse.yaml".destination ]
196 ++ cfg.extraConfigFiles)
197 } \
198 "${listenerProtocol}://${
199 if (isIpv6 bindAddress) then
200 "[${bindAddress}]"
201 else
202 "${bindAddress}"
203 }:${builtins.toString listener.port}/"
204 '';
205 in [ (lib.meta.hiPrio registerNewMatrixUser) ];
206 }
207else
208 { })