blob: d87732fc7b6bddbcc3e647a6837f1479ce2eb489 [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 Grey22428b02023-11-19 13:20:56 +000011 server_name = "clicks.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!!";
Skyler Grey22428b02023-11-19 13:20:56 +000018 public_baseurl = "https://matrix-backend.clicks.codes/";
Skyler Grey8e32c832023-05-20 22:54:30 +020019 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 Grey22428b02023-11-19 13:20:56 +000031
32 oidc_providers = [
33 {
34 idp_id = "keycloak";
35 idp_name = "Clicks Keycloak";
36 issuer = "https://login.clicks.codes/realms/master";
37 client_id = "matrix";
38 client_secret = "!!matrix_keycloak_client_secret!!";
39 scopes = [ "openid" "profile" ];
40 user_mapping_provider = {
41 config = {
42 localpart_template = "{{ user.preferred_username }}";
43 display_name_template = "{{ user.name }}";
44 };
45 };
46 backchannel_logout_enabled = true;
47 }
48 ];
49
Skyler Greyb64b5e92023-08-20 21:53:37 +000050 turn_uris = [
51
Skyler Grey22428b02023-11-19 13:20:56 +000052 /* "turn:turn.clicks.codes:3478?transport=udp"
53 "turn:turn.clicks.codes:3478?transport=tcp"
54 "turns:turn.clicks.codes:5349?transport=udp"
55 "turns:turn.clicks.codes:5349?transport=tcp"
Skyler Greyfe1740c2023-10-21 01:24:18 +000056 */
Skyler Greyb64b5e92023-08-20 21:53:37 +000057 ]; # Please use matrix.org turn
58 # turn_shared_secret = "!!turn_shared_secret!!";
Skyler Greyd18587c2023-10-09 07:25:36 +000059
60 log_config = lib.pipe {
61 version = 1;
62 formatters = {
63 precise = {
64 format =
65 "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
66 };
67 };
68 handlers = {
69 console = {
70 class = "logging.StreamHandler";
71 formatter = "precise";
72 };
73 };
74 loggers = { "synapse.storage.SQL" = { level = "WARNING"; }; };
75 root = {
76 level = "ERROR";
77 handlers = [ "console" ];
78 };
79 "disable_existing_loggers" = false;
Skyler Greyfe1740c2023-10-21 01:24:18 +000080 } [ builtins.toJSON (builtins.toFile "logcfg.yaml") ];
Skyler Greye6a5a912023-11-21 20:19:30 +000081
82 server_notices = {
83 system_mxid_localpart = "system";
84 system_mxid_display_name = "Clicks Administrators";
85 room_name = "Announcements";
86 };
Skyler Greya78aa672023-05-20 13:48:18 +020087 };
88 };
89
Skyler Greyb64b5e92023-08-20 21:53:37 +000090 networking.firewall.allowedTCPPorts = [ 3478 5349 ];
91 networking.firewall.allowedUDPPorts = [ 3478 5349 ];
92
Skyler Grey874a2a82023-06-08 12:29:28 +020093 services.mjolnir = {
Skyler Grey083b1e32023-11-20 18:48:02 +000094 enable = true;
Skyler Grey874a2a82023-06-08 12:29:28 +020095
96 settings = {
97 autojoinOnlyIfManager = true;
Skyler Greyfe1740c2023-10-21 01:24:18 +000098 automaticallyRedactForReasons =
99 [ "nsfw" "gore" "spam" "harassment" "hate" ];
Skyler Grey874a2a82023-06-08 12:29:28 +0200100 recordIgnoredInvites = true;
101 admin.enableMakeRoomAdminCommand = true;
102 allowNoPrefix = true;
103 protections.wordlist.words = [ ];
Skyler Grey22428b02023-11-19 13:20:56 +0000104 protectedRooms = [ "https://matrix.to/#/#global:clicks.codes" ];
Skyler Grey874a2a82023-06-08 12:29:28 +0200105 };
106
107 pantalaimon = {
108 enable = true;
109 username = "system";
110 passwordFile = config.sops.secrets.mjolnir_password.path;
111 options = {
112 ssl = false;
113 listenAddress = "127.0.0.1";
114 };
115 };
116
117 homeserverUrl = "http://localhost:4527";
118
Skyler Grey22428b02023-11-19 13:20:56 +0000119 managementRoom = "#moderation-commands:clicks.codes";
Skyler Grey874a2a82023-06-08 12:29:28 +0200120 };
121
Skyler Greyb64b5e92023-08-20 21:53:37 +0000122 services.coturn = {
123 enable = false;
124
125 use-auth-secret = true;
126 # static-auth-secret-file = config.sops.secrets.turn_shared_secret.path;
127
Skyler Grey22428b02023-11-19 13:20:56 +0000128 realm = "turn.clicks.codes";
Skyler Greyb64b5e92023-08-20 21:53:37 +0000129
130 no-tcp-relay = true;
131
132 no-cli = true;
133
134 extraConfig = ''
Skyler Grey22428b02023-11-19 13:20:56 +0000135 external-ip=turn.clicks.codes
Skyler Greyb64b5e92023-08-20 21:53:37 +0000136 '';
137 };
138
Skyler Grey8e32c832023-05-20 22:54:30 +0200139 sops.secrets = {
Skyler Greyb64b5e92023-08-20 21:53:37 +0000140 #turn_shared_secret = {
141 # mode = "0440";
142 # owner = "turnserver";
143 # group = "matrix-synapse";
Samuel Shuertf68685d2023-10-28 20:07:56 -0400144 # sopsFile = ../../secrets/matrix.json;
Skyler Greyb64b5e92023-08-20 21:53:37 +0000145 # format = "json";
146 #};
Skyler Grey22428b02023-11-19 13:20:56 +0000147 matrix_keycloak_client_secret = {
148 mode = "0400";
149 owner = config.users.users.matrix-synapse.name;
150 group = config.users.users.matrix-synapse.group;
151 sopsFile = ../../secrets/matrix.json;
152 format = "json";
153 };
Skyler Grey8e32c832023-05-20 22:54:30 +0200154 registration_shared_secret = {
Skyler Greya78aa672023-05-20 13:48:18 +0200155 mode = "0400";
Skyler Grey8e32c832023-05-20 22:54:30 +0200156 owner = config.users.users.root.name;
Skyler Greybcb46d32023-11-10 20:48:38 +0000157 group = config.users.users.root.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400158 sopsFile = ../../secrets/matrix.json;
Skyler Grey8e32c832023-05-20 22:54:30 +0200159 format = "json";
160 };
161 matrix_private_key = {
162 mode = "0600";
163 owner = config.users.users.matrix-synapse.name;
164 group = config.users.users.matrix-synapse.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400165 sopsFile = ../../secrets/matrix_private_key.pem;
Skyler Greya78aa672023-05-20 13:48:18 +0200166 format = "binary";
Skyler Grey8e32c832023-05-20 22:54:30 +0200167 path = config.services.matrix-synapse.settings.signing_key_path;
Skyler Greya78aa672023-05-20 13:48:18 +0200168 };
Skyler Grey083b1e32023-11-20 18:48:02 +0000169 mjolnir_password = {
Skyler Grey874a2a82023-06-08 12:29:28 +0200170 mode = "0600";
171 owner = config.users.users.mjolnir.name;
172 group = config.users.users.mjolnir.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400173 sopsFile = ../../secrets/matrix.json;
Skyler Grey874a2a82023-06-08 12:29:28 +0200174 format = "json";
Skyler Grey083b1e32023-11-20 18:48:02 +0000175 };
Skyler Greya78aa672023-05-20 13:48:18 +0200176 };
Skyler Greyfe1740c2023-10-21 01:24:18 +0000177} (let isDerived = base != null;
178in if isDerived
179# We cannot use mkIf as both sides are evaluated no matter the condition value
180# Given we use base as an attrset, mkIf will error if base is null in here
181then
182 let synapse_cfgfile = config.services.matrix-synapse.configFile;
183 in {
184 scalpel.trafos."synapse.yaml" = {
185 source = toString synapse_cfgfile;
186 matchers."registration_shared_secret".secret =
187 config.sops.secrets.registration_shared_secret.path;
Skyler Grey22428b02023-11-19 13:20:56 +0000188 matchers."matrix_keycloak_client_secret".secret =
189 config.sops.secrets.matrix_keycloak_client_secret.path;
Skyler Greyfe1740c2023-10-21 01:24:18 +0000190 # matchers."turn_shared_secret".secret =
191 # config.sops.secrets.turn_shared_secret.path;
192 owner = config.users.users.matrix-synapse.name;
193 group = config.users.users.matrix-synapse.group;
194 mode = "0400";
195 };
196
197 systemd.services.matrix-synapse.serviceConfig.ExecStart = lib.mkForce
198 (builtins.replaceStrings [ "${synapse_cfgfile}" ]
199 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
200 "${base.config.systemd.services.matrix-synapse.serviceConfig.ExecStart}");
201
202 systemd.services.matrix-synapse.preStart = lib.mkForce
203 (builtins.replaceStrings [ "${synapse_cfgfile}" ]
204 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
205 "${base.config.systemd.services.matrix-synapse.preStart}");
206
207 systemd.services.matrix-synapse.restartTriggers = [ synapse_cfgfile ];
208
209 environment.systemPackages = with lib;
Skyler Grey874a2a82023-06-08 12:29:28 +0200210 let
Skyler Greyfe1740c2023-10-21 01:24:18 +0000211 cfg = config.services.matrix-synapse;
212 registerNewMatrixUser = let
213 isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
214 listener = lib.findFirst (listener:
215 lib.any (resource: lib.any (name: name == "client") resource.names)
216 listener.resources) (lib.last cfg.settings.listeners)
217 cfg.settings.listeners;
218 # FIXME: Handle cases with missing client listener properly,
219 # don't rely on lib.last, this will not work.
Skyler Greya78aa672023-05-20 13:48:18 +0200220
Skyler Greyfe1740c2023-10-21 01:24:18 +0000221 # add a tail, so that without any bind_addresses we still have a useable address
222 bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]);
223 listenerProtocol = if listener.tls then "https" else "http";
224 in pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
225 exec ${cfg.package}/bin/register_new_matrix_user \
226 $@ \
227 ${
228 lib.concatMapStringsSep " " (x: "-c ${x}")
229 ([ config.scalpel.trafos."synapse.yaml".destination ]
230 ++ cfg.extraConfigFiles)
231 } \
232 "${listenerProtocol}://${
233 if (isIpv6 bindAddress) then
234 "[${bindAddress}]"
235 else
236 "${bindAddress}"
237 }:${builtins.toString listener.port}/"
238 '';
239 in [ (lib.meta.hiPrio registerNewMatrixUser) ];
240 }
241else
242 { })