blob: 2694826727d1e3e8f7136518a8a2f7b677950333 [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 Greya78aa672023-05-20 13:48:18 +020081 };
82 };
83
Skyler Greyb64b5e92023-08-20 21:53:37 +000084 networking.firewall.allowedTCPPorts = [ 3478 5349 ];
85 networking.firewall.allowedUDPPorts = [ 3478 5349 ];
86
Skyler Grey874a2a82023-06-08 12:29:28 +020087 services.mjolnir = {
Skyler Grey083b1e32023-11-20 18:48:02 +000088 enable = true;
Skyler Grey874a2a82023-06-08 12:29:28 +020089
90 settings = {
91 autojoinOnlyIfManager = true;
Skyler Greyfe1740c2023-10-21 01:24:18 +000092 automaticallyRedactForReasons =
93 [ "nsfw" "gore" "spam" "harassment" "hate" ];
Skyler Grey874a2a82023-06-08 12:29:28 +020094 recordIgnoredInvites = true;
95 admin.enableMakeRoomAdminCommand = true;
96 allowNoPrefix = true;
97 protections.wordlist.words = [ ];
Skyler Grey22428b02023-11-19 13:20:56 +000098 protectedRooms = [ "https://matrix.to/#/#global:clicks.codes" ];
Skyler Grey874a2a82023-06-08 12:29:28 +020099 };
100
101 pantalaimon = {
102 enable = true;
103 username = "system";
104 passwordFile = config.sops.secrets.mjolnir_password.path;
105 options = {
106 ssl = false;
107 listenAddress = "127.0.0.1";
108 };
109 };
110
111 homeserverUrl = "http://localhost:4527";
112
Skyler Grey22428b02023-11-19 13:20:56 +0000113 managementRoom = "#moderation-commands:clicks.codes";
Skyler Grey874a2a82023-06-08 12:29:28 +0200114 };
115
Skyler Greyb64b5e92023-08-20 21:53:37 +0000116 services.coturn = {
117 enable = false;
118
119 use-auth-secret = true;
120 # static-auth-secret-file = config.sops.secrets.turn_shared_secret.path;
121
Skyler Grey22428b02023-11-19 13:20:56 +0000122 realm = "turn.clicks.codes";
Skyler Greyb64b5e92023-08-20 21:53:37 +0000123
124 no-tcp-relay = true;
125
126 no-cli = true;
127
128 extraConfig = ''
Skyler Grey22428b02023-11-19 13:20:56 +0000129 external-ip=turn.clicks.codes
Skyler Greyb64b5e92023-08-20 21:53:37 +0000130 '';
131 };
132
Skyler Grey8e32c832023-05-20 22:54:30 +0200133 sops.secrets = {
Skyler Greyb64b5e92023-08-20 21:53:37 +0000134 #turn_shared_secret = {
135 # mode = "0440";
136 # owner = "turnserver";
137 # group = "matrix-synapse";
Samuel Shuertf68685d2023-10-28 20:07:56 -0400138 # sopsFile = ../../secrets/matrix.json;
Skyler Greyb64b5e92023-08-20 21:53:37 +0000139 # format = "json";
140 #};
Skyler Grey22428b02023-11-19 13:20:56 +0000141 matrix_keycloak_client_secret = {
142 mode = "0400";
143 owner = config.users.users.matrix-synapse.name;
144 group = config.users.users.matrix-synapse.group;
145 sopsFile = ../../secrets/matrix.json;
146 format = "json";
147 };
Skyler Grey8e32c832023-05-20 22:54:30 +0200148 registration_shared_secret = {
Skyler Greya78aa672023-05-20 13:48:18 +0200149 mode = "0400";
Skyler Grey8e32c832023-05-20 22:54:30 +0200150 owner = config.users.users.root.name;
Skyler Greybcb46d32023-11-10 20:48:38 +0000151 group = config.users.users.root.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400152 sopsFile = ../../secrets/matrix.json;
Skyler Grey8e32c832023-05-20 22:54:30 +0200153 format = "json";
154 };
155 matrix_private_key = {
156 mode = "0600";
157 owner = config.users.users.matrix-synapse.name;
158 group = config.users.users.matrix-synapse.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400159 sopsFile = ../../secrets/matrix_private_key.pem;
Skyler Greya78aa672023-05-20 13:48:18 +0200160 format = "binary";
Skyler Grey8e32c832023-05-20 22:54:30 +0200161 path = config.services.matrix-synapse.settings.signing_key_path;
Skyler Greya78aa672023-05-20 13:48:18 +0200162 };
Skyler Grey083b1e32023-11-20 18:48:02 +0000163 mjolnir_password = {
Skyler Grey874a2a82023-06-08 12:29:28 +0200164 mode = "0600";
165 owner = config.users.users.mjolnir.name;
166 group = config.users.users.mjolnir.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -0400167 sopsFile = ../../secrets/matrix.json;
Skyler Grey874a2a82023-06-08 12:29:28 +0200168 format = "json";
Skyler Grey083b1e32023-11-20 18:48:02 +0000169 };
Skyler Greya78aa672023-05-20 13:48:18 +0200170 };
Skyler Greyfe1740c2023-10-21 01:24:18 +0000171} (let isDerived = base != null;
172in if isDerived
173# We cannot use mkIf as both sides are evaluated no matter the condition value
174# Given we use base as an attrset, mkIf will error if base is null in here
175then
176 let synapse_cfgfile = config.services.matrix-synapse.configFile;
177 in {
178 scalpel.trafos."synapse.yaml" = {
179 source = toString synapse_cfgfile;
180 matchers."registration_shared_secret".secret =
181 config.sops.secrets.registration_shared_secret.path;
Skyler Grey22428b02023-11-19 13:20:56 +0000182 matchers."matrix_keycloak_client_secret".secret =
183 config.sops.secrets.matrix_keycloak_client_secret.path;
Skyler Greyfe1740c2023-10-21 01:24:18 +0000184 # matchers."turn_shared_secret".secret =
185 # config.sops.secrets.turn_shared_secret.path;
186 owner = config.users.users.matrix-synapse.name;
187 group = config.users.users.matrix-synapse.group;
188 mode = "0400";
189 };
190
191 systemd.services.matrix-synapse.serviceConfig.ExecStart = lib.mkForce
192 (builtins.replaceStrings [ "${synapse_cfgfile}" ]
193 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
194 "${base.config.systemd.services.matrix-synapse.serviceConfig.ExecStart}");
195
196 systemd.services.matrix-synapse.preStart = lib.mkForce
197 (builtins.replaceStrings [ "${synapse_cfgfile}" ]
198 [ "${config.scalpel.trafos."synapse.yaml".destination}" ]
199 "${base.config.systemd.services.matrix-synapse.preStart}");
200
201 systemd.services.matrix-synapse.restartTriggers = [ synapse_cfgfile ];
202
203 environment.systemPackages = with lib;
Skyler Grey874a2a82023-06-08 12:29:28 +0200204 let
Skyler Greyfe1740c2023-10-21 01:24:18 +0000205 cfg = config.services.matrix-synapse;
206 registerNewMatrixUser = let
207 isIpv6 = x: lib.length (lib.splitString ":" x) > 1;
208 listener = lib.findFirst (listener:
209 lib.any (resource: lib.any (name: name == "client") resource.names)
210 listener.resources) (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 Greya78aa672023-05-20 13:48:18 +0200214
Skyler Greyfe1740c2023-10-21 01:24:18 +0000215 # 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 = if listener.tls then "https" else "http";
218 in pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" ''
219 exec ${cfg.package}/bin/register_new_matrix_user \
220 $@ \
221 ${
222 lib.concatMapStringsSep " " (x: "-c ${x}")
223 ([ config.scalpel.trafos."synapse.yaml".destination ]
224 ++ cfg.extraConfigFiles)
225 } \
226 "${listenerProtocol}://${
227 if (isIpv6 bindAddress) then
228 "[${bindAddress}]"
229 else
230 "${bindAddress}"
231 }:${builtins.toString listener.port}/"
232 '';
233 in [ (lib.meta.hiPrio registerNewMatrixUser) ];
234 }
235else
236 { })