From 5f1253638ea116b6606c7a5f2353a314a0232d51 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 17 Jan 2024 23:56:54 +0300 Subject: [PATCH] Make matrix happen --- hosts/cube/matrix-synapse.nix | 138 ++++++++++++++++++ hosts/cube/matrix.nix | 30 ---- hosts/cube/nginx.nix | 6 +- .../cube/password.secret.matrix-synapse.age | Bin 0 -> 307 bytes secrets/cube/password.sync.matrix-synapse.age | Bin 0 -> 293 bytes secrets/secrets.nix | 3 + 6 files changed, 144 insertions(+), 33 deletions(-) create mode 100644 hosts/cube/matrix-synapse.nix delete mode 100644 hosts/cube/matrix.nix create mode 100644 secrets/cube/password.secret.matrix-synapse.age create mode 100644 secrets/cube/password.sync.matrix-synapse.age diff --git a/hosts/cube/matrix-synapse.nix b/hosts/cube/matrix-synapse.nix new file mode 100644 index 0000000..cf97d5c --- /dev/null +++ b/hosts/cube/matrix-synapse.nix @@ -0,0 +1,138 @@ +{ config, ulib, ... }: with ulib; + +let + inherit (config.networking) domain; + + chatDomain = "chat.${domain}"; + + wellKnownResponse = data: '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON data}'; + ''; + + clientConfig."m.homeserver".base_url = chatDomain; + serverConfig."m.server" = "${chatDomain}:443"; + + synapsePort = 8001; + slidingSyncPort = 8002; + exporterPort = 9060; +in serverSystemConfiguration { + age.secrets."cube/password.secret.matrix-synapse".owner = "matrix-synapse"; + age.secrets."cube/password.sync.matrix-synapse".owner = "matrix-synapse"; + + services.prometheus = { + scrapeConfigs = [{ + job_name = "matrix-synapse"; + metrics_path = "/_synapse/metrics"; + + static_configs = [{ + labels.job = "matrix-synapse"; + targets = [ + "[::]:${toString exporterPort}" + ]; + }]; + }]; + }; + + services.postgresql = { + ensureDatabases = [ "matrix-synapse" "matrix-sliding-sync" ]; + ensureUsers = [ + { + name = "matrix-synapse"; + ensureDBOwnership = true; + } + { + name = "matrix-sliding-sync"; + ensureDBOwnership = true; + } + ]; + }; + + services.matrix-synapse = enabled { + withJemalloc = true; + + configureRedisLocally = true; + settings.redis.enabled = true; + + extras = [ "postgres" "url-preview" "user-search" ]; + + settings = { + server_name = domain; + # We are not setting web_client_location since the root is not accessible + # from the outside web at all. Only /_matrix is reverse proxied to. + + database.name = "psycopg2"; + + report_stats = false; + + enable_metrics = true; + metrics_flags.known_servers = true; + + allow_guest_access = false; + enable_registration = false; + + expire_access_token = true; + url_preview_enabled = true; + + # Trusting Matrix.org. + suppress_key_server_warning = true; + }; + + # Sets registration_shared_secret. + extraConfigFiles = [ config.age.secrets."cube/password.secret.matrix-synapse".path ]; + + settings.listeners = [ + { + port = synapsePort; + + bind_addresses = [ "::" ]; + tls = false; + type = "http"; + x_forwarded = true; + + resources = [{ + compress = false; + names = [ "client" "federation" ]; + }]; + } + { + port = exporterPort; + + bind_addresses = [ "::" ]; + tls = false; + type = "metrics"; + + resources = []; + } + ]; + }; + + services.matrix-sliding-sync = enabled { + settings = { + SYNCV3_SERVER = "https://${chatDomain}"; + SYNCV3_DB = "postgresql:///matrix-sliding-sync?host=/run/postgresql"; + SYNCV3_BINDADDR = "[::]:${toString slidingSyncPort}"; + }; + environmentFile = config.age.secrets."cube/password.sync.matrix-synapse".path; + }; + + services.nginx.virtualHosts.${domain}.locations = { + "= /.well-known/matrix/client".extraConfig = wellKnownResponse clientConfig; + "= /.well-known/matrix/server".extraConfig = wellKnownResponse serverConfig; + }; + + services.nginx.virtualHosts.${chatDomain} = { + forceSSL = true; + useACMEHost = domain; + + locations."/".proxyPass = "http://[::]:${toString config.services.site.port}/404"; + locations."/assets".proxyPass = "http://[::]:${toString config.services.site.port}/assets"; + + locations."= /.well-known/matrix/client".extraConfig = wellKnownResponse clientConfig; + locations."= /.well-known/matrix/server".extraConfig = wellKnownResponse serverConfig; + + locations."/_matrix".proxyPass = "http://[::]:${toString synapsePort}"; + locations."/_synapse/client".proxyPass = "http://[::]:${toString synapsePort}"; + }; +} diff --git a/hosts/cube/matrix.nix b/hosts/cube/matrix.nix deleted file mode 100644 index 3bd251a..0000000 --- a/hosts/cube/matrix.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ config, ulib, ... }: with ulib; - -# Documenting this because I found the way Matrix works a bit weird: -# -# Since it uses normal plain HTTP on ports 80 and 443, we are using -# the root domain and proxying ${domain}/_matrix to the local matrix -# instance that is running. This means there are no matrix or chat -# or whatever 3rd level domains in this setup. The server url is -# the root, everywhere. - -let - inherit (config.networking) domain; -in serverSystemConfiguration { - age.secrets."cube/password.matrix".owner = "matrix"; - age.secrets."cube/password.matrix.sync".owner = "matrix"; - - services.postgresql = { - ensureDatabases = [ "matrix" ]; - ensureUsers = [{ - name = "matrix"; - ensureDBOwnership = true; - }]; - }; - - services.matrix-synapse = { # enabled { - settings = { - server_name = domain; - }; - }; -} diff --git a/hosts/cube/nginx.nix b/hosts/cube/nginx.nix index 045e3b1..ebb4eb7 100644 --- a/hosts/cube/nginx.nix +++ b/hosts/cube/nginx.nix @@ -29,7 +29,7 @@ serverSystemConfiguration { recommendedProxySettings = true; recommendedTlsSettings = true; - appendHttpConfig = '' + commonHttpConfig = '' map $scheme $hsts_header { https "max-age=31536000; includeSubdomains; preload"; } @@ -39,9 +39,9 @@ serverSystemConfiguration { add_header "Referrer-Policy" "no-referrer"; - add_header X-Frame-Options DENY; + # add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; + # add_header X-Content-Type-Options nosniff; proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; ''; diff --git a/secrets/cube/password.secret.matrix-synapse.age b/secrets/cube/password.secret.matrix-synapse.age new file mode 100644 index 0000000000000000000000000000000000000000..9b9c21356184b5294f305c2e341a463a101c4821 GIT binary patch literal 307 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCUFE{ZY;DOZSc4%GH9 z@;59nt||}H&yKLr56B6rO41K0%MQ4W+EzQbx(#|k5 z(KgP^E!8&hFwQOy&U7}iFx5`9%nMC)ayKwe&*#$B)m6wSH#PJxDo-~oPYN~FE;fxa zPs;W(vZyEx^7aX;^fSp$F}H9^Gj+-H$mcRE@vQslljd`i)$@*IkBrFauagu6?svRd zJ!?gLcJ{B-!^=Mg`rR^=E>x2F+n}zUt(APfQ0mvW>B(|zH{K~;=CzMwSoA9OgsGU} z*SHl&DlaBSeDX7Gx4il4T+-vJ-`l6JUBdTo7TbZMjr#8{otv7mruoQ^<^Ai7HqWe9 JJ*gQx8vu$ec{Bh3 literal 0 HcmV?d00001 diff --git a/secrets/cube/password.sync.matrix-synapse.age b/secrets/cube/password.sync.matrix-synapse.age new file mode 100644 index 0000000000000000000000000000000000000000..6d47c5b6a1646aac392fadc55d164a0f2ec0175a GIT binary patch literal 293 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCUFE{ZY;DOYeaF7q}v zsH*fgH7~MstV}e_Dkv{3Pb;j>)`62@ymZKDz)I5$?~b5Z;rF!4{lK%_NQX) tO=X%X;Y%bee=|=gy`NyN6d5q1YTD0vj4Pi%-~T#LRPqPIHL?Fq#{srpZV~_h literal 0 HcmV?d00001 diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 9823c4b..95f7926 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -18,6 +18,9 @@ in with keys; { "cube/password.grafana.age".publicKeys = key cube; "cube/password.mail.grafana.age".publicKeys = key cube; + "cube/password.secret.matrix-synapse.age".publicKeys = key cube; + "cube/password.sync.matrix-synapse.age".publicKeys = key cube; + "cube/password.nextcloud.age".publicKeys = key cube; "enka/password.hash.orhan.age".publicKeys = key rgbcube;