diff --git a/hosts/hainich/configuration.nix b/hosts/hainich/configuration.nix index 02ae012..7183cbb 100644 --- a/hosts/hainich/configuration.nix +++ b/hosts/hainich/configuration.nix @@ -9,9 +9,7 @@ ./services/mail.nix ./services/codimd.nix ../../common -# ./wireguard.nix ./services/nginx.nix -# ./k8s.nix ./services/docker.nix ./services/gitlab-runner.nix ./services/lantifa.nix @@ -20,6 +18,7 @@ ./services/workadventure.nix ./services/minecraft.nix # ./services/mattermost.nix + ./services/matrix-synapse.nix ]; boot.loader.grub.enable = true; boot.loader.grub.version = 2; diff --git a/hosts/hainich/services/matrix-synapse.nix b/hosts/hainich/services/matrix-synapse.nix new file mode 100644 index 0000000..7e88452 --- /dev/null +++ b/hosts/hainich/services/matrix-synapse.nix @@ -0,0 +1,217 @@ +{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"; + public_baseurl = "https://matrix.hacc.space"; + enable_registration = true; + allow_guest_access = true; + max_upload_size = "25M"; + max_image_pixels = "25M"; + dynamic_thumbnails = true; + extraConfigFiles = [ "/var/lib/matrix-synapse/secrets.yml" ]; + extraConfig = '' + 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" + + admin_contact: 'mailto:admin@hacc.space' + web_client_location: https://element.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" + + 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 + + auto_join_rooms: + - "#lobby:hacc.space" + auto_join_rooms_for_guests: true + + 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 + # + ''; + listeners = [ { + port = 8008; + bind_address = "::1"; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ { + names = [ "client" "federation" ]; + compress = false; + } ]; + } ]; + }; +}