{config, lib, pkgs, ... }: { networking.firewall.allowedTCPPorts = [ 80 443 ]; services.postgresql.enable = true; services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"; ''; services.nginx = { enable = true; # only recommendedProxySettings and recommendedGzipSettings are strictly required, # but the rest make sense as well (according to the broken example from the manual) recommendedTlsSettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; recommendedProxySettings = true; virtualHosts = { # This host section can be placed on a different host than the rest, # i.e. to delegate from the host on which matrix / synapse actually run. # This may make migration easier; in our case it's mostly added complexity. "hacc.space" = { # see https://matrix.org/docs/spec/client_server/latest#get-well-known-matrix-client # for documentation on what should be returned at these endpoints. locations."= /.well-known/matrix/server".extraConfig = '' add_header Content-Type application/json; return 200 '${builtins.toJSON { "m.server" = "matrix.hacc.space:443"; }}'; ''; # this is to configure the nice default homeserver setting for our element web. locations."= /.well-known/matrix/client".extraConfig = let client = { "m.homeserver" = { "base_url" = "https://matrix.hacc.space"; }; "m.identity_server" = { "base_url" = "https://vector.im"; }; }; in '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; return 200 '${builtins.toJSON client}'; ''; }; # this serves the actual matrix endpoint "matrix.hacc.space" = { enableACME = true; forceSSL = true; # it is not recommended to have the actual element web interface on the same domain, # cf. https://github.com/vector-im/element-web#separate-domains on this. locations."/".extraConfig = '' return 404; ''; locations."/_matrix" = { proxyPass = "http://[::1]:8008"; }; }; # the element web client for our matrix server. "element.hacc.space" = { enableACME = true; forceSSL = true; root = pkgs.element-web.override { conf = { # the base_url here must be identical to the one on hacc.space/.well-known above. default_server_config."m.homeserver" = { "base_url" = "https://matrix.hacc.space"; "server_name" = "matrix.hacc.space"; }; }; }; }; }; }; services.matrix-synapse = { enable = true; server_name = "hacc.space"; extraConfigFiles = [ "/var/lib/matrix-synapse/secrets.yml" ]; extraConfig = '' public_baseurl: https://matrix.hacc.space email: smtp_host: mail.hacc.space smtp_user: "noreply@infra4future.de" smtp_port: 587 notif_from: "Your Friendly %(app)s homeserver " require_transport_security: true enable_notifs: true client_base_url: "https://element.hacc.space" invite_client_location: "https://element.hacc.space" enable_registration = true; allow_guest_access = true; admin_contact: 'mailto:admin@hacc.space' web_client_location: https://element.hacc.space/ public_baseurl: https://matrix.hacc.space/ use_presence: false # uses lots of CPU for bacially nothing limit_profile_requests_to_users_who_share_rooms: true # limits unoticed stalking/network analysis allow_public_rooms_without_auth: true # public rooms should be public. can be changed if too much spam occurs default_room_version: "6" limit_usage_by_mau: false # disables max userer mau_stats_only: false redaction_retention_period: 3d # ich hab keine Ahnung, was das tut, aber weniger klingt besser user_ips_max_age: 1d # ich will das Zeug gar nicht qq retention: enabled: true default_policy: min_lifetime: 1d # does nothing max_lifetime: 2w allowed_lifetime_min: 1h allowed_lifetime_max: 15w purge_jobs: - longest_max_lifetime: 1h interval: 15m - longest_max_lifetime: 1d interval: 1h - longest_max_lifetime: 3d interval: 12h - shortest_max_lifetime: 1w interval: 1d ## TLS ## # PEM-encoded X509 certificate for TLS. # This certificate, as of Synapse 1.0, will need to be a valid and verifiable # certificate, signed by a recognised Certificate Authority. # # See 'ACME support' below to enable auto-provisioning this certificate via # Let's Encrypt. # # If supplying your own, be sure to use a `.pem` file that includes the # full certificate chain including any intermediate certificates (for # instance, if using certbot, use `fullchain.pem` as your certificate, # not `cert.pem`). # #tls_certificate_path: "CONFDIR/SERVERNAME.tls.crt" # PEM-encoded private key for TLS # #tls_private_key_path: "CONFDIR/SERVERNAME.tls.key" # The minimum TLS version that will be used for outbound federation requests. # # Defaults to `1`. Configurable to `1`, `1.1`, `1.2`, or `1.3`. Note # that setting this value higher than `1.2` will prevent federation to most # of the public Matrix network: only configure it to `1.3` if you have an # entirely private federation setup and you can ensure TLS 1.3 support. # #federation_client_minimum_tls_version: 1.2 # also eigentlich will ich ja 1.3 und wieso zur hölle das nicht standard ist, keine Ahnung. Ich lass die Option mal drin, dass wir ran kommen, wenn 1.2 engültig broken ist acme: # ACME support is disabled by default. Set this to `true` and uncomment # tls_certificate_path and tls_private_key_path above to enable it. # enabled: false # Endpoint to use to request certificates. If you only want to test, # use Let's Encrypt's staging url: # https://acme-staging.api.letsencrypt.org/directory # #url: https://acme-v01.api.letsencrypt.org/directory # Port number to listen on for the HTTP-01 challenge. Change this if # you are forwarding connections through Apache/Nginx/etc. # port: 80 # Local addresses to listen on for incoming connections. # Again, you may want to change this if you are forwarding connections # through Apache/Nginx/etc. # bind_addresses: ['::', '0.0.0.0'] # How many days remaining on a certificate before it is renewed. # reprovision_threshold: 30 # The domain that the certificate should be for. Normally this # should be the same as your Matrix domain (i.e., 'server_name'), but, # by putting a file at 'https:///.well-known/matrix/server', # you can delegate incoming traffic to another server. If you do that, # you should give the target of the delegation here. # # For example: if your 'server_name' is 'example.com', but # 'https://example.com/.well-known/matrix/server' delegates to # 'matrix.example.com', you should put 'matrix.example.com' here. # # If not set, defaults to your 'server_name'. # domain: matrix.example.com # file to use for the account key. This will be generated if it doesn't # exist. # # If unspecified, we will use CONFDIR/client.key. # account_key_file: DATADIR/acme_account.key ## Database ## # The 'database' setting defines the database that synapse uses to store all of # its data. # # 'name' gives the database engine to use: either 'sqlite3' (for SQLite) or # 'psycopg2' (for PostgreSQL). # # 'args' gives options which are passed through to the database engine, # except for options starting 'cp_', which are used to configure the Twisted # connection pool. For a reference to valid arguments, see: # * for sqlite: https://docs.python.org/3/library/sqlite3.html#sqlite3.connect # * for postgres: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS # * for the connection pool: https://twistedmatrix.com/documents/current/api/twisted.enterprise.adbapi.ConnectionPool.html#__init__ # # # Example SQLite configuration: # #database: # name: sqlite3 # args: # database: /path/to/homeserver.db # # # Example Postgres configuration: # #database: # name: psycopg2 # args: # user: synapse_user # password: secretpassword # database: synapse # host: localhost # cp_min: 5 # cp_max: 10 # # For more information on using Synapse with Postgres, see `docs/postgres.md`. # #database: # name: sqlite3 # args: # database: DATADIR/homeserver.db max_upload_size: 50M max_image_pixels: 24M url_preview_enabled: false # disabled, can leak urls of encrypted communication enable_registration: false auto_join_rooms: - "#lobby:hacc.space" auto_join_rooms_for_guests: true enable_metrics: false report_stats: false password_config: policy: enabled: true minimum_length: 16 push: include_content: false group_unread_count_by_room: false encryption_enabled_by_default_for_room_type: all # invite might be the more sane setting, but like this we never retain any unecrypted messeage from our rooms enable_group_creation: true group_creation_prefix: "__" # groups created by non-admins start eith this prefix user_directory: enabled: true search_all_users: false prefer_local_users: true # User Consent configuration # # for detailed instructions, see # https://github.com/matrix-org/synapse/blob/master/docs/consent_tracking.md # # Parts of this section are required if enabling the 'consent' resource under # 'listeners', in particular 'template_dir' and 'version'. # # 'template_dir' gives the location of the templates for the HTML forms. # This directory should contain one subdirectory per language (eg, 'en', 'fr'), # and each language directory should contain the policy document (named as # '.html') and a success page (success.html). # # 'version' specifies the 'current' version of the policy document. It defines # the version to be served by the consent resource if there is no 'v' # parameter. # # 'server_notice_content', if enabled, will send a user a "Server Notice" # asking them to consent to the privacy policy. The 'server_notices' section # must also be configured for this to work. Notices will *not* be sent to # guest users unless 'send_server_notice_to_guests' is set to true. # # 'block_events_error', if set, will block any attempts to send events # until the user consents to the privacy policy. The value of the setting is # used as the text of the error. # # 'require_at_registration', if enabled, will add a step to the registration # process, similar to how captcha works. Users will be required to accept the # policy before their account is created. # # 'policy_name' is the display name of the policy users will see when registering # for an account. Has no effect unless `require_at_registration` is enabled. # Defaults to "Privacy Policy". # #user_consent: # template_dir: res/templates/privacy # version: 1.0 # server_notice_content: # msgtype: m.text # body: >- # To continue using this homeserver you must review and agree to the # terms and conditions at %(consent_uri)s # send_server_notice_to_guests: true # block_events_error: >- # To continue using this homeserver you must review and agree to the # terms and conditions at %(consent_uri)s # require_at_registration: false # policy_name: Privacy Policy # stats: enabled: true # disabling this apparently breaks the room directory bucket_size: 1w "; ''; listeners = [ { port = 8008; bind_address = "::1"; type = "http"; tls = false; x_forwarded = true; resources = [ { names = [ "client" "federation" ]; compress = false; } ]; } ]; }; }