Matrix Authentication Support for Jitsi

This extends the collection with support for seamless authentication at the Jitsi server using Matrix OpenID.

1. New role for installing the [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service)
2. Changes to Jitsi role: Installing Jitsi Prosody Mods and configuring Jitsi Auth
3. Changes to Jitsi and nginx-proxy roles: Serving .well-known/element/jitsi from jitsi.DOMAIN
4. We updated the Jitsi documentation on authentication and added documentation for the user verification service.
housekeeping
jakicoll 2 years ago committed by titanz
parent 9fd152a3ec
commit adf1e78f04
Signed by: titanz
GPG Key ID: EABC72179C71D4F5

@ -39,7 +39,17 @@ By default the Jitsi Meet instance does not require any kind of login and is ope
If you're fine with such an open Jitsi instance, please skip to [Apply changes](#apply-changes).
If you would like to control who is allowed to open meetings on your new Jitsi instance, then please follow this step to enable Jitsi's authentication and guests mode. With authentication enabled, all meeting rooms have to be opened by a registered user, after which guests are free to join. If a registered host is not yet present, guests are put on hold in individual waiting rooms.
If you would like to control who is allowed to open meetings on your new Jitsi instance, then please follow the following steps to enable Jitsi's authentication and optionally guests mode.
Currently, there are three supported authentication modes: 'internal' (default), 'matrix' and 'ldap'.
**Note:** Authentication is not tested via the playbook's self-checks.
We therefore recommend that you manually verify if authentication is required by jitsi.
For this, try to manually create a conference on jitsi.DOMAIN in your browser.
### Authenticate using Jitsi accounts (Auth-Type 'internal')
The default authentication mechanism is 'internal' auth, which requires jitsi-accounts to be setup and is the recommended setup, as it also works in federated rooms.
With authentication enabled, all meeting rooms have to be opened by a registered user, after which guests are free to join.
If a registered host is not yet present, guests are put on hold in individual waiting rooms.
Add these lines to your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration:
@ -53,20 +63,35 @@ matrix_jitsi_prosody_auth_internal_accounts:
password: "another-password"
```
**Caution:** Accounts added here and subsquently removed will not be automatically removed from the Prosody server until user account cleaning is integrated into the playbook.
**Caution:** Accounts added here and subsequently removed will not be automatically removed from the Prosody server until user account cleaning is integrated into the playbook.
**If you get an error** like this: "Error: Account creation/modification not supported.", it's likely that you had previously installed Jitsi without auth/guest support. In such a case, you should look into [Rebuilding your Jitsi installation](#rebuilding-your-jitsi-installation).
### Authenticate using Matrix OpenID (Auth-Type 'matrix')
### (Optional) LDAP authentication
**Attention: Probably breaks jitsi in federated rooms and does not allow sharing conference links with guests.**
The default authentication mode of Jitsi is `internal`, however LDAP is also supported. An example LDAP configuration could be:
Using this authentication type require a [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service).
By default, this playbook creates and configures a user-verification-service to run locally, see [configuring-user-verification-service](configuring-playbook-user-verification-service.md).
To enable set this configuration at host level:
```yaml
matrix_jitsi_enable_auth: true
matrix_jitsi_auth_type: "matrix"
```
For more information see also [https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification](https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification).
### Authenticate using LDAP (Auth-Type 'ldap')
An example LDAP configuration could be:
```yaml
matrix_jitsi_enable_auth: true
matrix_jitsi_auth_type: ldap
matrix_jitsi_ldap_url: "ldap://ldap.DOMAIN"
matrix_jitsi_ldap_base: "OU=People,DC=DOMAIN
matrix_jitsi_ldap_base: "OU=People,DC=DOMAIN"
#matrix_jitsi_ldap_binddn: ""
#matrix_jitsi_ldap_bindpw: ""
matrix_jitsi_ldap_filter: "uid=%u"
@ -200,7 +225,19 @@ matrix_nginx_proxy_proxy_jitsi_additional_jvbs:
Applied together this will allow you to provision extra JVB instances which will register themselves with the prosody service and be available for jicofo
to route conferences too.
## (Optional) Enable Gravatar
In the default Jisti Meet configuration, gravatar.com is enabled as an avatar service. This results in third party request leaking data to gravatar.
Since element already sends the url of configured Matrix avatars to Jitsi, we disabled gravatar.
To enable Gravatar set:
```yaml
matrix_jitsi_disable_gravatar: false
```
**Beware:** This leaks information to a third party, namely the Gravatar-Service (unless configured otherwise: gravatar.com).
Besides metadata, this includes the matrix user_id and possibly the room identifier (via `referrer` header).
## Apply changes

@ -0,0 +1,116 @@
# Setting up Matrix User Verification Service (optional)
**[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) (hereafter: UVS) can only be installed after Matrix services are installed and running.**
If you're just installing Matrix services for the first time, please continue with the [Configuration](configuring-playbook.md) / [Installation](installing.md) flow and come back here later.
Currently, the main purpose of this role is to allow Jitsi to authenticate matrix users and check if they are authorized to join a conference. Please refer to the documentation of the [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) to understand how it works.
**Note**: enabling Matrix User Verification Service, means that the `openid` API endpoints will be exposed on the Matrix Federation port (usually `8448`), even if [federation](configuring-playbook-federation.md) is disabled.
If the Jitsi server is also configured by this collection, all plugging of variables and secrets is handled in `group_vars/matrix_servers`.
__Some general concepts of UVS may be helpful to understand the rest, so here they are:__
UVS can be used to verify two claims:
* (A) Whether a given OpenID token is valid for a given server and
* (B) whether a user is member of a given room and the corresponding PowerLevel
Verifying an OpenID token id done by finding the corresponding Homeserver via '.well-known/matrix/server' for the given domain.
The configured `matrix_user_verification_service_uvs_homeserver_url` does **not** factor into this.
By default, this collection only checks against `matrix_server_fqn_matrix`.
Therefore, the request will be made against the public openid API for `matrix_server_fqn_matrix`.
Verifying RoomMembership and PowerLevel is done against `matrix_user_verification_service_uvs_homeserver_url` which is by default done via the docker network.
UVS will verify the validity of the token beforehand though.
## Prerequisites
In order to use UVS, an admin token for the configured homeserver must be supplied. For now this means configuring Synapse and creating the token before installing UVS.
## Enable
[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) installation is disabled by default unless required by Jitsi (see group_vars/matrix_servers).
You can enable it in your configuration file (`inventory/host_vars/matrix.<your-domain>/vars.yml`):
```yaml
matrix_user_verification_service_enabled: true
```
## Configuration
The only required configuration variable is `matrix_user_verification_service_uvs_access_token` (see below).
For a list of all configuration options see the role defaults [`roles/matrix-user-verification-service/defaults/main.yml`](../roles/custom/matrix-user-verification-service/defaults/main.yml).
But be aware of all the plugging happening in `group_vars/matrix_servers`.
In the default configuration, the UVS Server is only reachable via the docker network, which is fine if e.g. Jitsi is also running in a container on the host.
However, it is possible to expose UVS via setting `matrix_user_verification_service_container_http_host_bind_port`. Be aware that the normally used port (3000) may collide with Grafana.
### Access token
The Synapse Access Token is used to verify RoomMembership and PowerLevel against the configured homeserver_url (which is plugged in group_vars).
We recommend that you create a dedicated Matrix user for uvs (`uvs` is a good username).
Follow our [Registering users](registering-users.md) guide to register a user with administration privileges.
You are required to specify an access token (belonging to this new user) for UVS to work.
To get an access token for the UVS user, you can follow the documentation on [how to do obtain an access token](obtaining-access-tokens.md).
**Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone.**
```yaml
matrix_user_verification_service_uvs_access_token: "YOUR ACCESS TOKEN HERE"
```
### (Optional) Auth Token
It is possible to set an API Auth Token to restrict access to the UVS. If this is set, anyone making a request to UVS must provide it via the header "Authorization: Bearer TOKEN"
By default, the token will be derived from `matrix_homeserver_generic_secret_key` in `group_vars/matrix_servers`.
To set your own Token, simply put the following in your host_vars.
```yaml
matrix_user_verification_service_uvs_auth_token: "TOKEN"
```
In case Jitsi is also managed by this collection and 'matrix' authentication in Jitsi is enabled, this collection will automatically configure Jitsi to use the configured auth token.
### (Optional) Federation
In theory (however currently untested), UVS can handle federation. Simply set:
```yaml
matrix_user_verification_service_uvs_openid_verify_server_name: ~
```
using host_vars to override the group_vars.
This will instruct UVS to verify the OpenID token against any domain given in a request.
Homeserver discovery is done via '.well-known/matrix/server' of the given domain.
## Installation
After these variables have been set, please run the following command to re-run setup and to restart UVS:
```
ansible-playbook -i inventory/hosts setup.yml --tags=setup-matrix-user-verification-service,start
```
## Logging
The configuration variable `UVS_LOG_LEVEL` can be set to:
- warning
- info
- debug
## TLS Certificate Checking
If the matrix Homeserver does not provide a valid TLS certificate, UVS will fail with the following error message:
> message: 'No response received: [object Object]',
This also applies to self-signed and let's encrypt staging certificates.
To disable certificate validation altogether (INSECURE! Not suitable for production use!) set: `NODE_TLS_REJECT_UNAUTHORIZED=0`
Alternatively, it is possible to inject your own CA certificates into the container by mounting a PEM file with additional trusted CAs into the container and pointing the `NODE_EXTRA_CA_CERTS` environment variable to it.

@ -320,6 +320,8 @@ devture_systemd_service_manager_services_list_auto: |
([{'name': 'matrix-synapse-admin.service', 'priority': 4000, 'groups': ['matrix', 'synapse-admin']}] if matrix_synapse_admin_enabled else [])
+
([{'name': 'matrix-synapse-reverse-proxy-companion.service', 'priority': 1500, 'groups': ['matrix', 'homeservers', 'synapse', 'reverse-proxies']}] if matrix_synapse_reverse_proxy_companion_enabled else [])
+
([{'name': 'matrix-user-verification-service.service', 'priority': 800, 'groups': ['matrix', 'matrix-user-verification-service']}] if matrix_user_verification_service_enabled else [])
}}
########################################################################
@ -2011,6 +2013,11 @@ matrix_jitsi_web_stun_servers: |
matrix_jitsi_etherpad_enabled: "{{ matrix_etherpad_enabled }}"
matrix_jitsi_etherpad_base: "{{ matrix_etherpad_base_url if matrix_etherpad_enabled else 'https://scalar.vector.im/etherpad' }}"
# Allow verification using JWT and matrix-UVS
matrix_jitsi_prosody_auth_matrix_uvs_auth_token: "{{ matrix_user_verification_service_uvs_auth_token }}"
matrix_jitsi_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}"
######################################################################
#
# /matrix-jitsi
@ -2156,7 +2163,10 @@ matrix_nginx_proxy_proxy_buscarron_enabled: "{{ matrix_bot_buscarron_enabled }}"
matrix_nginx_proxy_proxy_dimension_enabled: "{{ matrix_dimension_enabled }}"
matrix_nginx_proxy_proxy_etherpad_enabled: "{{ matrix_etherpad_enabled and matrix_etherpad_mode == 'standalone' }}"
matrix_nginx_proxy_proxy_bot_go_neb_enabled: "{{ matrix_bot_go_neb_enabled }}"
matrix_nginx_proxy_proxy_jitsi_enabled: "{{ matrix_jitsi_enabled }}"
matrix_nginx_proxy_proxy_jitsi_manage_wellknown: "{{ matrix_jitsi_require_well_known }}"
matrix_nginx_proxy_proxy_grafana_enabled: "{{ matrix_grafana_enabled }}"
matrix_nginx_proxy_proxy_sygnal_enabled: "{{ matrix_sygnal_enabled }}"
matrix_nginx_proxy_proxy_ntfy_enabled: "{{ matrix_ntfy_enabled }}"
@ -2804,7 +2814,7 @@ matrix_synapse_tls_federation_listener_enabled: false
matrix_synapse_tls_certificate_path: ~
matrix_synapse_tls_private_key_path: ~
matrix_synapse_federation_port_openid_resource_required: "{{ not matrix_synapse_federation_enabled and (matrix_dimension_enabled or matrix_ma1sd_enabled) }}"
matrix_synapse_federation_port_openid_resource_required: "{{ not matrix_synapse_federation_enabled and (matrix_dimension_enabled or matrix_ma1sd_enabled or matrix_user_verification_service_enabled) }}"
# If someone instals Prometheus via the playbook, they most likely wish to monitor Synapse.
matrix_synapse_metrics_enabled: "{{ matrix_prometheus_enabled }}"
@ -3251,3 +3261,52 @@ matrix_user_creator_users_auto: |
# /matrix-user-creator
#
######################################################################
######################################################################
#
# matrix-user-verification-service
#
######################################################################
## FIXME: Needs to be updated when there is a proper release by upstream.
matrix_user_verification_service_docker_image: "{{ matrix_user_verification_service_docker_image_name_prefix }}matrixdotorg/matrix-user-verification-service@sha256:d2aabc984dd69d258c91900c36928972d7aaef19d776caa3cd6a0fbc0e307270"
# enable if jitsi is managed by this playbook and requires JWT auth
matrix_user_verification_service_enabled: "{{ (matrix_jitsi_enabled | bool and matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == 'matrix') }}"
matrix_user_verification_service_systemd_required_services_list: |
{{
['docker.service']
+
(['matrix-synapse.service'] if matrix_synapse_enabled else [])
+
([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else [])
}}
# If Jitsi is managed by this playbook we can use the docker network - no need to expose a port.
# If Jitsi is not managed by this playbook, or you otherwise have a need for it, you can expose
# matrix-user-verfification-services's client-server port to the local host.
# Note: If grafana is also enabled, the exposed port is changed to 3003.
matrix_user_verification_service_container_http_host_bind_port: "{{ '' if (matrix_jitsi_enabled | bool and matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == 'matrix') else '127.0.0.1:' + ('3003' if matrix_nginx_proxy_proxy_grafana_enabled else '3000') }}"
# URL exposed in the docker network
matrix_user_verification_service_container_url: "http://{{ matrix_user_verification_service_container_name }}:3000"
# Set the homeserver URL to the container name if synapse is managed by this collection
matrix_user_verification_service_uvs_homeserver_url: "{{ matrix_homeserver_container_url if matrix_synapse_enabled }}"
# If synapse is managed by this collection, we will connect via docker network, which is a private ip.
# Therefore we need to disable IP checks
matrix_user_verification_service_uvs_disable_ip_blacklist: "{{'true' if matrix_synapse_enabled else 'false'}}"
matrix_user_verification_service_uvs_auth_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'uvs.auth.token', rounds=655555) | to_uuid }}"
# Pin UVS to only check openId Tokens for the matrix_server_name configured by this collection.
# This is not the homeserverURL, but rather the domain in the matrix "user ID"
matrix_user_verification_service_uvs_openid_verify_server_name: "{{ matrix_domain }}"
matrix_user_verification_service_uvs_log_level: warning
######################################################################
#
# /matrix-user-verification-service
#
######################################################################

@ -97,6 +97,7 @@
- custom/matrix-client-hydrogen
- custom/matrix-client-cinny
- custom/matrix-jitsi
- custom/matrix-user-verification-service
- custom/matrix-ldap-registration-proxy
- custom/matrix-ma1sd
- custom/matrix-dimension

@ -13,14 +13,16 @@ matrix_jitsi_enable_jaas_components: false
matrix_jitsi_enable_p2p: true
matrix_jitsi_enable_av_moderation: true
matrix_jitsi_enable_breakout_rooms: true
matrix_jitsi_disable_gravatar: true
# Authentication type, must be one of internal, jwt or ldap.
# Currently only internal and ldap mechanisms are supported by this playbook.
# Authentication type, must be one of internal, jwt, matrix or ldap.
# Currently, only internal, matrix and ldap mechanisms are supported by this playbook.
# matrix auth verifies against matrix openID, and requires a user-verification-service to run.
matrix_jitsi_auth_type: internal
# A list of Jitsi (Prosody) accounts to create using the internal authentication mechanism.
#
# Accounts added here and subsquently removed will not be automatically removed
# Accounts added here and subsequently removed will not be automatically removed
# from the Prosody server until user account cleaning is integrated into the playbook.
#
# Example:
@ -49,6 +51,23 @@ matrix_jitsi_ldap_tls_cacert_file: "/etc/ssl/certs/ca-certificates.crt"
matrix_jitsi_ldap_tls_cacert_dir: "/etc/ssl/certs"
matrix_jitsi_ldap_start_tls: false
# Auth type: matrix
matrix_jitsi_prosody_auth_matrix_user_verification_repo_location: "https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification"
matrix_jitsi_prosody_auth_matrix_user_verification_repo_target: "{{ matrix_jitsi_prosody_ext_path }}/prosody_auth_matrix_user_verification"
matrix_jitsi_prosody_auth_matrix_user_verification_repo_version: "2839499cb03894d8cfc3e5b2219441427cb133d8" # v1.8.0
matrix_jitsi_prosody_auth_matrix_uvs_sync_power_levels: true
matrix_jitsi_prosody_auth_matrix_uvs_location: "{{ matrix_user_verification_service_container_url }}"
# Should match domain, see https://github.com/vector-im/element-web/pull/15114/commits/0410a6b3be82a41457275e4d1ce879dea146e092
matrix_jitsi_prosody_auth_matrix_jwt_app_id: "{{ matrix_server_fqn_jitsi }}"
matrix_jitsi_prosody_auth_matrix_files:
- path: "mod_auth_matrix_user_verification.lua"
when: true
- path: "mod_matrix_power_sync.lua"
when: "{{ matrix_jitsi_prosody_auth_matrix_uvs_sync_power_levels }}"
# Plugged in group_vars
#matrix_jitsi_prosody_auth_matrix_uvs_auth_token:
matrix_jitsi_timezone: UTC
matrix_jitsi_xmpp_domain: meet.jitsi
@ -180,6 +199,17 @@ matrix_jitsi_prosody_docker_image_force_pull: "{{ matrix_jitsi_prosody_docker_im
matrix_jitsi_prosody_base_path: "{{ matrix_base_data_path }}/jitsi/prosody"
matrix_jitsi_prosody_config_path: "{{ matrix_jitsi_prosody_base_path }}/config"
matrix_jitsi_prosody_plugins_path: "{{ matrix_jitsi_prosody_base_path }}/prosody-plugins-custom"
matrix_jitsi_prosody_ext_path: "{{ matrix_jitsi_prosody_base_path }}/ext"
# well known is currently only needed for auth type "matrix"
matrix_jitsi_require_well_known: "{{ matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == 'matrix' }}"
matrix_jitsi_wellknown_element_jitsi_json: '{"auth": "openidtoken-jwt"}'
#
matrix_jitsi_muc_modules: |
{{
(['matrix_power_sync'] if matrix_jitsi_prosody_auth_matrix_uvs_sync_power_levels | bool else [])
}}
# A list of extra arguments to pass to the container
matrix_jitsi_prosody_container_extra_arguments: []

@ -67,3 +67,9 @@
- setup-all
- setup-jitsi
- setup-additional-jitsi-jvb
- block:
- when: matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == 'matrix'
ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_matrix_auth.yml"
tags:
- self-check

@ -0,0 +1,62 @@
---
- ansible.builtin.set_fact:
matrix_jitsi_prosody_self_check_uvs_health_url: "{{ matrix_jitsi_prosody_auth_matrix_uvs_location }}/health"
matrix_jitsi_element_jitsi_well_known_url: "{{ matrix_jitsi_web_public_url }}/.well-known/element/jitsi"
- name: Check if jitsi serves the .well-known/element/jitsi
ansible.builtin.uri:
url: "{{ matrix_jitsi_element_jitsi_well_known_url }}"
follow_redirects: none
return_content: true
validate_certs: "{{ matrix_jitsi_self_check_validate_certificates }}"
headers:
Origin: example.com
check_mode: false
register: result_well_known_jitsi_element_jitsi
ignore_errors: true
- name: Fail if .well-known not working
ansible.builtin.fail:
msg: |
Failed checking that the Jitsi well-known file for Element auth is configured at `{{ matrix_jitsi_element_jitsi_well_known_url }}`
Full error: {{ result_well_known_jitsi_element_jitsi }}
when: "result_well_known_jitsi_element_jitsi.failed"
- name: Parse JSON for well-known payload at the matrix hostname
ansible.builtin.set_fact:
well_known_matrix_payload: "{{ result_well_known_jitsi_element_jitsi.content | from_json }}"
- name: Fail if .well-known not CORS-aware
ansible.builtin.fail:
msg: "The well-known file on `{{ matrix_jitsi_element_jitsi_well_known_url }}` is not CORS-aware. The file needs to be served with an Access-Control-Allow-Origin header set."
when: "'access_control_allow_origin' not in result_well_known_jitsi_element_jitsi"
- name: Report working .well-known
ansible.builtin.debug:
msg: "well-known is configured correctly at `{{ matrix_jitsi_element_jitsi_well_known_url }}`"
- name: Check if we can reach the user verification service and if it's healthy
ansible.builtin.command:
argv:
- "docker"
- "exec"
- "matrix-jitsi-prosody"
- "wget"
- "-O"
- "-"
- "--quiet"
- "{{ matrix_jitsi_prosody_self_check_uvs_health_url | quote }}"
register: matrix_jitsi_prosody_self_check_uvs_result
ignore_errors: true
- name: Fail if user verification service is not (reachable and healthy)
ansible.builtin.fail:
msg: |
Failed checking user verification service is up (checked endpoint: `{{ matrix_jitsi_prosody_self_check_uvs_health_url }}`).
Full error: {{ matrix_jitsi_prosody_self_check_uvs_result }}
when: "matrix_jitsi_prosody_self_check_uvs_result.failed"
- name: Report healthy user verification service
ansible.builtin.debug:
msg: "User verification service is working (checked endpoint: `{{ matrix_jitsi_prosody_self_check_uvs_health_url }}`)"

@ -11,6 +11,7 @@
- {path: "{{ matrix_jitsi_prosody_base_path }}", when: true}
- {path: "{{ matrix_jitsi_prosody_config_path }}", when: true}
- {path: "{{ matrix_jitsi_prosody_plugins_path }}", when: true}
- {path: "{{ matrix_jitsi_prosody_ext_path }}", when: true}
when: item.when | bool
- name: Ensure jitsi-prosody Docker image is pulled
@ -32,6 +33,43 @@
group: "{{ matrix_user_groupname }}"
mode: 0640
# Configure matrix authentication.
- name: Install user verification plugin
ansible.builtin.include_tasks:
file: "{{ role_path }}/tasks/util/setup_jitsi_auth_uvs_install.yml"
when: matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == "matrix"
- name: Manage Jitsi .well-known
when: matrix_jitsi_require_well_known | bool
block:
- name: Ensure .well-known directories exist
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
mode: 0775
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- {path: "{{ matrix_static_files_base_path }}/.well-known/element", when: "{{ matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == 'matrix' }}"}
when: item.when | bool
# Create .well-known/element/jitsi in the static file directory for nginx-proxy.
- name: Ensure Jitsi /.well-known/element/jitsi configured
ansible.builtin.copy:
content: "{{ matrix_jitsi_wellknown_element_jitsi_json }}"
dest: "{{ matrix_static_files_base_path }}/.well-known/element/jitsi"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
when: matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == "matrix"
# END Block
# Remove matrix authentication if disabled
- name: Ensure user verification plugin is not present if matrix auth is disabled
ansible.builtin.include_tasks:
file: "{{ role_path }}/tasks/util/setup_jitsi_auth_uvs_uninstall.yml"
when: (not matrix_jitsi_enable_auth | bool) or (matrix_jitsi_auth_type != "matrix")
- name: Ensure matrix-jitsi-prosody.service file is installed
ansible.builtin.template:
src: "{{ role_path }}/templates/prosody/matrix-jitsi-prosody.service.j2"
@ -39,7 +77,9 @@
mode: 0644
register: matrix_jitsi_prosody_systemd_service_result
- name: Ensure authentication is properly configured
# Tasks that require a running prosody container are called in this file.
- name: Run prosody related tasks, that require a running container.
ansible.builtin.include_tasks:
file: "{{ role_path }}/tasks/util/setup_jitsi_auth.yml"
when: matrix_jitsi_enable_auth | bool
file: "{{ role_path }}/tasks/util/setup_jitsi_prosody_post_setup_hooks.yml"
when:
- matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == "internal"

@ -0,0 +1,17 @@
---
#
# Tasks related to configuring Jitsi internal authentication on a running prosody instance.
#
- name: Ensure Jitsi internal authentication users are configured
ansible.builtin.shell: "{{ devture_systemd_docker_base_host_command_docker }} exec matrix-jitsi-prosody prosodyctl --config /config/prosody.cfg.lua register {{ item.username | quote }} meet.jitsi {{ item.password | quote }}"
with_items: "{{ matrix_jitsi_prosody_auth_internal_accounts }}"
when:
- matrix_jitsi_prosody_auth_internal_accounts|length > 0
register: matrix_jitsi_user_configuration_result
changed_when: matrix_jitsi_user_configuration_result.rc == 0
no_log: true
#
# Tasks related to clean up after configuring internal authentication.
#

@ -1,42 +0,0 @@
---
#
# Start Necessary Services
#
- name: Ensure matrix-jitsi-prosody container is running
ansible.builtin.systemd:
state: started
name: matrix-jitsi-prosody
register: matrix_jitsi_prosody_start_result
#
# Tasks related to configuring Jitsi internal authentication
#
- name: Ensure Jitsi internal authentication users are configured
ansible.builtin.shell: "{{ devture_systemd_docker_base_host_command_docker }} exec matrix-jitsi-prosody prosodyctl --config /config/prosody.cfg.lua register {{ item.username | quote }} meet.jitsi {{ item.password | quote }}"
with_items: "{{ matrix_jitsi_prosody_auth_internal_accounts }}"
when:
- matrix_jitsi_auth_type == "internal"
- matrix_jitsi_prosody_auth_internal_accounts|length > 0
register: matrix_jitsi_user_configuration_result
changed_when: matrix_jitsi_user_configuration_result.rc == 0
no_log: true
#
# Tasks related to configuring other Jitsi authentication mechanisms
#
#
# Tasks related to cleaning after Jitsi authentication configuration
#
#
# Stop Necessary Services
#
- name: Ensure matrix-jitsi-prosody container is stopped if necessary
ansible.builtin.systemd:
state: stopped
name: matrix-jitsi-prosody
when: matrix_jitsi_prosody_start_result.changed | bool

@ -0,0 +1,13 @@
- name: Checkout Prosody Auth Matrix User Verification Plugin Repo
ansible.builtin.git:
repo: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_location }}"
dest: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_target }}"
version: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_version }}"
- name: Install Prosody Auth Matrix User Verification Plugin
ansible.builtin.copy:
remote_src: yes
src: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_target }}/{{ item.path }}"
dest: "{{ matrix_jitsi_prosody_plugins_path }}/{{ item.path }}"
with_items: "{{ matrix_jitsi_prosody_auth_matrix_files }}"
when: item.when | bool

@ -0,0 +1,26 @@
- name: Remove all files regarding prosody mod auth_matrix_user_verification and .well-known/element/jitsi
ansible.builtin.file:
path: "{{ item }}"
state: absent
with_flattened:
- "{{ matrix_static_files_base_path }}/.well-known/element/jitsi"
- "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_target }}"
- "{{ matrix_jitsi_prosody_auth_matrix_files | map(attribute='path') | map('regex_replace', '^', matrix_jitsi_prosody_plugins_path+'/') | list }}"
register: matrix_jitsi_prosody_auth_matrix_user_verification_uninstalled
- name: Remove .well-known/element directory if empty
ansible.builtin.command:
argv:
- rmdir
- "{{ matrix_static_files_base_path }}/.well-known/element"
removes: "{{matrix_static_files_base_path}}/.well-known/element"
ignore_errors: yes
- when: matrix_jitsi_prosody_auth_matrix_user_verification_uninstalled.changed
block:
- name: Populate service facts
ansible.builtin.service_facts:
- name: Ensure prosody is restarted later on if currently running
set_fact:
matrix_jitsi_prosody_require_restart: "{{ true if ansible_facts.services['matrix-jitsi-prosody.service']['state'] == 'running' else false }}"

@ -0,0 +1,49 @@
---
#####
#
# This tasks file starts and stops (if state before was stopped) a prosody container during setup to run commands,
# that require a running prosody container.
# The task is called in ../setup_jitsi_prosody_install.yml.
#
# Important: The task is called conditionally, as to only start if really needed.
# So if you add or change anything - remember to also change the 'when' in: ../setup_jitsi_prosody_install.yml
#
#####
#
# Start Necessary Services
#
- name: Ensure matrix-jitsi-prosody container is running
ansible.builtin.systemd:
state: "{{ 'restarted' if matrix_jitsi_prosody_require_restart | d(false) | bool else 'started' }}"
name: matrix-jitsi-prosody
register: matrix_jitsi_prosody_start_result
# If the flag was set, we can safely disable now.
- name: Disable require restart flag
set_fact:
matrix_jitsi_prosody_require_restart: false
#
# Tasks related to configuring Jitsi internal authentication
#
- name: Ensure internal authentication is properly configured
ansible.builtin.include_tasks:
file: "{{ role_path }}/tasks/util/prosody_post_setup_hooks/setup_jitsi_auth_internal.yml"
when: matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == "internal"
#
# Tasks related to ...
#
#
# Stop Necessary Services
#
- name: Ensure matrix-jitsi-prosody container is stopped if necessary
ansible.builtin.systemd:
state: stopped
name: matrix-jitsi-prosody
when: matrix_jitsi_prosody_start_result.changed | bool

@ -25,16 +25,25 @@
- "matrix_jitsi_jvb_auth_password"
- name: Fail if a Jitsi internal authentication account is not defined
- name: Fail if authentication is enabled, but not properly configured.
ansible.builtin.fail:
msg: >-
You have enabled authentication, but the configured auth type is missing required configuration.
Auth type 'internal':
At least one Jitsi user needs to be defined in `matrix_jitsi_prosody_auth_internal_accounts` when using internal authentication.
If you're setting up Jitsi for the first time, you may have missed a step.
Refer to our setup instructions (docs/configuring-playbook-jitsi.md).
Auth type 'matrix':
If you want to enable matrix_user_verification in jitsi,
please provide an auth token for the user verification service (uvs) using `matrix_jitsi_prosody_auth_matrix_uvs_auth_token`.
If the user-verfication-service is also managed by this playbook the token is derived from `matrix_homeserver_generic_secret_key` in the group vars.
when:
- matrix_jitsi_enable_auth | bool
- matrix_jitsi_auth_type == 'internal'
- matrix_jitsi_prosody_auth_internal_accounts|length == 0
- ((matrix_jitsi_auth_type == 'internal' and matrix_jitsi_prosody_auth_internal_accounts|length == 0)
or (matrix_jitsi_auth_type == 'matrix' and matrix_jitsi_prosody_auth_matrix_uvs_auth_token|length == 0))
- name: (Deprecation) Catch and report renamed settings

@ -41,6 +41,12 @@ LDAP_TLS_CACERT_DIR={{ matrix_jitsi_ldap_tls_cacert_dir }}
LDAP_START_TLS={{ 1 if matrix_jitsi_ldap_start_tls else 0 }}
LDAP_URL={{ matrix_jitsi_ldap_url }}
LDAP_USE_TLS={{ 1 if matrix_jitsi_ldap_use_tls else 0 }}
MATRIX_UVS_ISSUER={{ matrix_jitsi_prosody_auth_matrix_jwt_app_id }}
MATRIX_UVS_URL={{ matrix_jitsi_prosody_auth_matrix_uvs_location }}
{% if matrix_jitsi_prosody_auth_matrix_uvs_auth_token is defined %}
MATRIX_UVS_AUTH_TOKEN={{ matrix_jitsi_prosody_auth_matrix_uvs_auth_token }}
{% endif %}
MATRIX_UVS_SYNC_POWER_LEVELS={{ 'true' if matrix_jitsi_prosody_auth_matrix_uvs_sync_power_levels else 'false' }}
PUBLIC_URL={{ matrix_jitsi_web_public_url }}
TURN_CREDENTIALS={{ matrix_jitsi_turn_credentials }}
TURN_HOST={{ matrix_jitsi_turn_host }}
@ -55,7 +61,7 @@ XMPP_GUEST_DOMAIN={{ matrix_jitsi_xmpp_guest_domain }}
XMPP_MUC_DOMAIN={{ matrix_jitsi_xmpp_muc_domain }}
XMPP_INTERNAL_MUC_DOMAIN={{ matrix_jitsi_xmpp_internal_muc_domain }}
XMPP_MODULES={{ matrix_jitsi_xmpp_modules }}
XMPP_MUC_MODULES=
XMPP_MUC_MODULES={{ matrix_jitsi_muc_modules | join(',') }}
XMPP_INTERNAL_MUC_MODULES=
XMPP_RECORDER_DOMAIN={{ matrix_jitsi_recorder_domain }}
XMPP_CROSS_DOMAIN=true

@ -11,6 +11,10 @@ config.p2p.stunServers = [
];
{% endif %}
{% if matrix_jitsi_disable_gravatar %}
config.gravatar = {'disabled': true};
{% endif %}
{% if matrix_jitsi_etherpad_enabled %}
config.etherpad_base = {{ (matrix_jitsi_etherpad_base + '/p/') |to_json }}
{% endif %}

@ -203,6 +203,8 @@ matrix_nginx_proxy_proxy_bot_go_neb_hostname: "{{ matrix_server_fqn_bot_go_neb }
# Controls whether proxying the jitsi domain should be done.
matrix_nginx_proxy_proxy_jitsi_enabled: false
matrix_nginx_proxy_proxy_jitsi_hostname: "{{ matrix_server_fqn_jitsi }}"
matrix_nginx_proxy_proxy_jitsi_manage_wellknown: false
matrix_nginx_proxy_proxy_jitsi_well_known_configuration_blocks: []
# Controls whether proxying the grafana domain should be done.
matrix_nginx_proxy_proxy_grafana_enabled: false

@ -18,6 +18,15 @@
{{- configuration_block }}
{% endfor %}
{% if matrix_nginx_proxy_proxy_jitsi_manage_wellknown %}
location /.well-known {
root {{ matrix_static_files_base_path }};
expires 4h;
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
{% endif %}
location / {
{% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #}
@ -75,7 +84,7 @@
{% if matrix_nginx_proxy_enabled %}
resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s;
set $backend {{ matrix_jitsi_xmpp_bosh_url_base }};
proxy_pass $backend/xmpp-websocket;
proxy_pass $backend$request_uri;
{% else %}
{# Generic configuration for use outside of our container setup #}
proxy_pass http://127.0.0.1:5280;

@ -0,0 +1,81 @@
---
# Set this to the display name for ansible used in Output e.g. fail_msg
matrix_user_verification_service_ansible_name: "Matrix User Verification Service"
# Enable by default. This is overwritten in provided group vars.
matrix_user_verification_service_enabled: true
# Fix version tag
matrix_user_verification_service_version: "v2.0.0"
# Paths
matrix_user_verification_service_base_path: "{{ matrix_base_data_path }}/user-verification-service"
# We need the docker src directory to be named user_verification_service. See: https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/588
matrix_user_verification_service_docker_src_files_path: "{{ matrix_user_verification_service_base_path }}/docker-src/user-verification-service"
matrix_user_verification_service_config_path: "{{ matrix_user_verification_service_base_path }}/config"
matrix_user_verification_service_config_env_file: "{{ matrix_user_verification_service_config_path }}/.env"
# Set this to true in order to not use the docker image from docker hub, but rather build locally
matrix_user_verification_service_container_image_self_build: false
matrix_user_verification_service_container_image_self_build_repo: "https://github.com/matrix-org/matrix-user-verification-service.git"
matrix_user_verification_service_container_image_self_build_branch: "{{ matrix_user_verification_service_version }}"
# Docker
matrix_user_verification_service_docker_image_name_prefix: "{{ 'localhost/' if matrix_user_verification_service_container_image_self_build else matrix_container_global_registry_prefix }}"
matrix_user_verification_service_docker_image: "{{ matrix_user_verification_service_docker_image_name_prefix }}matrixdotorg/matrix-user-verification-service:{{ matrix_user_verification_service_version }}"
matrix_user_verification_service_docker_image_force_pull: "{{ matrix_user_verification_service_docker_image.endswith(':latest') }}"
matrix_user_verification_service_container_name: "matrix-user-verification-service"
# Normally this would run on port 3000 however that may conflict with grafana. It is thus advised to change this port.
#matrix_user_verification_service_container_http_host_bind_port:
matrix_user_verification_service_container_extra_arguments: []
# Systemd
matrix_user_verification_service_systemd_required_services_list: []
matrix_user_verification_service_systemd_wanted_services_list: []
matrix_user_verification_service_systemd_service_basename: "matrix-user-verification-service"
matrix_user_verification_service_systemd_service_name: "{{ matrix_user_verification_service_systemd_service_basename }}.service"
# Matrix User Verification Service Configuration
## REQUIRED
# Homeserver client API admin token (synapse only)- Required for the service to verify room membership
# matrix_user_verification_service_uvs_access_token:
# homeserver client api url
# matrix_user_verification_service_uvs_homeserver_url: ""
# disable check for non private ip range of homeserver. e.g. set to `true` if your homeserver domain resolves to a private ip.
matrix_user_verification_service_uvs_disable_ip_blacklist: false
## OPTIONAL
# Auth token to protect the API
# If this is set any calls to the provided API endpoints
# need have the header "Authorization: Bearer changeme".
# matrix_user_verification_service_uvs_auth_token: changeme
# Matrix server name to verify OpenID tokens against. See below section.
# Defaults to empty value which means verification is made against
# whatever Matrix server name passed in with the token
# matrix_user_verification_service_uvs_openid_verify_server_name: matrix.org
# Log level, defaults to 'info'
# See choices here: https://github.com/winstonjs/winston#logging-levels
# matrix_user_verification_service_uvs_log_level: info
######################################################################
##### #####
##### Variables used in this role which are not set by this role #####
##### #####
######################################################################
# matrix_user_username
# matrix_user_groupname
# matrix_user_uid
# matrix_user_gid
# matrix_container_global_registry_prefix
# matrix_docker_network
# devture_systemd_docker_base_systemd_path
# devture_systemd_docker_base_systemd_unit_home_path
# devture_systemd_docker_base_host_command_sh
# devture_systemd_docker_base_host_command_docker

@ -0,0 +1,6 @@
---
- name: Ensure systemd reloaded after matrix-user-verification-service.service installation
service:
daemon_reload: yes
listen: "reload matrix-user-verification-service"

@ -0,0 +1,24 @@
---
- name: verify all necessary variables are present
assert:
that:
- matrix_user_verification_service_uvs_access_token is defined and matrix_user_verification_service_uvs_access_token|length
- matrix_user_verification_service_uvs_homeserver_url is defined and matrix_user_verification_service_uvs_homeserver_url|length
fail_msg: "Missing variable in {{ matrix_user_verification_service_ansible_name }} role"
- block:
- when: run_setup | bool and matrix_user_verification_service_enabled | bool
ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml"
tags:
- setup-all
- setup-user-verification-service
- install-all
- install-user-verification-service
- block:
- when: run_setup | bool and not matrix_user_verification_service_enabled | bool
ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
tags:
- setup-all
- setup-user-verification-service

@ -0,0 +1,42 @@
---
- name: "Ensure Matrix User Verification Service paths exist"
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
mode: 0750
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- { path: "{{ matrix_user_verification_service_config_path }}", when: true }
- { path: "{{ matrix_user_verification_service_docker_src_files_path }}", when: "{{ matrix_user_verification_service_container_image_self_build }}" }
when: item.when | bool
- name: Ensure Matrix User Verification Service image is pulled
community.docker.docker_image:
name: "{{ matrix_user_verification_service_docker_image }}"
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
force_source: "{{ matrix_user_verification_service_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_user_verification_service_docker_image_force_pull }}"
when: "not matrix_user_verification_service_container_image_self_build | bool"
register: result
retries: "{{ devture_playbook_help_container_retries_count }}"
delay: "{{ devture_playbook_help_container_retries_delay }}"
until: result is not failed
#- block:
# TODO
# when: "matrix_user_verification_service_container_image_self_build|bool"
- name: write env file
ansible.builtin.template:
src: "{{ role_path }}/templates/.env.j2"
dest: "{{ matrix_user_verification_service_config_env_file }}"
mode: 0644
- name: Ensure matrix-user-verification-service.service installed
ansible.builtin.template:
src: "{{ role_path }}/templates/systemd/matrix-user-verification-service.service.j2"
dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_user_verification_service_systemd_service_name }}"
mode: 0644
notify: "reload matrix-user-verification-service"

@ -0,0 +1,35 @@
---
- name: Check existence of matrix-user-verification-service service
stat:
path: "{{ matrix_systemd_path }}/{{ matrix_user_verification_service_systemd_service_name }}"
register: matrix_user_verification_service_service_stat
- name: Ensure matrix-user-verification-service is stopped
service:
name: "{{ matrix_user_verification_service_systemd_service_basename }}"
state: stopped
daemon_reload: yes
register: stopping_result
when: "matrix_user_verification_service_service_stat.stat.exists|bool"
- name: Ensure matrix-user-verification-service.service doesn't exist
file:
path: "{{ matrix_systemd_path }}/{{ matrix_user_verification_service_systemd_service_name }}"
state: absent
when: "matrix_user_verification_service_service_stat.stat.exists|bool"
- name: Ensure systemd reloaded after matrix-user-verification-service.service removal
service:
daemon_reload: yes
when: "matrix_user_verification_service_service_stat.stat.exists|bool"
- name: Ensure Matrix user-verification-service paths don't exist
file:
path: "{{ matrix_user_verification_service_base_path }}"
state: absent
- name: Ensure user-verification-service Docker image doesn't exist
docker_image:
name: "{{ matrix_user_verification_service_docker_image }}"
state: absent

@ -0,0 +1,14 @@
UVS_ACCESS_TOKEN={{ matrix_user_verification_service_uvs_access_token }}
UVS_HOMESERVER_URL={{ matrix_user_verification_service_uvs_homeserver_url }}
UVS_DISABLE_IP_BLACKLIST={{ matrix_user_verification_service_uvs_disable_ip_blacklist }}
{% if matrix_user_verification_service_uvs_auth_token is defined and matrix_user_verification_service_uvs_auth_token|length %}
UVS_AUTH_TOKEN={{ matrix_user_verification_service_uvs_auth_token }}
{% endif %}
{% if matrix_user_verification_service_uvs_openid_verify_server_name is defined and matrix_user_verification_service_uvs_openid_verify_server_name|length %}
UVS_OPENID_VERIFY_SERVER_NAME={{ matrix_user_verification_service_uvs_openid_verify_server_name }}
{% endif %}
{% if matrix_user_verification_service_uvs_log_level is defined and matrix_user_verification_service_uvs_log_level|length %}
UVS_LOG_LEVEL={{ matrix_user_verification_service_uvs_log_level }}
{% endif %}

@ -0,0 +1,42 @@
#jinja2: lstrip_blocks: "True"
[Unit]
Description={{ matrix_user_verification_service_ansible_name }}
{% for service in matrix_user_verification_service_systemd_required_services_list %}
Requires={{ service }}
After={{ service }}
{% endfor %}
{% for service in matrix_user_verification_service_systemd_wanted_services_list %}
Wants={{ service }}
{% endfor %}
DefaultDependencies=no
[Service]
Type=simple
Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}"
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill {{ matrix_user_verification_service_container_name }} 2>/dev/null'
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_user_verification_service_container_name }} 2>/dev/null'
ExecStart={{ devture_systemd_docker_base_host_command_docker }} run --rm --name {{ matrix_user_verification_service_container_name }}\
--log-driver=none \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--cap-drop=ALL \
--read-only \
--network={{ matrix_docker_network }} \
{% if matrix_user_verification_service_container_http_host_bind_port %}
-p {{ matrix_user_verification_service_container_http_host_bind_port }}:3000 \
{% endif %}
--mount type=bind,src={{ matrix_user_verification_service_config_env_file }},dst=/app/.env,ro \
{% for arg in matrix_user_verification_service_container_extra_arguments %}
{{ arg }} \
{% endfor %}
{{ matrix_user_verification_service_docker_image }}
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill {{ matrix_user_verification_service_container_name }} 2>/dev/null'
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_user_verification_service_container_name }} 2>/dev/null'
Restart=always
RestartSec=30
SyslogIdentifier={{ matrix_user_verification_service_systemd_service_basename }}
[Install]
WantedBy=multi-user.target
Loading…
Cancel
Save