Merge pull request #227588 from camillemndn/jitsi-meet
nixos/jitsi-meet: updated prosody, support secure domain setup and Excalidraw whiteboards
This commit is contained in:
commit
cac11727b3
3 changed files with 201 additions and 19 deletions
|
@ -169,6 +169,15 @@ in
|
||||||
off if you want to configure it manually.
|
off if you want to configure it manually.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
excalidraw.enable = mkEnableOption (lib.mdDoc "Excalidraw collaboration backend for Jitsi");
|
||||||
|
excalidraw.port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 3002;
|
||||||
|
description = lib.mdDoc ''The port which the Excalidraw backend for Jitsi should listen to.'';
|
||||||
|
};
|
||||||
|
|
||||||
|
secureDomain.enable = mkEnableOption (lib.mdDoc "Authenticated room creation");
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -192,41 +201,118 @@ in
|
||||||
roomLocking = false;
|
roomLocking = false;
|
||||||
roomDefaultPublicJids = true;
|
roomDefaultPublicJids = true;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
|
restrict_room_creation = true
|
||||||
storage = "memory"
|
storage = "memory"
|
||||||
|
admins = { "focus@auth.${cfg.hostName}" }
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
domain = "internal.${cfg.hostName}";
|
domain = "breakout.${cfg.hostName}";
|
||||||
|
name = "Jitsi Meet Breakout MUC";
|
||||||
|
roomLocking = false;
|
||||||
|
roomDefaultPublicJids = true;
|
||||||
|
extraConfig = ''
|
||||||
|
restrict_room_creation = true
|
||||||
|
storage = "memory"
|
||||||
|
admins = { "focus@auth.${cfg.hostName}" }
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "internal.auth.${cfg.hostName}";
|
||||||
name = "Jitsi Meet Videobridge MUC";
|
name = "Jitsi Meet Videobridge MUC";
|
||||||
|
roomLocking = false;
|
||||||
|
roomDefaultPublicJids = true;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
storage = "memory"
|
storage = "memory"
|
||||||
admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" }
|
admins = { "focus@auth.${cfg.hostName}", "jvb@auth.${cfg.hostName}" }
|
||||||
'';
|
'';
|
||||||
#-- muc_room_cache_size = 1000
|
#-- muc_room_cache_size = 1000
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
domain = "lobby.${cfg.hostName}";
|
||||||
|
name = "Jitsi Meet Lobby MUC";
|
||||||
|
roomLocking = false;
|
||||||
|
roomDefaultPublicJids = true;
|
||||||
|
extraConfig = ''
|
||||||
|
restrict_room_creation = true
|
||||||
|
storage = "memory"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
extraModules = [
|
||||||
|
"pubsub"
|
||||||
|
"smacks"
|
||||||
|
"speakerstats"
|
||||||
|
"external_services"
|
||||||
|
"conference_duration"
|
||||||
|
"end_conference"
|
||||||
|
"muc_lobby_rooms"
|
||||||
|
"muc_breakout_rooms"
|
||||||
|
"av_moderation"
|
||||||
|
"muc_hide_all"
|
||||||
|
"muc_meeting_id"
|
||||||
|
"muc_domain_mapper"
|
||||||
|
"muc_rate_limit"
|
||||||
|
"limits_exception"
|
||||||
|
"persistent_lobby"
|
||||||
|
"room_metadata"
|
||||||
];
|
];
|
||||||
extraModules = [ "pubsub" "smacks" ];
|
|
||||||
extraPluginPaths = [ "${pkgs.jitsi-meet-prosody}/share/prosody-plugins" ];
|
extraPluginPaths = [ "${pkgs.jitsi-meet-prosody}/share/prosody-plugins" ];
|
||||||
extraConfig = lib.mkMerge [ (mkAfter ''
|
extraConfig = lib.mkMerge [
|
||||||
Component "focus.${cfg.hostName}" "client_proxy"
|
(mkAfter ''
|
||||||
target_address = "focus@auth.${cfg.hostName}"
|
Component "focus.${cfg.hostName}" "client_proxy"
|
||||||
|
target_address = "focus@auth.${cfg.hostName}"
|
||||||
|
|
||||||
|
Component "speakerstats.${cfg.hostName}" "speakerstats_component"
|
||||||
|
muc_component = "conference.${cfg.hostName}"
|
||||||
|
|
||||||
|
Component "conferenceduration.${cfg.hostName}" "conference_duration_component"
|
||||||
|
muc_component = "conference.${cfg.hostName}"
|
||||||
|
|
||||||
|
Component "endconference.${cfg.hostName}" "end_conference"
|
||||||
|
muc_component = "conference.${cfg.hostName}"
|
||||||
|
|
||||||
|
Component "avmoderation.${cfg.hostName}" "av_moderation_component"
|
||||||
|
muc_component = "conference.${cfg.hostName}"
|
||||||
|
|
||||||
|
Component "metadata.${cfg.hostName}" "room_metadata_component"
|
||||||
|
muc_component = "conference.${cfg.hostName}"
|
||||||
|
breakout_rooms_component = "breakout.${cfg.hostName}"
|
||||||
'')
|
'')
|
||||||
(mkBefore ''
|
(mkBefore ''
|
||||||
|
muc_mapper_domain_base = "${cfg.hostName}"
|
||||||
|
|
||||||
cross_domain_websocket = true;
|
cross_domain_websocket = true;
|
||||||
consider_websocket_secure = true;
|
consider_websocket_secure = true;
|
||||||
|
|
||||||
|
unlimited_jids = {
|
||||||
|
"focus@auth.${cfg.hostName}",
|
||||||
|
"jvb@auth.${cfg.hostName}"
|
||||||
|
}
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
virtualHosts.${cfg.hostName} = {
|
virtualHosts.${cfg.hostName} = {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
domain = cfg.hostName;
|
domain = cfg.hostName;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
authentication = "anonymous"
|
authentication = ${if cfg.secureDomain.enable then "\"internal_hashed\"" else "\"jitsi-anonymous\""}
|
||||||
c2s_require_encryption = false
|
c2s_require_encryption = false
|
||||||
admins = { "focus@auth.${cfg.hostName}" }
|
admins = { "focus@auth.${cfg.hostName}" }
|
||||||
smacks_max_unacked_stanzas = 5
|
smacks_max_unacked_stanzas = 5
|
||||||
smacks_hibernation_time = 60
|
smacks_hibernation_time = 60
|
||||||
smacks_max_hibernated_sessions = 1
|
smacks_max_hibernated_sessions = 1
|
||||||
smacks_max_old_sessions = 1
|
smacks_max_old_sessions = 1
|
||||||
|
|
||||||
|
av_moderation_component = "avmoderation.${cfg.hostName}"
|
||||||
|
speakerstats_component = "speakerstats.${cfg.hostName}"
|
||||||
|
conference_duration_component = "conferenceduration.${cfg.hostName}"
|
||||||
|
end_conference_component = "endconference.${cfg.hostName}"
|
||||||
|
|
||||||
|
c2s_require_encryption = false
|
||||||
|
lobby_muc = "lobby.${cfg.hostName}"
|
||||||
|
breakout_rooms_muc = "breakout.${cfg.hostName}"
|
||||||
|
room_metadata_component = "metadata.${cfg.hostName}"
|
||||||
|
main_muc = "conference.${cfg.hostName}"
|
||||||
'';
|
'';
|
||||||
ssl = {
|
ssl = {
|
||||||
cert = "/var/lib/jitsi-meet/jitsi-meet.crt";
|
cert = "/var/lib/jitsi-meet/jitsi-meet.crt";
|
||||||
|
@ -237,7 +323,7 @@ in
|
||||||
enabled = true;
|
enabled = true;
|
||||||
domain = "auth.${cfg.hostName}";
|
domain = "auth.${cfg.hostName}";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
authentication = "internal_plain"
|
authentication = "internal_hashed"
|
||||||
'';
|
'';
|
||||||
ssl = {
|
ssl = {
|
||||||
cert = "/var/lib/jitsi-meet/jitsi-meet.crt";
|
cert = "/var/lib/jitsi-meet/jitsi-meet.crt";
|
||||||
|
@ -252,6 +338,14 @@ in
|
||||||
c2s_require_encryption = false
|
c2s_require_encryption = false
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
virtualHosts."guest.${cfg.hostName}" = {
|
||||||
|
enabled = true;
|
||||||
|
domain = "guest.${cfg.hostName}";
|
||||||
|
extraConfig = ''
|
||||||
|
authentication = "anonymous"
|
||||||
|
c2s_require_encryption = false
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
systemd.services.prosody = mkIf cfg.prosody.enable {
|
systemd.services.prosody = mkIf cfg.prosody.enable {
|
||||||
preStart = let
|
preStart = let
|
||||||
|
@ -270,7 +364,7 @@ in
|
||||||
reloadIfChanged = true;
|
reloadIfChanged = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.jitsi-meet = {};
|
users.groups.jitsi-meet = { };
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d '/var/lib/jitsi-meet' 0750 root jitsi-meet - -"
|
"d '/var/lib/jitsi-meet' 0750 root jitsi-meet - -"
|
||||||
];
|
];
|
||||||
|
@ -317,6 +411,20 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services.jitsi-excalidraw = mkIf cfg.excalidraw.enable {
|
||||||
|
description = "Excalidraw collaboration backend for Jitsi";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment.PORT = toString cfg.excalidraw.port;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.jitsi-excalidraw}/bin/jitsi-excalidraw-backend";
|
||||||
|
Restart = "on-failure";
|
||||||
|
Group = "jitsi-meet";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.nginx.enable {
|
services.nginx = mkIf cfg.nginx.enable {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
virtualHosts.${cfg.hostName} = {
|
virtualHosts.${cfg.hostName} = {
|
||||||
|
@ -345,12 +453,23 @@ in
|
||||||
locations."=/external_api.js" = mkDefault {
|
locations."=/external_api.js" = mkDefault {
|
||||||
alias = "${pkgs.jitsi-meet}/libs/external_api.min.js";
|
alias = "${pkgs.jitsi-meet}/libs/external_api.min.js";
|
||||||
};
|
};
|
||||||
|
locations."=/_api/room-info" = {
|
||||||
|
proxyPass = "http://localhost:5280/room-info";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
'';
|
||||||
|
};
|
||||||
locations."=/config.js" = mkDefault {
|
locations."=/config.js" = mkDefault {
|
||||||
alias = overrideJs "${pkgs.jitsi-meet}/config.js" "config" (recursiveUpdate defaultCfg cfg.config) cfg.extraConfig;
|
alias = overrideJs "${pkgs.jitsi-meet}/config.js" "config" (recursiveUpdate defaultCfg cfg.config) cfg.extraConfig;
|
||||||
};
|
};
|
||||||
locations."=/interface_config.js" = mkDefault {
|
locations."=/interface_config.js" = mkDefault {
|
||||||
alias = overrideJs "${pkgs.jitsi-meet}/interface_config.js" "interfaceConfig" cfg.interfaceConfig "";
|
alias = overrideJs "${pkgs.jitsi-meet}/interface_config.js" "interfaceConfig" cfg.interfaceConfig "";
|
||||||
};
|
};
|
||||||
|
locations."/socket.io/" = mkIf cfg.excalidraw.enable {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString cfg.excalidraw.port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -359,7 +478,7 @@ in
|
||||||
virtualHosts.${cfg.hostName} = {
|
virtualHosts.${cfg.hostName} = {
|
||||||
extraConfig =
|
extraConfig =
|
||||||
let
|
let
|
||||||
templatedJitsiMeet = pkgs.runCommand "templated-jitsi-meet" {} ''
|
templatedJitsiMeet = pkgs.runCommand "templated-jitsi-meet" { } ''
|
||||||
cp -R ${pkgs.jitsi-meet}/* .
|
cp -R ${pkgs.jitsi-meet}/* .
|
||||||
for file in *.html **/*.html ; do
|
for file in *.html **/*.html ; do
|
||||||
${pkgs.sd}/bin/sd '<!--#include virtual="(.*)" -->' '{{ include "$1" }}' $file
|
${pkgs.sd}/bin/sd '<!--#include virtual="(.*)" -->' '{{ include "$1" }}' $file
|
||||||
|
@ -390,13 +509,24 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.jitsi-meet.config = recursiveUpdate
|
||||||
|
(mkIf cfg.excalidraw.enable {
|
||||||
|
whiteboard = {
|
||||||
|
enabled = true;
|
||||||
|
collabServerBaseUrl = "https://${cfg.hostName}";
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(mkIf cfg.secureDomain.enable {
|
||||||
|
hosts.anonymousdomain = "guest.${cfg.hostName}";
|
||||||
|
});
|
||||||
|
|
||||||
services.jitsi-videobridge = mkIf cfg.videobridge.enable {
|
services.jitsi-videobridge = mkIf cfg.videobridge.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
xmppConfigs."localhost" = {
|
xmppConfigs."localhost" = {
|
||||||
userName = "jvb";
|
userName = "jvb";
|
||||||
domain = "auth.${cfg.hostName}";
|
domain = "auth.${cfg.hostName}";
|
||||||
passwordFile = "/var/lib/jitsi-meet/videobridge-secret";
|
passwordFile = "/var/lib/jitsi-meet/videobridge-secret";
|
||||||
mucJids = "jvbbrewery@internal.${cfg.hostName}";
|
mucJids = "jvbbrewery@internal.auth.${cfg.hostName}";
|
||||||
disableCertificateVerification = true;
|
disableCertificateVerification = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -409,17 +539,27 @@ in
|
||||||
userName = "focus";
|
userName = "focus";
|
||||||
userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret";
|
userPasswordFile = "/var/lib/jitsi-meet/jicofo-user-secret";
|
||||||
componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret";
|
componentPasswordFile = "/var/lib/jitsi-meet/jicofo-component-secret";
|
||||||
bridgeMuc = "jvbbrewery@internal.${cfg.hostName}";
|
bridgeMuc = "jvbbrewery@internal.auth.${cfg.hostName}";
|
||||||
config = mkMerge [{
|
config = mkMerge [{
|
||||||
jicofo.xmpp.service.disable-certificate-verification = true;
|
jicofo.xmpp.service.disable-certificate-verification = true;
|
||||||
jicofo.xmpp.client.disable-certificate-verification = true;
|
jicofo.xmpp.client.disable-certificate-verification = true;
|
||||||
#} (lib.mkIf cfg.jibri.enable {
|
}
|
||||||
} (lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) {
|
(lib.mkIf (config.services.jibri.enable || cfg.jibri.enable) {
|
||||||
jicofo.jibri = {
|
jicofo.jibri = {
|
||||||
brewery-jid = "JibriBrewery@internal.${cfg.hostName}";
|
brewery-jid = "JibriBrewery@internal.auth.${cfg.hostName}";
|
||||||
pending-timeout = "90";
|
pending-timeout = "90";
|
||||||
};
|
};
|
||||||
})];
|
})
|
||||||
|
(lib.mkIf cfg.secureDomain.enable {
|
||||||
|
jicofo = {
|
||||||
|
authentication = {
|
||||||
|
enabled = "true";
|
||||||
|
type = "XMPP";
|
||||||
|
login-url = cfg.hostName;
|
||||||
|
};
|
||||||
|
xmpp.client.client-proxy = "focus.${cfg.hostName}";
|
||||||
|
};
|
||||||
|
})];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.jibri = mkIf cfg.jibri.enable {
|
services.jibri = mkIf cfg.jibri.enable {
|
||||||
|
@ -430,7 +570,7 @@ in
|
||||||
xmppDomain = cfg.hostName;
|
xmppDomain = cfg.hostName;
|
||||||
|
|
||||||
control.muc = {
|
control.muc = {
|
||||||
domain = "internal.${cfg.hostName}";
|
domain = "internal.auth.${cfg.hostName}";
|
||||||
roomName = "JibriBrewery";
|
roomName = "JibriBrewery";
|
||||||
nickname = "jibri";
|
nickname = "jibri";
|
||||||
};
|
};
|
||||||
|
|
40
pkgs/servers/jitsi-excalidraw/default.nix
Normal file
40
pkgs/servers/jitsi-excalidraw/default.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ lib
|
||||||
|
, buildNpmPackage
|
||||||
|
, fetchFromGitHub
|
||||||
|
, nodejs
|
||||||
|
, python3
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildNpmPackage rec {
|
||||||
|
pname = "jitsi-excalidraw-backend";
|
||||||
|
version = "17";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "jitsi";
|
||||||
|
repo = "excalidraw-backend";
|
||||||
|
rev = "x${version}";
|
||||||
|
hash = "sha256-aQePkVA8KRL06VewiD0ePRpj88pAItcV7B2SBnRRtCs=";
|
||||||
|
};
|
||||||
|
|
||||||
|
npmDepsHash = "sha256-BJqjaqTeg5i+ECGMuiBYVToK2i2XCOVP9yeDFz6nP4k=";
|
||||||
|
|
||||||
|
nativeBuildInputs = [ python3 ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/share
|
||||||
|
cp -r {node_modules,dist} $out/share
|
||||||
|
'';
|
||||||
|
|
||||||
|
postFixup = ''
|
||||||
|
makeWrapper ${nodejs}/bin/node $out/bin/jitsi-excalidraw-backend \
|
||||||
|
--add-flags dist/index.js \
|
||||||
|
--chdir $out/share
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Excalidraw collaboration backend for Jitsi";
|
||||||
|
homepage = "https://github.com/jitsi/excalidraw-backend";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = with maintainers; [ camillemndn ];
|
||||||
|
};
|
||||||
|
}
|
|
@ -26552,6 +26552,8 @@ with pkgs;
|
||||||
|
|
||||||
jicofo = callPackage ../servers/jicofo { };
|
jicofo = callPackage ../servers/jicofo { };
|
||||||
|
|
||||||
|
jitsi-excalidraw = callPackage ../servers/jitsi-excalidraw { };
|
||||||
|
|
||||||
jitsi-meet = callPackage ../servers/web-apps/jitsi-meet { };
|
jitsi-meet = callPackage ../servers/web-apps/jitsi-meet { };
|
||||||
|
|
||||||
jitsi-meet-prosody = callPackage ../misc/jitsi-meet-prosody { };
|
jitsi-meet-prosody = callPackage ../misc/jitsi-meet-prosody { };
|
||||||
|
|
Loading…
Reference in a new issue