at 23.05-pre 34 kB view raw
1{ config, lib, options, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.matrix-synapse; 7 format = pkgs.formats.yaml {}; 8 9 # remove null values from the final configuration 10 finalSettings = lib.filterAttrsRecursive (_: v: v != null) cfg.settings; 11 configFile = format.generate "homeserver.yaml" finalSettings; 12 logConfigFile = format.generate "log_config.yaml" cfg.logConfig; 13 14 pluginsEnv = cfg.package.python.buildEnv.override { 15 extraLibs = cfg.plugins; 16 }; 17 18 usePostgresql = cfg.settings.database.name == "psycopg2"; 19 hasLocalPostgresDB = let args = cfg.settings.database.args; in 20 usePostgresql && (!(args ? host) || (elem args.host [ "localhost" "127.0.0.1" "::1" ])); 21 22 registerNewMatrixUser = 23 let 24 isIpv6 = x: lib.length (lib.splitString ":" x) > 1; 25 listener = 26 lib.findFirst ( 27 listener: lib.any ( 28 resource: lib.any ( 29 name: name == "client" 30 ) resource.names 31 ) listener.resources 32 ) (lib.last cfg.settings.listeners) cfg.settings.listeners; 33 # FIXME: Handle cases with missing client listener properly, 34 # don't rely on lib.last, this will not work. 35 36 # add a tail, so that without any bind_addresses we still have a useable address 37 bindAddress = head (listener.bind_addresses ++ [ "127.0.0.1" ]); 38 listenerProtocol = if listener.tls 39 then "https" 40 else "http"; 41 in 42 pkgs.writeShellScriptBin "matrix-synapse-register_new_matrix_user" '' 43 exec ${cfg.package}/bin/register_new_matrix_user \ 44 $@ \ 45 ${lib.concatMapStringsSep " " (x: "-c ${x}") ([ configFile ] ++ cfg.extraConfigFiles)} \ 46 "${listenerProtocol}://${ 47 if (isIpv6 bindAddress) then 48 "[${bindAddress}]" 49 else 50 "${bindAddress}" 51 }:${builtins.toString listener.port}/" 52 ''; 53in { 54 55 imports = [ 56 57 (mkRemovedOptionModule [ "services" "matrix-synapse" "trusted_third_party_id_servers" ] '' 58 The `trusted_third_party_id_servers` option as been removed in `matrix-synapse` v1.4.0 59 as the behavior is now obsolete. 60 '') 61 (mkRemovedOptionModule [ "services" "matrix-synapse" "create_local_database" ] '' 62 Database configuration must be done manually. An exemplary setup is demonstrated in 63 <nixpkgs/nixos/tests/matrix-synapse.nix> 64 '') 65 (mkRemovedOptionModule [ "services" "matrix-synapse" "web_client" ] "") 66 (mkRemovedOptionModule [ "services" "matrix-synapse" "room_invite_state_types" ] '' 67 You may add additional event types via 68 `services.matrix-synapse.room_prejoin_state.additional_event_types` and 69 disable the default events via 70 `services.matrix-synapse.room_prejoin_state.disable_default_event_types`. 71 '') 72 73 # options that don't exist in synapse anymore 74 (mkRemovedOptionModule [ "services" "matrix-synapse" "bind_host" ] "Use listener settings instead." ) 75 (mkRemovedOptionModule [ "services" "matrix-synapse" "bind_port" ] "Use listener settings instead." ) 76 (mkRemovedOptionModule [ "services" "matrix-synapse" "expire_access_tokens" ] "" ) 77 (mkRemovedOptionModule [ "services" "matrix-synapse" "no_tls" ] "It is no longer supported by synapse." ) 78 (mkRemovedOptionModule [ "services" "matrix-synapse" "tls_dh_param_path" ] "It was removed from synapse." ) 79 (mkRemovedOptionModule [ "services" "matrix-synapse" "unsecure_port" ] "Use settings.listeners instead." ) 80 (mkRemovedOptionModule [ "services" "matrix-synapse" "user_creation_max_duration" ] "It is no longer supported by synapse." ) 81 (mkRemovedOptionModule [ "services" "matrix-synapse" "verbose" ] "Use a log config instead." ) 82 83 # options that were moved into rfc42 style settigns 84 (mkRemovedOptionModule [ "services" "matrix-synapse" "app_service_config_files" ] "Use settings.app_service_config_files instead" ) 85 (mkRemovedOptionModule [ "services" "matrix-synapse" "database_args" ] "Use settings.database.args instead" ) 86 (mkRemovedOptionModule [ "services" "matrix-synapse" "database_name" ] "Use settings.database.args.database instead" ) 87 (mkRemovedOptionModule [ "services" "matrix-synapse" "database_type" ] "Use settings.database.name instead" ) 88 (mkRemovedOptionModule [ "services" "matrix-synapse" "database_user" ] "Use settings.database.args.user instead" ) 89 (mkRemovedOptionModule [ "services" "matrix-synapse" "dynamic_thumbnails" ] "Use settings.dynamic_thumbnails instead" ) 90 (mkRemovedOptionModule [ "services" "matrix-synapse" "enable_metrics" ] "Use settings.enable_metrics instead" ) 91 (mkRemovedOptionModule [ "services" "matrix-synapse" "enable_registration" ] "Use settings.enable_registration instead" ) 92 (mkRemovedOptionModule [ "services" "matrix-synapse" "extraConfig" ] "Use settings instead." ) 93 (mkRemovedOptionModule [ "services" "matrix-synapse" "listeners" ] "Use settings.listeners instead" ) 94 (mkRemovedOptionModule [ "services" "matrix-synapse" "logConfig" ] "Use settings.log_config instead" ) 95 (mkRemovedOptionModule [ "services" "matrix-synapse" "max_image_pixels" ] "Use settings.max_image_pixels instead" ) 96 (mkRemovedOptionModule [ "services" "matrix-synapse" "max_upload_size" ] "Use settings.max_upload_size instead" ) 97 (mkRemovedOptionModule [ "services" "matrix-synapse" "presence" "enabled" ] "Use settings.presence.enabled instead" ) 98 (mkRemovedOptionModule [ "services" "matrix-synapse" "public_baseurl" ] "Use settings.public_baseurl instead" ) 99 (mkRemovedOptionModule [ "services" "matrix-synapse" "report_stats" ] "Use settings.report_stats instead" ) 100 (mkRemovedOptionModule [ "services" "matrix-synapse" "server_name" ] "Use settings.server_name instead" ) 101 (mkRemovedOptionModule [ "services" "matrix-synapse" "servers" ] "Use settings.trusted_key_servers instead." ) 102 (mkRemovedOptionModule [ "services" "matrix-synapse" "tls_certificate_path" ] "Use settings.tls_certificate_path instead" ) 103 (mkRemovedOptionModule [ "services" "matrix-synapse" "tls_private_key_path" ] "Use settings.tls_private_key_path instead" ) 104 (mkRemovedOptionModule [ "services" "matrix-synapse" "turn_shared_secret" ] "Use settings.turn_shared_secret instead" ) 105 (mkRemovedOptionModule [ "services" "matrix-synapse" "turn_uris" ] "Use settings.turn_uris instead" ) 106 (mkRemovedOptionModule [ "services" "matrix-synapse" "turn_user_lifetime" ] "Use settings.turn_user_lifetime instead" ) 107 (mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_enabled" ] "Use settings.url_preview_enabled instead" ) 108 (mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_ip_range_blacklist" ] "Use settings.url_preview_ip_range_blacklist instead" ) 109 (mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_ip_range_whitelist" ] "Use settings.url_preview_ip_range_whitelist instead" ) 110 (mkRemovedOptionModule [ "services" "matrix-synapse" "url_preview_url_blacklist" ] "Use settings.url_preview_url_blacklist instead" ) 111 112 # options that are too specific to mention them explicitly in settings 113 (mkRemovedOptionModule [ "services" "matrix-synapse" "account_threepid_delegates" "email" ] "Use settings.account_threepid_delegates.email instead" ) 114 (mkRemovedOptionModule [ "services" "matrix-synapse" "account_threepid_delegates" "msisdn" ] "Use settings.account_threepid_delegates.msisdn instead" ) 115 (mkRemovedOptionModule [ "services" "matrix-synapse" "allow_guest_access" ] "Use settings.allow_guest_access instead" ) 116 (mkRemovedOptionModule [ "services" "matrix-synapse" "bcrypt_rounds" ] "Use settings.bcrypt_rounds instead" ) 117 (mkRemovedOptionModule [ "services" "matrix-synapse" "enable_registration_captcha" ] "Use settings.enable_registration_captcha instead" ) 118 (mkRemovedOptionModule [ "services" "matrix-synapse" "event_cache_size" ] "Use settings.event_cache_size instead" ) 119 (mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_concurrent" ] "Use settings.rc_federation.concurrent instead" ) 120 (mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_reject_limit" ] "Use settings.rc_federation.reject_limit instead" ) 121 (mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_sleep_delay" ] "Use settings.rc_federation.sleep_delay instead" ) 122 (mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_sleep_limit" ] "Use settings.rc_federation.sleep_limit instead" ) 123 (mkRemovedOptionModule [ "services" "matrix-synapse" "federation_rc_window_size" ] "Use settings.rc_federation.window_size instead" ) 124 (mkRemovedOptionModule [ "services" "matrix-synapse" "key_refresh_interval" ] "Use settings.key_refresh_interval instead" ) 125 (mkRemovedOptionModule [ "services" "matrix-synapse" "rc_messages_burst_count" ] "Use settings.rc_messages.burst_count instead" ) 126 (mkRemovedOptionModule [ "services" "matrix-synapse" "rc_messages_per_second" ] "Use settings.rc_messages.per_second instead" ) 127 (mkRemovedOptionModule [ "services" "matrix-synapse" "recaptcha_private_key" ] "Use settings.recaptcha_private_key instead" ) 128 (mkRemovedOptionModule [ "services" "matrix-synapse" "recaptcha_public_key" ] "Use settings.recaptcha_public_key instead" ) 129 (mkRemovedOptionModule [ "services" "matrix-synapse" "redaction_retention_period" ] "Use settings.redaction_retention_period instead" ) 130 (mkRemovedOptionModule [ "services" "matrix-synapse" "room_prejoin_state" "additional_event_types" ] "Use settings.room_prejoin_state.additional_event_types instead" ) 131 (mkRemovedOptionModule [ "services" "matrix-synapse" "room_prejoin_state" "disable_default_event_types" ] "Use settings.room_prejoin-state.disable_default_event_types instead" ) 132 133 # Options that should be passed via extraConfigFiles, so they are not persisted into the nix store 134 (mkRemovedOptionModule [ "services" "matrix-synapse" "macaroon_secret_key" ] "Pass this value via extraConfigFiles instead" ) 135 (mkRemovedOptionModule [ "services" "matrix-synapse" "registration_shared_secret" ] "Pass this value via extraConfigFiles instead" ) 136 137 ]; 138 139 options = { 140 services.matrix-synapse = { 141 enable = mkEnableOption (lib.mdDoc "matrix.org synapse"); 142 143 configFile = mkOption { 144 type = types.path; 145 readOnly = true; 146 description = lib.mdDoc '' 147 Path to the configuration file on the target system. Useful to configure e.g. workers 148 that also need this. 149 ''; 150 }; 151 152 package = mkOption { 153 type = types.package; 154 default = pkgs.matrix-synapse; 155 defaultText = literalExpression "pkgs.matrix-synapse"; 156 description = lib.mdDoc '' 157 Overridable attribute of the matrix synapse server package to use. 158 ''; 159 }; 160 161 plugins = mkOption { 162 type = types.listOf types.package; 163 default = [ ]; 164 example = literalExpression '' 165 with config.services.matrix-synapse.package.plugins; [ 166 matrix-synapse-ldap3 167 matrix-synapse-pam 168 ]; 169 ''; 170 description = lib.mdDoc '' 171 List of additional Matrix plugins to make available. 172 ''; 173 }; 174 175 withJemalloc = mkOption { 176 type = types.bool; 177 default = false; 178 description = lib.mdDoc '' 179 Whether to preload jemalloc to reduce memory fragmentation and overall usage. 180 ''; 181 }; 182 183 dataDir = mkOption { 184 type = types.str; 185 default = "/var/lib/matrix-synapse"; 186 description = lib.mdDoc '' 187 The directory where matrix-synapse stores its stateful data such as 188 certificates, media and uploads. 189 ''; 190 }; 191 192 settings = mkOption { 193 default = {}; 194 description = mdDoc '' 195 The primary synapse configuration. See the 196 [sample configuration](https://github.com/matrix-org/synapse/blob/v${cfg.package.version}/docs/sample_config.yaml) 197 for possible values. 198 199 Secrets should be passed in by using the `extraConfigFiles` option. 200 ''; 201 type = with types; submodule { 202 freeformType = format.type; 203 options = { 204 # This is a reduced set of popular options and defaults 205 # Do not add every available option here, they can be specified 206 # by the user at their own discretion. This is a freeform type! 207 208 server_name = mkOption { 209 type = types.str; 210 example = "example.com"; 211 default = config.networking.hostName; 212 defaultText = literalExpression "config.networking.hostName"; 213 description = lib.mdDoc '' 214 The domain name of the server, with optional explicit port. 215 This is used by remote servers to look up the server address. 216 This is also the last part of your UserID. 217 218 The server_name cannot be changed later so it is important to configure this correctly before you start Synapse. 219 ''; 220 }; 221 222 enable_registration = mkOption { 223 type = types.bool; 224 default = false; 225 description = lib.mdDoc '' 226 Enable registration for new users. 227 ''; 228 }; 229 230 registration_shared_secret = mkOption { 231 type = types.nullOr types.str; 232 default = null; 233 description = mdDoc '' 234 If set, allows registration by anyone who also has the shared 235 secret, even if registration is otherwise disabled. 236 237 Secrets should be passed in via `extraConfigFiles`! 238 ''; 239 }; 240 241 macaroon_secret_key = mkOption { 242 type = types.nullOr types.str; 243 default = null; 244 description = mdDoc '' 245 Secret key for authentication tokens. If none is specified, 246 the registration_shared_secret is used, if one is given; otherwise, 247 a secret key is derived from the signing key. 248 249 Secrets should be passed in via `extraConfigFiles`! 250 ''; 251 }; 252 253 enable_metrics = mkOption { 254 type = types.bool; 255 default = false; 256 description = lib.mdDoc '' 257 Enable collection and rendering of performance metrics 258 ''; 259 }; 260 261 report_stats = mkOption { 262 type = types.bool; 263 default = false; 264 description = lib.mdDoc '' 265 Whether or not to report anonymized homeserver usage statistics. 266 ''; 267 }; 268 269 signing_key_path = mkOption { 270 type = types.path; 271 default = "${cfg.dataDir}/homeserver.signing.key"; 272 description = lib.mdDoc '' 273 Path to the signing key to sign messages with. 274 ''; 275 }; 276 277 pid_file = mkOption { 278 type = types.path; 279 default = "/run/matrix-synapse.pid"; 280 readOnly = true; 281 description = lib.mdDoc '' 282 The file to store the PID in. 283 ''; 284 }; 285 286 log_config = mkOption { 287 type = types.path; 288 default = ./synapse-log_config.yaml; 289 description = lib.mdDoc '' 290 The file that holds the logging configuration. 291 ''; 292 }; 293 294 media_store_path = mkOption { 295 type = types.path; 296 default = if lib.versionAtLeast config.system.stateVersion "22.05" 297 then "${cfg.dataDir}/media_store" 298 else "${cfg.dataDir}/media"; 299 defaultText = "${cfg.dataDir}/media_store for when system.stateVersion is at least 22.05, ${cfg.dataDir}/media when lower than 22.05"; 300 description = lib.mdDoc '' 301 Directory where uploaded images and attachments are stored. 302 ''; 303 }; 304 305 public_baseurl = mkOption { 306 type = types.nullOr types.str; 307 default = null; 308 example = "https://example.com:8448/"; 309 description = lib.mdDoc '' 310 The public-facing base URL for the client API (not including _matrix/...) 311 ''; 312 }; 313 314 tls_certificate_path = mkOption { 315 type = types.nullOr types.str; 316 default = null; 317 example = "/var/lib/acme/example.com/fullchain.pem"; 318 description = lib.mdDoc '' 319 PEM encoded X509 certificate for TLS. 320 You can replace the self-signed certificate that synapse 321 autogenerates on launch with your own SSL certificate + key pair 322 if you like. Any required intermediary certificates can be 323 appended after the primary certificate in hierarchical order. 324 ''; 325 }; 326 327 tls_private_key_path = mkOption { 328 type = types.nullOr types.str; 329 default = null; 330 example = "/var/lib/acme/example.com/key.pem"; 331 description = lib.mdDoc '' 332 PEM encoded private key for TLS. Specify null if synapse is not 333 speaking TLS directly. 334 ''; 335 }; 336 337 presence.enabled = mkOption { 338 type = types.bool; 339 default = true; 340 example = false; 341 description = lib.mdDoc '' 342 Whether to enable presence tracking. 343 344 Presence tracking allows users to see the state (e.g online/offline) 345 of other local and remote users. 346 ''; 347 }; 348 349 listeners = mkOption { 350 type = types.listOf (types.submodule { 351 options = { 352 port = mkOption { 353 type = types.port; 354 example = 8448; 355 description = lib.mdDoc '' 356 The port to listen for HTTP(S) requests on. 357 ''; 358 }; 359 360 bind_addresses = mkOption { 361 type = types.listOf types.str; 362 default = [ 363 "::1" 364 "127.0.0.1" 365 ]; 366 example = literalExpression '' 367 [ 368 "::" 369 "0.0.0.0" 370 ] 371 ''; 372 description = lib.mdDoc '' 373 IP addresses to bind the listener to. 374 ''; 375 }; 376 377 type = mkOption { 378 type = types.enum [ 379 "http" 380 "manhole" 381 "metrics" 382 "replication" 383 ]; 384 default = "http"; 385 example = "metrics"; 386 description = lib.mdDoc '' 387 The type of the listener, usually http. 388 ''; 389 }; 390 391 tls = mkOption { 392 type = types.bool; 393 default = true; 394 example = false; 395 description = lib.mdDoc '' 396 Whether to enable TLS on the listener socket. 397 ''; 398 }; 399 400 x_forwarded = mkOption { 401 type = types.bool; 402 default = false; 403 example = true; 404 description = lib.mdDoc '' 405 Use the X-Forwarded-For (XFF) header as the client IP and not the 406 actual client IP. 407 ''; 408 }; 409 410 resources = mkOption { 411 type = types.listOf (types.submodule { 412 options = { 413 names = mkOption { 414 type = types.listOf (types.enum [ 415 "client" 416 "consent" 417 "federation" 418 "keys" 419 "media" 420 "metrics" 421 "openid" 422 "replication" 423 "static" 424 ]); 425 description = lib.mdDoc '' 426 List of resources to host on this listener. 427 ''; 428 example = [ 429 "client" 430 ]; 431 }; 432 compress = mkOption { 433 type = types.bool; 434 description = lib.mdDoc '' 435 Should synapse compress HTTP responses to clients that support it? 436 This should be disabled if running synapse behind a load balancer 437 that can do automatic compression. 438 ''; 439 }; 440 }; 441 }); 442 description = lib.mdDoc '' 443 List of HTTP resources to serve on this listener. 444 ''; 445 }; 446 }; 447 }); 448 default = [ { 449 port = 8008; 450 bind_addresses = [ "127.0.0.1" ]; 451 type = "http"; 452 tls = false; 453 x_forwarded = true; 454 resources = [ { 455 names = [ "client" ]; 456 compress = true; 457 } { 458 names = [ "federation" ]; 459 compress = false; 460 } ]; 461 } ]; 462 description = lib.mdDoc '' 463 List of ports that Synapse should listen on, their purpose and their configuration. 464 ''; 465 }; 466 467 database.name = mkOption { 468 type = types.enum [ 469 "sqlite3" 470 "psycopg2" 471 ]; 472 default = if versionAtLeast config.system.stateVersion "18.03" 473 then "psycopg2" 474 else "sqlite3"; 475 defaultText = literalExpression '' 476 if versionAtLeast config.system.stateVersion "18.03" 477 then "psycopg2" 478 else "sqlite3" 479 ''; 480 description = lib.mdDoc '' 481 The database engine name. Can be sqlite3 or psycopg2. 482 ''; 483 }; 484 485 database.args.database = mkOption { 486 type = types.str; 487 default = { 488 sqlite3 = "${cfg.dataDir}/homeserver.db"; 489 psycopg2 = "matrix-synapse"; 490 }.${cfg.settings.database.name}; 491 defaultText = literalExpression '' 492 { 493 sqlite3 = "''${${options.services.matrix-synapse.dataDir}}/homeserver.db"; 494 psycopg2 = "matrix-synapse"; 495 }.''${${options.services.matrix-synapse.settings}.database.name}; 496 ''; 497 description = lib.mdDoc '' 498 Name of the database when using the psycopg2 backend, 499 path to the database location when using sqlite3. 500 ''; 501 }; 502 503 database.args.user = mkOption { 504 type = types.nullOr types.str; 505 default = { 506 sqlite3 = null; 507 psycopg2 = "matrix-synapse"; 508 }.${cfg.settings.database.name}; 509 description = lib.mdDoc '' 510 Username to connect with psycopg2, set to null 511 when using sqlite3. 512 ''; 513 }; 514 515 url_preview_enabled = mkOption { 516 type = types.bool; 517 default = true; 518 example = false; 519 description = lib.mdDoc '' 520 Is the preview URL API enabled? If enabled, you *must* specify an 521 explicit url_preview_ip_range_blacklist of IPs that the spider is 522 denied from accessing. 523 ''; 524 }; 525 526 url_preview_ip_range_blacklist = mkOption { 527 type = types.listOf types.str; 528 default = [ 529 "10.0.0.0/8" 530 "100.64.0.0/10" 531 "127.0.0.0/8" 532 "169.254.0.0/16" 533 "172.16.0.0/12" 534 "192.0.0.0/24" 535 "192.0.2.0/24" 536 "192.168.0.0/16" 537 "192.88.99.0/24" 538 "198.18.0.0/15" 539 "198.51.100.0/24" 540 "2001:db8::/32" 541 "203.0.113.0/24" 542 "224.0.0.0/4" 543 "::1/128" 544 "fc00::/7" 545 "fe80::/10" 546 "fec0::/10" 547 "ff00::/8" 548 ]; 549 description = lib.mdDoc '' 550 List of IP address CIDR ranges that the URL preview spider is denied 551 from accessing. 552 ''; 553 }; 554 555 url_preview_ip_range_whitelist = mkOption { 556 type = types.listOf types.str; 557 default = []; 558 description = lib.mdDoc '' 559 List of IP address CIDR ranges that the URL preview spider is allowed 560 to access even if they are specified in url_preview_ip_range_blacklist. 561 ''; 562 }; 563 564 url_preview_url_blacklist = mkOption { 565 type = types.listOf types.str; 566 default = []; 567 description = lib.mdDoc '' 568 Optional list of URL matches that the URL preview spider is 569 denied from accessing. 570 ''; 571 }; 572 573 max_upload_size = mkOption { 574 type = types.str; 575 default = "50M"; 576 example = "100M"; 577 description = lib.mdDoc '' 578 The largest allowed upload size in bytes 579 ''; 580 }; 581 582 max_image_pixels = mkOption { 583 type = types.str; 584 default = "32M"; 585 example = "64M"; 586 description = lib.mdDoc '' 587 Maximum number of pixels that will be thumbnailed 588 ''; 589 }; 590 591 dynamic_thumbnails = mkOption { 592 type = types.bool; 593 default = false; 594 example = true; 595 description = lib.mdDoc '' 596 Whether to generate new thumbnails on the fly to precisely match 597 the resolution requested by the client. If true then whenever 598 a new resolution is requested by the client the server will 599 generate a new thumbnail. If false the server will pick a thumbnail 600 from a precalculated list. 601 ''; 602 }; 603 604 turn_uris = mkOption { 605 type = types.listOf types.str; 606 default = []; 607 example = [ 608 "turn:turn.example.com:3487?transport=udp" 609 "turn:turn.example.com:3487?transport=tcp" 610 "turns:turn.example.com:5349?transport=udp" 611 "turns:turn.example.com:5349?transport=tcp" 612 ]; 613 description = lib.mdDoc '' 614 The public URIs of the TURN server to give to clients 615 ''; 616 }; 617 turn_shared_secret = mkOption { 618 type = types.str; 619 default = ""; 620 example = literalExpression '' 621 config.services.coturn.static-auth-secret 622 ''; 623 description = mdDoc '' 624 The shared secret used to compute passwords for the TURN server. 625 626 Secrets should be passed in via `extraConfigFiles`! 627 ''; 628 }; 629 630 trusted_key_servers = mkOption { 631 type = types.listOf (types.submodule { 632 options = { 633 server_name = mkOption { 634 type = types.str; 635 example = "matrix.org"; 636 description = lib.mdDoc '' 637 Hostname of the trusted server. 638 ''; 639 }; 640 641 verify_keys = mkOption { 642 type = types.nullOr (types.attrsOf types.str); 643 default = null; 644 example = literalExpression '' 645 { 646 "ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw"; 647 } 648 ''; 649 description = lib.mdDoc '' 650 Attribute set from key id to base64 encoded public key. 651 652 If specified synapse will check that the response is signed 653 by at least one of the given keys. 654 ''; 655 }; 656 }; 657 }); 658 default = [ { 659 server_name = "matrix.org"; 660 verify_keys = { 661 "ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw"; 662 }; 663 } ]; 664 description = lib.mdDoc '' 665 The trusted servers to download signing keys from. 666 ''; 667 }; 668 669 app_service_config_files = mkOption { 670 type = types.listOf types.path; 671 default = [ ]; 672 description = lib.mdDoc '' 673 A list of application service config file to use 674 ''; 675 }; 676 677 }; 678 }; 679 }; 680 681 extraConfigFiles = mkOption { 682 type = types.listOf types.path; 683 default = []; 684 description = lib.mdDoc '' 685 Extra config files to include. 686 687 The configuration files will be included based on the command line 688 argument --config-path. This allows to configure secrets without 689 having to go through the Nix store, e.g. based on deployment keys if 690 NixOps is in use. 691 ''; 692 }; 693 }; 694 }; 695 696 config = mkIf cfg.enable { 697 assertions = [ 698 { assertion = hasLocalPostgresDB -> config.services.postgresql.enable; 699 message = '' 700 Cannot deploy matrix-synapse with a configuration for a local postgresql database 701 and a missing postgresql service. Since 20.03 it's mandatory to manually configure the 702 database (please read the thread in https://github.com/NixOS/nixpkgs/pull/80447 for 703 further reference). 704 705 If you 706 - try to deploy a fresh synapse, you need to configure the database yourself. An example 707 for this can be found in <nixpkgs/nixos/tests/matrix-synapse.nix> 708 - update your existing matrix-synapse instance, you simply need to add `services.postgresql.enable = true` 709 to your configuration. 710 711 For further information about this update, please read the release-notes of 20.03 carefully. 712 ''; 713 } 714 ]; 715 716 services.matrix-synapse.configFile = configFile; 717 718 users.users.matrix-synapse = { 719 group = "matrix-synapse"; 720 home = cfg.dataDir; 721 createHome = true; 722 shell = "${pkgs.bash}/bin/bash"; 723 uid = config.ids.uids.matrix-synapse; 724 }; 725 726 users.groups.matrix-synapse = { 727 gid = config.ids.gids.matrix-synapse; 728 }; 729 730 systemd.services.matrix-synapse = { 731 description = "Synapse Matrix homeserver"; 732 after = [ "network.target" ] ++ optional hasLocalPostgresDB "postgresql.service"; 733 wantedBy = [ "multi-user.target" ]; 734 preStart = '' 735 ${cfg.package}/bin/synapse_homeserver \ 736 --config-path ${configFile} \ 737 --keys-directory ${cfg.dataDir} \ 738 --generate-keys 739 ''; 740 environment = { 741 PYTHONPATH = makeSearchPathOutput "lib" cfg.package.python.sitePackages [ pluginsEnv ]; 742 } // optionalAttrs (cfg.withJemalloc) { 743 LD_PRELOAD = "${pkgs.jemalloc}/lib/libjemalloc.so"; 744 }; 745 serviceConfig = { 746 Type = "notify"; 747 User = "matrix-synapse"; 748 Group = "matrix-synapse"; 749 WorkingDirectory = cfg.dataDir; 750 ExecStartPre = [ ("+" + (pkgs.writeShellScript "matrix-synapse-fix-permissions" '' 751 chown matrix-synapse:matrix-synapse ${cfg.dataDir}/homeserver.signing.key 752 chmod 0600 ${cfg.dataDir}/homeserver.signing.key 753 '')) ]; 754 ExecStart = '' 755 ${cfg.package}/bin/synapse_homeserver \ 756 ${ concatMapStringsSep "\n " (x: "--config-path ${x} \\") ([ configFile ] ++ cfg.extraConfigFiles) } 757 --keys-directory ${cfg.dataDir} 758 ''; 759 ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID"; 760 Restart = "on-failure"; 761 UMask = "0077"; 762 763 # Security Hardening 764 # Refer to systemd.exec(5) for option descriptions. 765 CapabilityBoundingSet = [ "" ]; 766 LockPersonality = true; 767 NoNewPrivileges = true; 768 PrivateDevices = true; 769 PrivateTmp = true; 770 PrivateUsers = true; 771 ProcSubset = "pid"; 772 ProtectClock = true; 773 ProtectControlGroups = true; 774 ProtectHome = true; 775 ProtectHostname = true; 776 ProtectKernelLogs = true; 777 ProtectKernelModules = true; 778 ProtectKernelTunables = true; 779 ProtectProc = "invisible"; 780 ProtectSystem = "strict"; 781 ReadWritePaths = [ cfg.dataDir ]; 782 RemoveIPC = true; 783 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; 784 RestrictNamespaces = true; 785 RestrictRealtime = true; 786 RestrictSUIDSGID = true; 787 SystemCallArchitectures = "native"; 788 SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ]; 789 }; 790 }; 791 792 environment.systemPackages = [ registerNewMatrixUser ]; 793 }; 794 795 meta = { 796 buildDocsInSandbox = false; 797 doc = ./synapse.xml; 798 maintainers = teams.matrix.members; 799 }; 800 801}