From 3f93dbadf18b8991fb36ff5ebf255cb0bda39522 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 17 Oct 2021 00:11:18 +0200 Subject: [PATCH] VEGAS: add matrix service Provides the following: - Synapse homeserver - Element web client - Federation support --- hosts/VEGAS/services/matrix/default.nix | 108 +++++++++++++++++++++ hosts/VEGAS/services/matrix/federation.nix | 13 +++ hosts/VEGAS/services/matrix/web-client.nix | 34 +++++++ hosts/VEGAS/system.nix | 1 + secrets/secrets.nix | 5 + secrets/synapse-db.age | 13 +++ secrets/synapse-keys.age | Bin 0 -> 715 bytes secrets/synapse-ldap.age | Bin 0 -> 1176 bytes secrets/synapse-turn.age | Bin 0 -> 733 bytes 9 files changed, 174 insertions(+) create mode 100644 hosts/VEGAS/services/matrix/default.nix create mode 100644 hosts/VEGAS/services/matrix/federation.nix create mode 100644 hosts/VEGAS/services/matrix/web-client.nix create mode 100644 secrets/synapse-db.age create mode 100644 secrets/synapse-keys.age create mode 100644 secrets/synapse-ldap.age create mode 100644 secrets/synapse-turn.age diff --git a/hosts/VEGAS/services/matrix/default.nix b/hosts/VEGAS/services/matrix/default.nix new file mode 100644 index 0000000..21096fa --- /dev/null +++ b/hosts/VEGAS/services/matrix/default.nix @@ -0,0 +1,108 @@ +{ config, lib, pkgs, tools, ... }: +let + inherit (tools.meta) domain; + listener = { + port = 8008; + bind_address = "127.0.0.1"; + type = "http"; + tls = false; + x_forwarded = true; + resources = lib.singleton { + names = [ "client" "federation" ]; + compress = false; + }; + }; + clientConfig = { + "m.homeserver".base_url = "https://matrix.${domain}:443"; + "m.integrations".managers = [{ + api_url = "https://dimension.t2bot.io/api/v1/scalar"; + ui_url = "https://dimension.t2bot.io/riot"; + }]; + } // lib.optionalAttrs config.services.jitsi-meet.enable { + "im.vector.riot.jitsi".preferredDomain = config.services.jitsi-meet.hostName; + }; + clientConfigJSON = pkgs.writeText "matrix-client-config.json" (builtins.toJSON clientConfig); + extraConfig = { + experimental_features.spaces_enabled = true; + federation_ip_range_blacklist = cfg.url_preview_ip_range_blacklist; + admin_contact = "mailto:admins@${domain}"; + max_upload_size = "32M"; + max_spider_size = "10M"; + emable_registration = true; + allow_guest_access = true; + push.include_content = true; + group_creation_prefix = "unofficial/"; + app_service_config_files = [ + "/etc/synapse/discord-registration.yaml" + ]; + turn_uris = let + combinations = lib.cartesianProductOfSets { + proto = [ "udp" "tcp" ]; + scheme = [ "turns" "turn" ]; + }; + makeTurnServer = x: "${x.scheme}:turn.${domain}?transport=${x.proto}"; + in map makeTurnServer combinations; + }; + cfg = config.services.matrix-synapse; +in { + imports = [ + ./federation.nix + ./web-client.nix + ]; + + age.secrets = { + synapse-ldap = { + file = ../../../../secrets/synapse-ldap.age; + owner = "matrix-synapse"; + group = "matrix-synapse"; + mode = "0400"; + }; + synapse-db = { + file = ../../../../secrets/synapse-db.age; + owner = "matrix-synapse"; + group = "matrix-synapse"; + mode = "0400"; + }; + synapse-turn = { + file = ../../../../secrets/synapse-turn.age; + owner = "matrix-synapse"; + group = "matrix-synapse"; + mode = "0400"; + }; + synapse-keys = { + file = ../../../../secrets/synapse-keys.age; + owner = "matrix-synapse"; + group = "matrix-synapse"; + mode = "0400"; + }; + }; + services.matrix-synapse = { + enable = true; + plugins = [ pkgs.matrix-synapse-plugins.matrix-synapse-ldap3 ]; + + server_name = domain; + listeners = lib.singleton listener; + + url_preview_enabled = true; + + extraConfigFiles = [ + (pkgs.writeText "synapse-extra-config.yaml" (builtins.toJSON extraConfig)) + ] ++ (map (x: config.age.secrets.${x}.path) [ + "synapse-ldap" + "synapse-db" + "synapse-turn" + "synapse-keys" + ]); + }; + + services.nginx.virtualHosts = tools.nginx.mappers.mapSubdomains { + matrix = tools.nginx.vhosts.basic // { + locations."/".return = "204"; + locations."/_matrix" = { + proxyPass = with listener; "${type}://${bind_address}:${builtins.toString port}"; + extraConfig = "client_max_body_size ${extraConfig.max_upload_size};"; + }; + locations."= /.well-known/matrix/client".alias = clientConfigJSON; + }; + }; +} diff --git a/hosts/VEGAS/services/matrix/federation.nix b/hosts/VEGAS/services/matrix/federation.nix new file mode 100644 index 0000000..b7ef330 --- /dev/null +++ b/hosts/VEGAS/services/matrix/federation.nix @@ -0,0 +1,13 @@ +{ config, pkgs, tools, ... }: +let + inherit (tools.meta) domain; + federation = pkgs.writeText "matrix-federation.json" (builtins.toJSON { + "m.server" = "matrix.${domain}:443"; + }); +in +{ + services.nginx.virtualHosts."top-level.${domain}".locations = { + "= /.well-known/matrix/server".alias = federation; + inherit (config.services.nginx.virtualHosts."matrix.${domain}".locations) "= /.well-known/matrix/client"; + }; +} diff --git a/hosts/VEGAS/services/matrix/web-client.nix b/hosts/VEGAS/services/matrix/web-client.nix new file mode 100644 index 0000000..449b495 --- /dev/null +++ b/hosts/VEGAS/services/matrix/web-client.nix @@ -0,0 +1,34 @@ +{ lib, pkgs, tools, ... }: +let + inherit (tools.nginx) domain vhosts; +in +{ + services.nginx.virtualHosts."chat.${domain}" = vhosts.static (pkgs.element-web.override { + conf = { + default_server_config."m.homeserver" = { + base_url = "https://matrix.${domain}:443"; + server_name = tools.meta.domain; + }; + disable_3pid_login = true; + disable_custom_urls = true; + + brand = "Private Void Chat"; + # TODO: integrations + enableLabs = true; + showLabsSettings = true; + features = with lib; flip genAttrs (_: "labs") [ + "feature_custom_status" + "feature_custom_tags" + "feature_many_integration_managers" + "feature_new_spinner" + "feature_pinning" + "feature_state_counters" + ]; + default_federate = true; + default_theme = "dark"; + roomDirectory.servers = [ domain "matrix.org" ]; + piwik = false; + jitsi.preferredDomain = "meet.${domain}"; + }; + }); +} diff --git a/hosts/VEGAS/system.nix b/hosts/VEGAS/system.nix index 5665464..553c5e3 100644 --- a/hosts/VEGAS/system.nix +++ b/hosts/VEGAS/system.nix @@ -26,6 +26,7 @@ ./services/jokes ./services/nfs ./services/mail + ./services/matrix ./services/warehouse ./services/websites ] diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 28c9084..c829f4c 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -9,7 +9,12 @@ in with hosts; "gitea-db-credentials.age".publicKeys = max ++ map systemKeys [ VEGAS ]; "hydra-db-credentials.age".publicKeys = max ++ map systemKeys [ styx ]; "hydra-s3.age".publicKeys = max ++ map systemKeys [ styx ]; + "matrix-appservice-discord-token.age".publicKeys = max ++ map systemKeys [ VEGAS ]; "oauth2_proxy-secrets.age".publicKeys = max ++ map systemKeys [ VEGAS ]; "postfix-ldap-mailboxes.age".publicKeys = max ++ map systemKeys [ VEGAS ]; + "synapse-db.age".publicKeys = max ++ map systemKeys [ VEGAS ]; + "synapse-keys.age".publicKeys = max ++ map systemKeys [ VEGAS ]; + "synapse-ldap.age".publicKeys = max ++ map systemKeys [ VEGAS ]; + "synapse-turn.age".publicKeys = max ++ map systemKeys [ VEGAS ]; "wireguard-key-wgautobahn.age".publicKeys = max ++ map systemKeys [ VEGAS ]; } diff --git a/secrets/synapse-db.age b/secrets/synapse-db.age new file mode 100644 index 0000000..2779b95 --- /dev/null +++ b/secrets/synapse-db.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-ed25519 NO562A z3CK5DY5HpHg3ACVxLrz0YF/Yn114CZeaOWbBUiDbXA +WvWSEpovH2fVJuOCk2OpzgyONyHEaQb+Koafmfz0FRM +-> ssh-ed25519 5/zT0w /FNqwfZgpihWRHg7tGH42Ak31FAC2sGtyPD20BrFuVI +GTMAwKTosLe/3xjPIrKhkQT0yKI7YaFNRNMxUOh8Rh4 +-> ssh-ed25519 d3WGuA UA4tVfhoqb0nHOXw2Z94KsnsxXtyHd3Zoowcbh7/pk0 +nIfnGT2AtUxZX/GFptH8RgN8kMoEf5/TYM8TH38CI7Y +-> ~0K&gN-grease u +J1bL/6N3ZA +--- LhSYtzwk6JfYCX5Ae7ldAsCwDg1Bg2W8BMM1oQvl9m8 +1$]ΞZPeS Nm +[d:2Y)Y^i=7s`M ]X@+Cz S!Niw;sR9dr +LWqYd 0kxe!c\˸$o1kGib4Ma{hOǶu:P#Җt7e_3 \ No newline at end of file diff --git a/secrets/synapse-keys.age b/secrets/synapse-keys.age new file mode 100644 index 0000000000000000000000000000000000000000..357c353f263ca3d75a2d55d3b47cf5bb0a903672 GIT binary patch literal 715 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCUl^EWj!a#RR6Pb@S} zDa&&9O!PL+jdIsd4lQ&n3^EBQE_ROyFOKv}4XsRd3o1!*O6GF)$t`kE@<=lB@-p!A za4Zc>Epg3qE+{lh3=c04&o#SI;*?_N)U2GGicl^u?}*^Q!tgYUOzo61ZTAclAAg@H_u!16kbs=f zEc2*zlYnevvodX$q-2n70fG7nmb&Rhsfop@3OZc*kvS&5`Ys_QmHAGl#s%8WfyGgk zxq;f=PA1O9k#14xM%h^g2FAsy875r1y1EL+DVB~tL1uZ5DS@S4!M@p%`X*UrX)cx( zPH8@cKEdXx`l-edVFrd}Iptgng;ziD5G>;fR}+0yexc;KNUi;wo^>&+HrexEEm~vy zylY9^t+(ZIzndg>A9dJ%dEt9QzB7)^mHk&ACMYc^K6F+wi063F%#zAD)@g4J@mFe= zPD^&VE6(-6cHXON&Bw#$+-7sAE)KW;slm|k?T7EG+EuN8RwQvOTXp14^}`o)AJ2M} zDfhl7f#LSe58`R&yw5)F-Q1S)zvx>>_v)I8C4m-O+@><_+nYUMsolAiSzF8OrIWX& zntl=Q^okX#ao?hrTiJf{OY}V#Zi7b!!gYI^mcRJt-^F?=$fWE}xay+prkU*xf4t3B eOl+7MSZ32Hank0%+$8A}Ge1jidUi$GA_@R&pm1nE%(#n(AL6E%+^rkI9l3P%$ahat!THJ@pxU;X}p4|h7)4zJB0rUGuC zcb?Dhyuww)#juKvD(`!9i#pp~pQk-6kB+s0GpsySA^p5~gpd?Aiz5gMHj4oVOf z*QSL{0_p$T+!7w!>386?gPA&yDVV=poz5)Og+9xG)8;W$Vn`zarEoFgQi+8jFGym9 znHwUt2nx_@3|Uwb(0F)xb`PWn-P|y0D1%v)T(0$F2C~Ga^D?+)GMxb+nZB-An7_1?dSrm0ijx$tmxJhdP=`sF^y?VJrMNA7H=HpNz*KiWJz zqXn-Y-==DvxapLwdqO)$o-ro)Zf=G>v(oH%ie8NM_NRq@`}~_Tzt|7VY(BlcIyeCB zJ(R(*-{=0H)AVzRQL7Q ztI$O?@y%5!H!|+VgZ|k!r|fK5?sFZpa}sMWjnQ#i)^4MwHojC|%1zjlR{J=dA3EMY zHA?&~7-VHwYL}twkVL~YYtz}N>~wG8nZl-5%0pQj3a(#XbKvO*&yuPwmV-SzMQ3|w zmj3BKS~>XO-Fv$mpTrN{&!m>@OOC!=Cmw71b(&r&uRKK^pZqX-S^gKWD~@fb9C)B4l84axMoTD zxi-V*6P>j`u5%^V?aRiuxG#wR@H~pW o4_qyHPHybHa;5a6!<)xxv5J$~Cp&ZIus1i}$&b6czku2GANSJlS^xk5 literal 0 HcmV?d00001 diff --git a/secrets/synapse-turn.age b/secrets/synapse-turn.age new file mode 100644 index 0000000000000000000000000000000000000000..42ce7d9008068dbd4d4b5887e009b605f436312c GIT binary patch literal 733 zcmZ9_OKZ~r003YS85+EJ7(-8C4~ENXnygLRO$KR`w(0wor0G!Brb+tBqe+`S-1MMx zBJME69mYUV#+)clJPc8g9rPdyf;y%1}A}6t<2&g#Rto_^2Tz@3A8 z%YUBjZk$F4smfc5#KH+D8R?k;xvz90{jvFRu9@4lsp6>fX` aRext{IW&tbFkQX2#Y1cCk>uI=`~Lu4-wPiA literal 0 HcmV?d00001