diff options
Diffstat (limited to '')
-rw-r--r-- | hosts/by-name/server2/configuration.nix | 4 | ||||
-rw-r--r-- | modules/by-name/ji/jitsi-meet/module.nix | 108 | ||||
-rw-r--r-- | tests/by-name/ji/jitsi-meet/test.nix | 103 |
3 files changed, 215 insertions, 0 deletions
diff --git a/hosts/by-name/server2/configuration.nix b/hosts/by-name/server2/configuration.nix index 65e3b24..a492aed 100644 --- a/hosts/by-name/server2/configuration.nix +++ b/hosts/by-name/server2/configuration.nix @@ -57,6 +57,10 @@ "invidious-router.sils.li" ]; }; + jitsi-meet = { + enable = true; + domain = "jitsi-meet.vhack.eu"; + }; mail = { enable = true; fqdn = "mail.foss-syndicate.org"; diff --git a/modules/by-name/ji/jitsi-meet/module.nix b/modules/by-name/ji/jitsi-meet/module.nix new file mode 100644 index 0000000..d5844be --- /dev/null +++ b/modules/by-name/ji/jitsi-meet/module.nix @@ -0,0 +1,108 @@ +{ + config, + lib, + ... +}: let + cfg = config.vhack.jitsi-meet; +in { + options.vhack.jitsi-meet = { + enable = lib.mkEnableOption "jitsi-meet"; + + domain = lib.mkOption { + type = lib.types.str; + description = "The domain jitsi-meet should be served on."; + }; + }; + + config = lib.mkIf cfg.enable { + nixpkgs.config.permittedInsecurePackages = [ + # Jitsi uses libolm for E2EE, which is no longer maintained upstream by the element + # team (as they switch to a rust new based crypto library.) + # + # libolm has two CVEs about timing based side-channel attacks in their crypt + # primitives. This is not ideal, but it has not (yet) been exploited in the wild and + # upstream (i.e. the matrix/element team) claims, that the CVEs are very difficult to + # exploit (they have been know _long_ before element switched to the rust version). + # + # Considering the lack of deployable video conferencing alternatives, the active + # interest in upstream to resolve this issue [1] and the fact, that we are unlikely + # to be attacked via a target attack, permitting this package seems viable. + # + # [1]: https://github.com/jitsi/jitsi-meet/issues/15107 + "jitsi-meet-1.0.8043" + ]; + + services = { + nginx.virtualHosts.${cfg.domain} = { + enableACME = true; + forceSSL = true; + }; + + jitsi-meet = { + enable = true; + hostName = cfg.domain; + + nginx.enable = true; + + config = { + enableWelcomePage = true; + requireDisplayName = true; + analytics.disabled = true; + + # Don't try to GET gravata stuff. + disableThirdPartyRequests = true; + + # Avoids a heavy load on conference start. + startAudioOnly = true; + + # Only transmit the last four members. + channelLastN = 4; + + constraints.video.height = { + ideal = 720; + max = 1080; + min = 240; + }; + + remoteVideoMenu.disabled = false; + breakoutRooms.hideAddRoomButton = false; + maxFullResolutionParticipants = 1; + + prejoinPageEnabled = true; + defaultLang = "sv"; + }; + + interfaceConfig = { + GENERATE_ROOMNAMES_ON_WELCOME_PAGE = false; + DISABLE_PRESENCE_STATUS = true; + + SHOW_CHROME_EXTENSION_BANNER = false; + + # The default google play android apps comes with trackers. + MOBILE_DOWNLOAD_LINK_ANDROID = "https://f-droid.org/en/packages/org.jitsi.meet/"; + + # Don't try to promote the mobile app. + MOBILE_APP_PROMO = false; + + SHOW_JITSI_WATERMARK = false; + SHOW_WATERMARK_FOR_GUESTS = false; + }; + + prosody = { + enable = true; + + # We only use prosody for jitsi XMPP communication, and therefore can remove support + # for general XMPP server stuff. + lockdown = true; + }; + }; + + jitsi-videobridge = { + openFirewall = true; + config.videobridge = { + cc.assumed-bandwidth-limit = "1000 Mbps"; + }; + }; + }; + }; +} diff --git a/tests/by-name/ji/jitsi-meet/test.nix b/tests/by-name/ji/jitsi-meet/test.nix new file mode 100644 index 0000000..76d8539 --- /dev/null +++ b/tests/by-name/ji/jitsi-meet/test.nix @@ -0,0 +1,103 @@ +{ + nixos-lib, + pkgsUnstable, + nixpkgs-unstable, + vhackPackages, + pkgs, + extraModules, + nixLib, + ... +}: +nixos-lib.runTest { + hostPkgs = pkgs; + + name = "jitsi-meet"; + + node = { + specialArgs = {inherit pkgsUnstable extraModules vhackPackages nixpkgs-unstable nixLib;}; + + # Use the nixpkgs as constructed by the `nixpkgs.*` options + pkgs = null; + }; + + nodes = { + acme = {...}: { + imports = [ + ../../../common/acme/server.nix + ../../../common/dns/client.nix + ]; + }; + name_server = {nodes, ...}: { + imports = + extraModules + ++ [ + ../../../common/acme/client.nix + ../../../common/dns/server.nix + ]; + + vhack.dns.zones = { + "jitsi-meet.server" = { + SOA = { + nameServer = "ns"; + adminEmail = "admin@server.com"; + serial = 2025012301; + }; + useOrigin = false; + + A = [ + nodes.server.networking.primaryIPAddress + ]; + AAAA = [ + nodes.server.networking.primaryIPv6Address + ]; + }; + }; + }; + + server = {config, ...}: { + imports = + extraModules + ++ [ + ../../../../modules + ../../../common/acme/client.nix + ../../../common/dns/client.nix + ]; + + vhack = { + nginx.enable = true; + jitsi-meet = { + enable = true; + domain = "jitsi-meet.server"; + }; + }; + }; + + client = {...}: { + imports = [ + ../../../common/acme/client.nix + ../../../common/dns/client.nix + ]; + }; + }; + + testScript = {nodes, ...}: let + acme = import ../../../common/acme {inherit pkgs;}; + in + acme.prepare ["server" "client"] + # Python + '' + server.wait_for_unit("jitsi-videobridge.service") + server.wait_for_unit("jitsi-videobridge2.service") + + with subtest("All services running"): + import json + def all_services_running(host): + (status, output) = host.systemctl("list-units --state=failed --plain --no-pager --output=json") + host_failed = json.loads(output) + assert len(host_failed) == 0, f"Expected zero failing services, but found: {json.dumps(host_failed, indent=4)}" + all_services_running(server) + + client.wait_until_succeeds("curl --silent https://jitsi-meet.server") + client.succeed("curl --silent https://jitsi-meet.server | grep 'Join a WebRTC video conference'") + ''; +} |