diff --git a/modules/services/caddy.nix b/modules/services/caddy.nix index 86a5d9d..baef0ee 100644 --- a/modules/services/caddy.nix +++ b/modules/services/caddy.nix @@ -22,7 +22,37 @@ virtualHosts = { "nicknase27.com" = { extraConfig = '' - respond "Blank" 200 + # CORS headers for Matrix .well-known lookup + @matrix path /.well-known/matrix/* + header @matrix { + Access-Control-Allow-Origin "*" + Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" + Access-Control-Allow-Headers "X-Requested-With, Content-Type, Authorization" + Content-Type "application/json" + } + + # Matrix Client & Server Delegation + respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"https://nicknase27.com"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://rtc-jwt.nicknase27.com"}]}` + respond /.well-known/matrix/server `{"m.server":"nicknase27.com:443"}` + + # Route Matrix API requests to Tuwunel + reverse_proxy /_matrix/* localhost:6167 + + # Root domain catch-all (disable tuwunel landing page text) + respond / " " 200 + ''; + }; + # Reverse proxy for LiveKit JWT Service + "rtc-jwt.nicknase27.com" = { + extraConfig = '' + reverse_proxy localhost:8081 + ''; + }; + + # Reverse proxy for LiveKit WebSocket / Signal API + "matrix-rtc.nicknase27.com" = { + extraConfig = '' + reverse_proxy localhost:7880 ''; }; "nv.nicknase27.com" = { diff --git a/modules/services/default.nix b/modules/services/default.nix index 6e7c02e..fb142e8 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -8,6 +8,7 @@ ./vaultwarden.nix ./navidrome.nix ./homepage.nix + ./matrix.nix ./caddy.nix ./unifi.nix ./gitea.nix diff --git a/modules/services/matrix.nix b/modules/services/matrix.nix new file mode 100644 index 0000000..6111c24 --- /dev/null +++ b/modules/services/matrix.nix @@ -0,0 +1,72 @@ +{config, ...}: { + services.matrix-tuwunel = { + enable = true; + settings.global = { + server_name = "nicknase27.com"; + address = ["0.0.0.0"]; + port = [6167]; + allow_federation = true; + allow_registration = true; + new_user_displayname_suffix = " "; + registration_token_file = "${config.age.secrets.matrix-register.path}"; + unix_socket_path = "/run/tuwunel/tuwunel.sock"; + unix_socket_perms = 660; + well_known_client = "https://nicknase27.com"; + well_known_server = "nicknase27.com:443"; + msc4140_enabled = true; + }; + }; + + services.livekit = { + enable = true; + keyFile = config.age.secrets.livekit-keys.path; + openFirewall = true; + settings = { + port = 7880; + bind_addresses = ["0.0.0.0"]; + rtc = { + tcp_port = 7881; + port_range_start = 50100; + port_range_end = 50200; + + use_external_ip = false; + node_ip = "130.61.151.118"; + }; + }; + }; + + services.lk-jwt-service = { + enable = true; + port = 8081; + keyFile = config.age.secrets.livekit-keys.path; + livekitUrl = "wss://matrix-rtc.nicknase27.com"; + }; + + # Pass homeserver restriction environment variable to native JWT service + systemd.services.lk-jwt-service.environment = { + LIVEKIT_FULL_ACCESS_HOMESERVERS = "nicknase27.com"; + }; + + age.secrets = { + matrix-register = { + file = ../../secrets/matrix-register.age; + path = "/run/secrets/matrix-register"; + owner = "tuwunel"; + group = "tuwunel"; + }; + livekit-keys = { + file = ../../secrets/livekit-keys.age; + path = "/run/secrets/livekit-keys"; + }; + }; + + networking.firewall = { + allowedTCPPorts = [7881]; + allowedUDPPortRanges = [ + { + from = 50100; + to = 50200; + } + ]; + }; +} diff --git a/secrets/livekit-keys.age b/secrets/livekit-keys.age new file mode 100644 index 0000000..87ce05b Binary files /dev/null and b/secrets/livekit-keys.age differ diff --git a/secrets/matrix-register.age b/secrets/matrix-register.age new file mode 100644 index 0000000..10d8cf3 Binary files /dev/null and b/secrets/matrix-register.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index ae81f40..6efcf21 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -7,6 +7,8 @@ in { "caddy.age".publicKeys = systems; "restic.age".publicKeys = systems; "smb.age".publicKeys = systems; + "matrix-register.age".publicKeys = systems; + "livekit-keys.age".publicKeys = systems; "gitea-db.age".publicKeys = systems; "gitea-runner.age".publicKeys = systems; "navidrome.age".publicKeys = systems;