diff --git a/home-server.nix b/home-server.nix index ca4cae9..618786b 100644 --- a/home-server.nix +++ b/home-server.nix @@ -24,6 +24,7 @@ in with builtins; { ./services/genie.nix ./services/website.nix ./services/home-assistant + ./services/matrix ./services/watchtower.nix ./services/immich.nix ./services/miniflux.nix @@ -84,6 +85,8 @@ in with builtins; { "felschr.com" "home.felschr.com" "esphome.felschr.com" + "matrix.felschr.com" + "element.felschr.com" "cloud.felschr.com" "office.felschr.com" "media.felschr.com" diff --git a/secrets/dendrite/.env.age b/secrets/dendrite/.env.age new file mode 100644 index 0000000..83dc107 --- /dev/null +++ b/secrets/dendrite/.env.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 OAZQhA fgZF7gVrFY+mwM8BEfgkzXS7sCgarHTS2Y8UK7FB3hg +5Q45bu0Z1SbTsx0R2He4u7SErfe/DisHliYuxqisHyc +-> ssh-ed25519 72ij7w DnbIuHAmxkTqn7pgxlq91O9h0b0wsj2VighRh1WqQ0U +C1JAbl23+sZf4OClbqsc7GEGWauW9GfjCHfCmaYLaX0 +-> Oz`pkbz-grease 5w #,[ \ +JgtzmyNqvGxlyND1WSJLtlnmWYur +--- UlLvWMaswO3IWQLj/C8qhZaM2ffdsht54E6UVKRBHD8 +�K�8�kQ#N$��M�8\��"ؖϳ�S��d���Q��|32����9���DC�Pϻ6�+s(۫i|^5!�{��0�̻`������I/��U���'VY \ No newline at end of file diff --git a/secrets/dendrite/privateKey.age b/secrets/dendrite/privateKey.age new file mode 100644 index 0000000..eddc912 Binary files /dev/null and b/secrets/dendrite/privateKey.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index cd35cf6..0330a3a 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -33,4 +33,6 @@ in { "esphome/password.age".publicKeys = [ felschr home-server ]; "focalboard/.env.age".publicKeys = [ felschr home-server ]; "focalboard/db-password.age".publicKeys = [ felschr home-server ]; + "dendrite/.env.age".publicKeys = [ felschr home-server ]; + "dendrite/privateKey.age".publicKeys = [ felschr home-server ]; } diff --git a/services/matrix/default.nix b/services/matrix/default.nix new file mode 100644 index 0000000..ff3a114 --- /dev/null +++ b/services/matrix/default.nix @@ -0,0 +1,5 @@ +{ ... }: + +{ + imports = [ ./dendrite.nix ./element.nix ]; +} diff --git a/services/matrix/dendrite.nix b/services/matrix/dendrite.nix new file mode 100644 index 0000000..db0c477 --- /dev/null +++ b/services/matrix/dendrite.nix @@ -0,0 +1,124 @@ +{ config, pkgs, ... }: + +let + inherit (config.services) dendrite; + server_name = "felschr.com"; + domain = "matrix.${server_name}"; + connectionString = "postgresql:///dendrite?host=/run/postgresql"; +in { + age.secrets.dendrite-private-key = { + file = ../../secrets/dendrite/privateKey.age; + mode = "755"; + }; + age.secrets.dendrite-env = { + file = ../../secrets/dendrite/.env.age; + mode = "755"; + }; + + services.dendrite = { + enable = true; + environmentFile = config.age.secrets.dendrite-env.path; + settings = { + app_service_api.database.connection_string = connectionString; + federation_api.database.connection_string = connectionString; + key_server.database.connection_string = connectionString; + media_api.database.connection_string = connectionString; + mscs.database.connection_string = connectionString; + room_server.database.connection_string = connectionString; + sync_api.database.connection_string = connectionString; + user_api.account_database.connection_string = connectionString; + user_api.device_database.connection_string = connectionString; + + client_api.registration_shared_secret = "$REGISTRATION_SHARED_SECRET"; + + # 2 megabytes in bytes + media_api.max_file_size_bytes = 2097152; + + mscs.mscs = [ + # threading + "msc2946" + # spaces + "msc2836" + ]; + + federation_api.key_perspectives = [{ + server_name = "matrix.org"; + keys = [ + { + key_id = "ed25519:auto"; + public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw"; + } + { + key_id = "ed25519:a_RXGa"; + public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ"; + } + ]; + }]; + + global = { + inherit server_name; + private_key = config.age.secrets.dendrite-private-key.path; + jetstream.storage_path = "/var/lib/dendrite/jetstream"; + dns_cache = { + enabled = true; + cache_size = 4096; + cache_lifetime = "600s"; + }; + }; + }; + }; + + services.postgresql = { + ensureUsers = [{ + name = "dendrite"; + ensurePermissions = { "DATABASE dendrite" = "ALL PRIVILEGES"; }; + }]; + ensureDatabases = [ "dendrite" ]; + }; + + systemd.services.dendrite.after = [ "postgresql.service" ]; + + services.nginx.virtualHosts = { + ${server_name} = { + enableACME = true; + forceSSL = true; + locations = let + server = { "m.server" = "${domain}:443"; }; + client = { + "m.homeserver"."base_url" = "https://${domain}"; + "m.identity_server"."base_url" = "https://vector.im"; + }; + in { + "= /.well-known/matrix/server".extraConfig = '' + add_header Content-Type application/json; + return 200 '${builtins.toJSON server}'; + ''; + "= /.well-known/matrix/client".extraConfig = '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON client}'; + ''; + }; + }; + "${domain}" = { + enableACME = true; + forceSSL = true; + locations = { + "/".extraConfig = '' + return 404; + ''; + "/_matrix".proxyPass = + "http://127.0.0.1:${toString config.services.dendrite.httpPort}"; + }; + }; + }; + + environment.systemPackages = [ + # run like: dendrite-create-account --username --admin + (pkgs.writeShellScriptBin "dendrite-create-account" '' + ${pkgs.dendrite}/bin/create-account \ + --config /run/dendrite/dendrite.yaml \ + "$@" + '') + ]; +} diff --git a/services/matrix/element.nix b/services/matrix/element.nix new file mode 100644 index 0000000..7f38907 --- /dev/null +++ b/services/matrix/element.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +let inherit (config.services.dendrite.settings.global) server_name; +in { + services.nginx.virtualHosts."element.felschr.com" = { + forceSSL = true; + enableACME = true; + root = pkgs.element-web.override { + conf = { + default_server_config."m.homeserver" = { + "base_url" = "https://matrix.${server_name}"; + "server_name" = "${server_name}"; + }; + show_labs_settings = true; + }; + }; + }; +}