From 6b69268eddd752b14b49732a324e7bb486399ad2 Mon Sep 17 00:00:00 2001 From: Daniel Berteaud Date: Fri, 17 Apr 2020 01:00:30 +0200 Subject: [PATCH] Update to 2020-04-17 01:00 --- roles/jitsi/defaults/main.yml | 31 +++++++++++++++++++++- roles/jitsi/handlers/main.yml | 3 +++ roles/jitsi/tasks/conf.yml | 24 +++++++++++++---- roles/jitsi/tasks/directories.yml | 6 +++++ roles/jitsi/tasks/facts.yml | 8 +++--- roles/jitsi/tasks/install.yml | 17 +++++++++--- roles/jitsi/tasks/iptables.yml | 6 +++++ roles/jitsi/tasks/services.yml | 4 +++ roles/jitsi/templates/confmapper.json.j2 | 1 + roles/jitsi/templates/jicofo/jicofo.conf.j2 | 2 +- .../jicofo/sip-communicator.properties.j2 | 1 + roles/jitsi/templates/jitsi-confmapper.service.j2 | 19 +++++++++++++ roles/jitsi/templates/jitsi-videobridge.service.j2 | 2 +- roles/jitsi/templates/nginx.conf.j2 | 18 +++++++++---- roles/jitsi/templates/prosody.cfg.lua.j2 | 13 ++++++--- .../videobridge/sip-communicator.properties.j2 | 12 +++++++++ .../templates/videobridge/videobridge.conf.j2 | 6 +---- 17 files changed, 144 insertions(+), 29 deletions(-) create mode 100644 roles/jitsi/templates/confmapper.json.j2 create mode 100644 roles/jitsi/templates/jitsi-confmapper.service.j2 diff --git a/roles/jitsi/defaults/main.yml b/roles/jitsi/defaults/main.yml index 96ef5cc..4df12b2 100644 --- a/roles/jitsi/defaults/main.yml +++ b/roles/jitsi/defaults/main.yml @@ -18,11 +18,17 @@ jitsi_jicofo_git_url: https://github.com/jitsi/jicofo.git jitsi_jigasi_git_url: https://github.com/jitsi/jigasi.git jitsi_meet_git_url: https://github.com/jitsi/jitsi-meet.git -# XMPP server. Set to localhost would mean no certificate validation +# XMPP server to connect to. Default is the same machine jitsi_xmpp_server: "{{ inventory_hostname }}" # Port on which to connect to the XMPP server to register as a component jitsi_xmpp_component_port: 5347 +# XMPP password to connect to +jitsi_videobridge_xmpp_user: jvb +jitsi_videobridge_xmpp_domain: "{{ jitsi_auth_domain }}" +# A random pass will be created if not defined +# jitsi_videobridge_xmpp_pass: + jitsi_stun_servers: [] # jitsi_stun_servers: # - stun:meet-jit-si-turnrelay.jitsi.net:443 @@ -43,6 +49,8 @@ jitsi_auth: False # jitsi_videobridge_xmpp_secret: S3cr3t. # jitsi_jicofo_xmpp_secret: p@ssw0rd +jitsi_jicofo_xmpp_user: jicofo +jitsi_jicofo_xmpp_domain: "{{ jitsi_auth_domain }}" # Password for the focus user on the auth domain # jitsi_jicofo_xmpp_pass: p@ssw0rd @@ -216,5 +224,26 @@ jitsi_jigasi_default_room: sip #jitsi_jigasi_sip_secret: #jitsi_jigasi_sip_server: +jitsi_jigasi_xmpp_user: jigasi +jitsi_jigasi_xmpp_domain: "{{ jitsi_auth_domain }}" # Password to auth as an XMPP user. A random one will be created if missing #jitsi_jigasi_xmpp_pass: + +# conferenceMapper is used for inbound SIP call +jitsi_confmapper_port: 8823 +jitsi_confmapper_src_ip: [] +jitsi_confmapper_base_conf: + numbers: {} + # numbers: + # FR: + # - +335 99 99 99 99 + # - +339 88 88 88 88 + # EN: + # - 555 555 555 + port: "{{ jitsi_confmapper_port }}" + host: 0.0.0.0 + expire_seconds: 86400 + id_max_length: 5 + db_file: "{{ jitsi_root_dir }}/data/confmapper.sqlite" +jitsi_confmapper_extra_conf: {} +jitsi_confmapper_conf: "{{ jitsi_confmapper_base_conf | combine(jitsi_confmapper_extra_conf, recursive=True) }}" diff --git a/roles/jitsi/handlers/main.yml b/roles/jitsi/handlers/main.yml index ccf63ed..973afd9 100644 --- a/roles/jitsi/handlers/main.yml +++ b/roles/jitsi/handlers/main.yml @@ -8,3 +8,6 @@ - name: restart jitsi-jigasi service: name=jitsi-jigasi state={{ jitsi_jigasi | ternary('restarted', 'stopped') }} + +- name: restart jitsi-confmapper + service: name=jitsi-confmapper state={{ jitsi_jigasi | ternary('restarted', 'stopped') }} diff --git a/roles/jitsi/tasks/conf.yml b/roles/jitsi/tasks/conf.yml index ea94eec..7d57563 100644 --- a/roles/jitsi/tasks/conf.yml +++ b/roles/jitsi/tasks/conf.yml @@ -1,7 +1,7 @@ --- - name: Deploy prosody configuration - template: src=prosody.cfg.lua.j2 dest=/etc/prosody/ansible_conf.d/jitsi.cfg.lua + template: src=prosody.cfg.lua.j2 dest=/etc/prosody/ansible_conf.d/jitsi.cfg.lua group=prosody mode=640 register: jitsi_prosody_conf when: jitsi_xmpp_server in ['localhost', '127.0.0.1', inventory_hostname] tags: jitsi @@ -11,11 +11,16 @@ - name: Reload prosody service: name=prosody state=restarted - - name: Register the focus user - command: prosodyctl register focus {{ jitsi_auth_domain }} '{{ jitsi_jicofo_xmpp_pass }}' + - name: register XMPP users + command: prosodyctl register {{ item.user }} {{ jitsi_auth_domain }} '{{ item.pass }}' + loop: + - user: "{{ jitsi_videobridge_xmpp_user }}" + pass: "{{ jitsi_videobridge_xmpp_pass }}" + - user: "{{ jitsi_jicofo_xmpp_user }}" + pass: "{{ jitsi_jicofo_xmpp_pass }}" + - user: "{{ jitsi_jigasi_xmpp_user }}" + pass: "{{ jitsi_jigasi_xmpp_pass }}" - - name: Register the jigasi user - command: prosodyctl register jigasi {{ jitsi_auth_domain }} '{{ jitsi_jigasi_xmpp_pass }}' when: jitsi_prosody_conf is defined and jitsi_prosody_conf.changed tags: jitsi @@ -56,3 +61,12 @@ template: src=nginx.conf.j2 dest=/etc/nginx/ansible_conf.d/10-jitsi.conf notify: reload nginx tags: jitsi + +- name: Deploy conference mapper configuration + template: src=confmapper.json.j2 dest={{ jitsi_root_dir }}/etc/confmapper/config.json + notify: restart jitsi-confmapper + tags: jitsi + +- name: Link conference mapper configuration + file: path={{ jitsi_root_dir }}/confmapper/config.json src={{ jitsi_root_dir }}/etc/confmapper/config.json state=link + tags: jitsi diff --git a/roles/jitsi/tasks/directories.yml b/roles/jitsi/tasks/directories.yml index 1e6a57f..c50c5c0 100644 --- a/roles/jitsi/tasks/directories.yml +++ b/roles/jitsi/tasks/directories.yml @@ -40,4 +40,10 @@ owner: "{{ jitsi_user }}" group: "{{ jitsi_user }}" mode: 700 + - dir: "{{ jitsi_root_dir }}/etc/confmapper" + - dir: "{{ jitsi_root_dir }}/data" + owner: "{{ jitsi_user }}" + group: "{{ jitsi_user }}" + mode: 700 + - dir: "{{ jitsi_root_dir }}/confmapper" tags: jitsi diff --git a/roles/jitsi/tasks/facts.yml b/roles/jitsi/tasks/facts.yml index 4a7cb6c..7f4c6db 100644 --- a/roles/jitsi/tasks/facts.yml +++ b/roles/jitsi/tasks/facts.yml @@ -4,13 +4,13 @@ set_fact: jitsi_jigasi={{ (jitsi_jigasi_sip_user is defined and jitsi_jigasi_sip_secret is defined) | ternary(True, False) }} tags: jitsi -- name: Generate a random secret for videobridge +- name: Generate a random pass for videobridge block: - import_tasks: ../includes/get_rand_pass.yml vars: - - pass_file: "{{ jitsi_root_dir }}/meta/ansible_videobridge_xmpp_secret" - - set_fact: jitsi_videobridge_xmpp_secret={{ rand_pass }} - when: jitsi_videobridge_xmpp_secret is not defined + - pass_file: "{{ jitsi_root_dir }}/meta/ansible_videobridge_xmpp_pass" + - set_fact: jitsi_videobridge_xmpp_pass={{ rand_pass }} + when: jitsi_videobridge_xmpp_pass is not defined tags: jitsi - name: Generate a random secret for jicofo diff --git a/roles/jitsi/tasks/install.yml b/roles/jitsi/tasks/install.yml index 5694b78..957be25 100644 --- a/roles/jitsi/tasks/install.yml +++ b/roles/jitsi/tasks/install.yml @@ -5,8 +5,9 @@ name: - java-1.8.0-openjdk - git - - nodejs - - libXScrnSaver + - nodejs # needed to build meet + - libXScrnSaver # needed for jigasi + - python3 # needed for confmapper tags: jitsi # If you use an Let's Encrypt cert, it might not be there yet. In this case, create a link @@ -41,7 +42,7 @@ - name: Install or update videobridge block: - name: Build videobridge - command: /opt/maven/apache-maven/bin/mvn package -Dassembly.skipAssembly=false + command: /opt/maven/apache-maven/bin/mvn package -DskipTests -Dassembly.skipAssembly=false args: chdir: "{{ jitsi_root_dir }}/tmp/videobridge" become_user: "{{ jitsi_user }}" @@ -141,11 +142,13 @@ - jitsi-videobridge - jitsi-jicofo - jitsi-jigasi + - jitsi-confmapper register: jitsi_units notify: - restart jitsi-videobridge - restart jitsi-jicofo - restart jitsi-jigasi + - restart jitsi-confmapper tags: jitsi - name: Reload systemd @@ -196,3 +199,11 @@ - name: Install dehydrated hook template: src=dehydrated_hook.sh.j2 dest=/etc/dehydrated/hooks_deploy_cert.d/jitsi.sh mode=755 tags: jitsi + +- name: Install the conference mapping daemon + get_url: + url: https://raw.githubusercontent.com/gronke/jitsi-conferencemapper-api/master/daemon.py + dest: "{{ jitsi_root_dir }}/confmapper/daemon.py" + mode: 755 + notify: restart jitsi-confmapper + tags: jitsi diff --git a/roles/jitsi/tasks/iptables.yml b/roles/jitsi/tasks/iptables.yml index 4ce0640..92adbf1 100644 --- a/roles/jitsi/tasks/iptables.yml +++ b/roles/jitsi/tasks/iptables.yml @@ -8,3 +8,9 @@ -A INPUT -m state --state NEW -p tcp --dport {{ jitsi_videobridge_harvester_port }} -s {{ jitsi_videobridge_src_ip | join(',') }} -j ACCEPT" tags: firewall,jitsi +- name: Handle jitsi confmapper port + iptables_raw: + name: jitsi_confmapper_ports + state: "{{ (jitsi_confmapper_src_ip | length > 0) | ternary('present','absent') }}" + rules: "-A INPUT -m state --state NEW -p tcp --dport {{ jitsi_confmapper_port }} -s {{ jitsi_confmapper_src_ip | join(',') }} -j ACCEPT" + tags: firewall,jitsi diff --git a/roles/jitsi/tasks/services.yml b/roles/jitsi/tasks/services.yml index 3ab6d9b..289071b 100644 --- a/roles/jitsi/tasks/services.yml +++ b/roles/jitsi/tasks/services.yml @@ -10,3 +10,7 @@ - name: Start and enable jigasi service: name=jitsi-jigasi state={{ jitsi_jigasi | ternary('started', 'stopped') }} enabled={{ jitsi_jigasi }} tags: jitsi + +- name: Start and enable confmapper + service: name=jitsi-confmapper state={{ jitsi_jigasi | ternary('started', 'stopped') }} enabled={{ jitsi_jigasi }} + tags: jitsi diff --git a/roles/jitsi/templates/confmapper.json.j2 b/roles/jitsi/templates/confmapper.json.j2 new file mode 100644 index 0000000..9c25c11 --- /dev/null +++ b/roles/jitsi/templates/confmapper.json.j2 @@ -0,0 +1 @@ +{{ jitsi_confmapper_conf | to_nice_json }} diff --git a/roles/jitsi/templates/jicofo/jicofo.conf.j2 b/roles/jitsi/templates/jicofo/jicofo.conf.j2 index 06d5022..f068490 100644 --- a/roles/jitsi/templates/jicofo/jicofo.conf.j2 +++ b/roles/jitsi/templates/jicofo/jicofo.conf.j2 @@ -1,7 +1,7 @@ # {{ ansible_managed }} JICOFO_HOST={{ jitsi_xmpp_server }} JICOFO_DOMAIN={{ jitsi_domain }} -JICOFO_USER=focus +JICOFO_USER={{ jitsi_jicofo_xmpp_user }} JICOFO_USERDOMAIN={{ jitsi_auth_domain }} JICOFO_SECRET='{{ jitsi_jicofo_xmpp_secret }}' JICOFO_USER_PASS='{{ jitsi_jicofo_xmpp_pass }}' diff --git a/roles/jitsi/templates/jicofo/sip-communicator.properties.j2 b/roles/jitsi/templates/jicofo/sip-communicator.properties.j2 index bdbd312..11c3ac0 100644 --- a/roles/jitsi/templates/jicofo/sip-communicator.properties.j2 +++ b/roles/jitsi/templates/jicofo/sip-communicator.properties.j2 @@ -3,3 +3,4 @@ org.jitsi.jicofo.auth.URL=shibboleth:default {% elif jitsi_auth == 'ldap' %} org.jitsi.jicofo.auth.URL=XMPP:{{ jitsi_domain }} {% endif %} +org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.{{ jitsi_auth_domain }} diff --git a/roles/jitsi/templates/jitsi-confmapper.service.j2 b/roles/jitsi/templates/jitsi-confmapper.service.j2 new file mode 100644 index 0000000..8a0c0d9 --- /dev/null +++ b/roles/jitsi/templates/jitsi-confmapper.service.j2 @@ -0,0 +1,19 @@ +[Unit] +Description=Jitsi Conference Mapper +After=network.target + +[Service] +Type=simple +User={{ jitsi_user }} +Group={{ jitsi_user }} +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=full +Restart=on-failure +StartLimitInterval=0 +RestartSec=30 +ExecStart={{ jitsi_root_dir }}/confmapper/daemon.py + +[Install] +WantedBy=multi-user.target diff --git a/roles/jitsi/templates/jitsi-videobridge.service.j2 b/roles/jitsi/templates/jitsi-videobridge.service.j2 index 883d389..47a2de8 100644 --- a/roles/jitsi/templates/jitsi-videobridge.service.j2 +++ b/roles/jitsi/templates/jitsi-videobridge.service.j2 @@ -21,7 +21,7 @@ TasksMax=65000 # allow more open files for this process LimitNPROC=65000 LimitNOFILE=65000 -ExecStart={{ jitsi_root_dir }}/videobridge/jvb.sh --host=${JVB_HOST} --domain=${JVB_HOSTNAME} --port=${JVB_PORT} --secret=${JVB_SECRET} ${JVB_OPTS} +ExecStart={{ jitsi_root_dir }}/videobridge/jvb.sh ${JVB_OPTS} [Install] WantedBy=multi-user.target diff --git a/roles/jitsi/templates/nginx.conf.j2 b/roles/jitsi/templates/nginx.conf.j2 index 4b5a9b4..dad9e44 100644 --- a/roles/jitsi/templates/nginx.conf.j2 +++ b/roles/jitsi/templates/nginx.conf.j2 @@ -18,11 +18,11 @@ server { root {{ jitsi_root_dir }}/meet; index index.html; - location ~ ^/([a-zA-Z0-9=\?]+)$ { - rewrite ^/(.*)$ / break; - } - location / { - ssi on; + + # conferenceMapper endpoint + location ~ ^/(phoneNumberList|conferenceMapper) { + proxy_pass http://localhost:{{ jitsi_confmapper_port }}; + proxy_socket_keepalive on; } # BOSH endpoint @@ -57,4 +57,12 @@ server { add_header Content-Type 'text/html'; } {% endif %} + + # Conference rooms + location ~ ^/([a-zA-Z0-9=\?]+)$ { + rewrite ^/(.*)$ / break; + } + location / { + ssi on; + } } diff --git a/roles/jitsi/templates/prosody.cfg.lua.j2 b/roles/jitsi/templates/prosody.cfg.lua.j2 index df31a14..2be433b 100644 --- a/roles/jitsi/templates/prosody.cfg.lua.j2 +++ b/roles/jitsi/templates/prosody.cfg.lua.j2 @@ -76,7 +76,7 @@ VirtualHost "guest.{{ jitsi_domain }}" } {% endif %} -VirtualHost "auth.{{ jitsi_domain }}" +VirtualHost "{{ jitsi_auth_domain }}" ssl = { key = "{{ jitsi_key_path }}"; certificate = "{{ jitsi_cert_path }}"; @@ -84,12 +84,17 @@ VirtualHost "auth.{{ jitsi_domain }}" authentication = "internal_plain" c2s_require_encryption = false -admins = { "focus@auth.{{ jitsi_domain }}" } +admins = { "{{ jitsi_jicofo_xmpp_user }}@{{ jitsi_auth_domain }}" } Component "conference.{{ jitsi_domain }}" "muc" -Component "jitsi-videobridge.{{ jitsi_domain }}" - component_secret = "{{ jitsi_videobridge_xmpp_secret }}" +Component "internal.{{ jitsi_auth_domain }}" "muc" + storage = "memory" + modules_enabled = { "ping"; } + admins = { + "{{ jitsi_jicofo_xmpp_user }}@{{ jitsi_jicofo_xmpp_domain }}", + "{{ jitsi_videobridge_xmpp_user }}@{{ jitsi_videobridge_xmpp_domain }}" + } Component "focus.{{ jitsi_domain }}" component_secret = "{{ jitsi_jicofo_xmpp_secret }}" diff --git a/roles/jitsi/templates/videobridge/sip-communicator.properties.j2 b/roles/jitsi/templates/videobridge/sip-communicator.properties.j2 index e44fb54..bbae8df 100644 --- a/roles/jitsi/templates/videobridge/sip-communicator.properties.j2 +++ b/roles/jitsi/templates/videobridge/sip-communicator.properties.j2 @@ -1,7 +1,19 @@ org.jitsi.impl.neomedia.transform.srtp.SRTPCryptoContext.checkReplay=false org.jitsi.videobridge.TCP_HARVESTER_PORT={{ jitsi_videobridge_harvester_port }} org.ice4j.ipv6.DISABLED=true +org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true {% if jitsi_external_ip is defined %} org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS={{ ansible_default_ipv4.address }} org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS={{ jitsi_external_ip }} {% endif %} + +org.jitsi.videobridge.ENABLE_STATISTICS=true +org.jitsi.videobridge.STATISTICS_TRANSPORT=muc + +org.jitsi.videobridge.xmpp.user.xmppserver1.HOSTNAME={{ jitsi_xmpp_server }} +org.jitsi.videobridge.xmpp.user.xmppserver1.DOMAIN={{ jitsi_videobridge_xmpp_domain }} +org.jitsi.videobridge.xmpp.user.xmppserver1.USERNAME={{ jitsi_videobridge_xmpp_user }} +org.jitsi.videobridge.xmpp.user.xmppserver1.PASSWORD={{ jitsi_videobridge_xmpp_pass }} +org.jitsi.videobridge.xmpp.user.xmppserver1.MUC_JIDS=JvbBrewery@internal.{{ jitsi_auth_domain }} +org.jitsi.videobridge.xmpp.user.xmppserver1.MUC_NICKNAME={{ inventory_hostname | to_uuid }} + diff --git a/roles/jitsi/templates/videobridge/videobridge.conf.j2 b/roles/jitsi/templates/videobridge/videobridge.conf.j2 index 2b82ce2..1668e4e 100644 --- a/roles/jitsi/templates/videobridge/videobridge.conf.j2 +++ b/roles/jitsi/templates/videobridge/videobridge.conf.j2 @@ -1,7 +1,3 @@ -JVB_HOSTNAME={{ jitsi_domain }} -JVB_HOST={{ jitsi_xmpp_server }} -JVB_PORT={{ jitsi_xmpp_component_port }} -JVB_SECRET='{{ jitsi_videobridge_xmpp_secret }}' -JVB_OPTS="--apis=xmpp,rest" +JVB_OPTS="--apis=rest" JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION={{ jitsi_root_dir }}/etc -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=videobridge"