From 8cea61b4d171c115c8f5bbda2a98bcec25573613 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sun, 18 Feb 2024 09:52:00 +0200 Subject: [PATCH] Add lt-cred-mech authentication mechanism to Coturn All homeserver implementations have been updated to support this as well. It's just Jitsi that possibly doesn't work with anything other than `auth-secret`. Fixes https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191 --- docs/configuring-playbook-turn.md | 15 +++++++++++++ group_vars/matrix_servers | 21 ++++++++++++++----- roles/custom/matrix-coturn/defaults/main.yml | 18 +++++++++++++++- .../matrix-coturn/tasks/validate_config.yml | 14 ++++++++++--- .../templates/turnserver.conf.j2 | 12 ++++++++++- .../custom/matrix-dendrite/defaults/main.yml | 2 ++ .../templates/dendrite.yaml.j2 | 4 ++-- roles/custom/matrix-synapse/defaults/main.yml | 2 ++ .../templates/synapse/homeserver.yaml.j2 | 6 +++--- 9 files changed, 79 insertions(+), 15 deletions(-) diff --git a/docs/configuring-playbook-turn.md b/docs/configuring-playbook-turn.md index c7bf998fd2b..4e02dddb5f4 100644 --- a/docs/configuring-playbook-turn.md +++ b/docs/configuring-playbook-turn.md @@ -34,6 +34,21 @@ If your server has multiple external IP addresses, the Coturn role offers a diff matrix_coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7'] ``` +## Changing the authentication mechanism + +The playbook uses the [`auth-secret` authentication method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L186-L199) by default, but you may switch to the [`lt-cred-mech` method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L178) which [some report](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191) to be working better. + +To do so, add this override to your configuration: + +```yml +matrix_coturn_authentication_method: lt-cred-mech +``` + +Regardless of the selected authentication method, the playbook generates secrets automatically and passes them to the homeserver and Coturn. + +If you're using [Jitsi](./configuring-playbook-jitsi.md), note that switching to `lt-cred-mech` will remove the integration between Jitsi and your own Coturn server, because Jitsi only seems to support the `auth-secret` authentication method. + + ## Using your own external Coturn server If you'd like to use another TURN server (be it Coturn or some other one), you can configure the playbook like this: diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 265e5366972..b9ef2e6184b 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -2722,7 +2722,10 @@ matrix_coturn_container_image_self_build: "{{ matrix_architecture not in ['amd64 # to allow auto-detection (via an EchoIP service) to happen at runtime. matrix_coturn_turn_external_ip_address: "{{ ansible_host }}" -matrix_coturn_turn_static_auth_secret: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'coturn.sas', rounds=655555) | to_uuid }}" +matrix_coturn_turn_static_auth_secret: "{{ ('%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'coturn.sas', rounds=655555) | to_uuid) if matrix_coturn_authentication_method == 'auth-secret' else '' }}" + +matrix_coturn_lt_cred_mech_username: "{{ ('%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'coturn.user', rounds=655555) | to_uuid) if matrix_coturn_authentication_method == 'lt-cred-mech' else '' }}" +matrix_coturn_lt_cred_mech_password: "{{ ('%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'coturn.pass', rounds=655555) | to_uuid) if matrix_coturn_authentication_method == 'lt-cred-mech' else '' }}" matrix_coturn_tls_enabled: "{{ matrix_playbook_ssl_enabled }}" @@ -3006,7 +3009,9 @@ jitsi_web_stun_servers: | # The Jitsi instance installed by this playbook is meant for embedding into Matrix clients, so framing is allowed. jitsi_web_framing_enabled: true -jitsi_turn_credentials: "{{ matrix_coturn_turn_static_auth_secret if matrix_coturn_enabled else '' }}" +# Jitsi (Prosody) only seems to support authenticating with Coturn using `auth-secret`, not `lt-cred-mech`. +# See: https://prosody.im/doc/coturn +jitsi_turn_credentials: "{{ matrix_coturn_turn_static_auth_secret if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'auth-secret') else '' }}" jitsi_turn_host: "{{ ('turn.' + matrix_server_fqn_matrix) if matrix_coturn_enabled else '' }}" jitsi_turns_host: "{{ ('turn.' + matrix_server_fqn_matrix) if matrix_coturn_enabled else '' }}" jitsi_turn_port: "{{ matrix_coturn_container_stun_plain_host_bind_port if matrix_coturn_enabled else '' }}" @@ -3967,7 +3972,9 @@ matrix_synapse_turn_uris: | ] if matrix_coturn_enabled else []) }} -matrix_synapse_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if matrix_coturn_enabled else '' }}" +matrix_synapse_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'auth-secret') else '' }}" +matrix_synapse_turn_username: "{{ matrix_coturn_lt_cred_mech_username if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'lt-cred-mech') else '' }}" +matrix_synapse_turn_password: "{{ matrix_coturn_lt_cred_mech_password if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'lt-cred-mech') else '' }}" matrix_synapse_self_check_validate_certificates: "{{ matrix_playbook_ssl_enabled }}" @@ -4634,7 +4641,9 @@ matrix_dendrite_client_api_turn_uris: | else [] }} -matrix_dendrite_client_api_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if matrix_coturn_enabled else '' }}" +matrix_dendrite_client_api_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'auth-secret') else '' }}" +matrix_dendrite_client_api_turn_username: "{{ matrix_coturn_lt_cred_mech_username if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'lt-cred-mech') else '' }}" +matrix_dendrite_client_api_turn_password: "{{ matrix_coturn_lt_cred_mech_password if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'lt-cred-mech') else '' }}" matrix_dendrite_disable_tls_validation: "{{ not matrix_playbook_ssl_enabled }}" @@ -4712,7 +4721,9 @@ matrix_conduit_turn_uris: | ] if matrix_coturn_enabled else []) }} -matrix_conduit_turn_secret: "{{ matrix_coturn_turn_static_auth_secret if matrix_coturn_enabled else '' }}" +matrix_conduit_turn_secret: "{{ matrix_coturn_turn_static_auth_secret if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'auth-secret') else '' }}" +matrix_conduit_turn_username: "{{ matrix_coturn_lt_cred_mech_username if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'lt-cred-mech') else '' }}" +matrix_conduit_turn_password: "{{ matrix_coturn_lt_cred_mech_password if (matrix_coturn_enabled and matrix_coturn_authentication_method == 'lt-cred-mech') else '' }}" matrix_conduit_systemd_required_services_list: | {{ diff --git a/roles/custom/matrix-coturn/defaults/main.yml b/roles/custom/matrix-coturn/defaults/main.yml index cb242539618..5c1ca5acf59 100644 --- a/roles/custom/matrix-coturn/defaults/main.yml +++ b/roles/custom/matrix-coturn/defaults/main.yml @@ -73,10 +73,26 @@ matrix_coturn_container_turn_range_listen_interface: "{{ '' if matrix_coturn_con matrix_coturn_turn_udp_min_port: 49152 matrix_coturn_turn_udp_max_port: 49172 -# A shared secret (between Synapse and Coturn) used for authentication. +# Controls which authentication method to enable. +# +# lt-cred-mech likely provides better compatibility, +# as described here: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191 +# but those claims are unverified. +# +# For now, we still default to `auth-secret` like we've always done. +# +# Known values: auth-secret, lt-cred-mech +matrix_coturn_authentication_method: auth-secret + +# A shared secret used for authentication when `matrix_coturn_authentication_method` is `auth-secret`. # You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`). matrix_coturn_turn_static_auth_secret: "" +# A username used authentication when `matrix_coturn_authentication_method` is `lt-cred-mech`. +matrix_coturn_lt_cred_mech_username: "" +# A password used authentication when `matrix_coturn_authentication_method` is `lt-cred-mech`. +matrix_coturn_lt_cred_mech_password: "" + # The external IP address of the machine where Coturn is. # If do not define an IP address here or in `matrix_coturn_turn_external_ip_addresses`, auto-detection via an EchoIP service will be done. # See `matrix_coturn_turn_external_ip_address_auto_detection_enabled` diff --git a/roles/custom/matrix-coturn/tasks/validate_config.yml b/roles/custom/matrix-coturn/tasks/validate_config.yml index 19ddb6e13d4..96205b0e03d 100644 --- a/roles/custom/matrix-coturn/tasks/validate_config.yml +++ b/roles/custom/matrix-coturn/tasks/validate_config.yml @@ -9,10 +9,18 @@ with_items: - {'old': 'matrix_coturn_docker_network', 'new': 'matrix_coturn_container_network'} +- name: Fail if matrix_coturn_authentication_method is invalid + ansible.builtin.fail: + msg: >- + Invalid authentication method specified in `matrix_coturn_authentication_method` + when: "matrix_coturn_authentication_method not in ['auth-secret', 'lt-cred-mech']" + - name: Fail if required Coturn settings not defined ansible.builtin.fail: msg: >- - You need to define a required configuration setting (`{{ item }}`) for using Coturn. - when: "vars[item] == ''" + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and vars[item.name] == ''" with_items: - - "matrix_coturn_turn_static_auth_secret" + - {'name': 'matrix_coturn_turn_static_auth_secret', when: "{{ matrix_coturn_authentication_method == 'auth-secret' }}"} + - {'name': 'matrix_coturn_lt_cred_mech_username', when: "{{ matrix_coturn_authentication_method == 'lt-cred-mech' }}"} + - {'name': 'matrix_coturn_lt_cred_mech_password', when: "{{ matrix_coturn_authentication_method == 'lt-cred-mech' }}"} diff --git a/roles/custom/matrix-coturn/templates/turnserver.conf.j2 b/roles/custom/matrix-coturn/templates/turnserver.conf.j2 index b4688ff9e53..8debab90907 100644 --- a/roles/custom/matrix-coturn/templates/turnserver.conf.j2 +++ b/roles/custom/matrix-coturn/templates/turnserver.conf.j2 @@ -1,17 +1,27 @@ #jinja2: lstrip_blocks: "True" + +{% if matrix_coturn_authentication_method == 'auth-secret' %} use-auth-secret static-auth-secret={{ matrix_coturn_turn_static_auth_secret }} +userdb=/var/tmp/turnserver.db +{% endif %} + +{% if matrix_coturn_authentication_method == 'lt-cred-mech' %} +lt-cred-mech +user={{ matrix_coturn_lt_cred_mech_username }}:{{ matrix_coturn_lt_cred_mech_password }} +{% endif %} + realm=turn.{{ matrix_server_fqn_matrix }} min-port={{ matrix_coturn_turn_udp_min_port }} max-port={{ matrix_coturn_turn_udp_max_port }} + {% for ip in matrix_coturn_turn_external_ip_addresses %} external-ip={{ ip }} {% endfor %} log-file=stdout pidfile=/var/tmp/turnserver.pid -userdb=/var/tmp/turnserver.db no-cli diff --git a/roles/custom/matrix-dendrite/defaults/main.yml b/roles/custom/matrix-dendrite/defaults/main.yml index 44e09dd14de..4c2e4457166 100644 --- a/roles/custom/matrix-dendrite/defaults/main.yml +++ b/roles/custom/matrix-dendrite/defaults/main.yml @@ -283,6 +283,8 @@ matrix_dendrite_mscs_database: "dendrite_mscs" matrix_dendrite_client_api_turn_uris: [] matrix_dendrite_client_api_turn_shared_secret: "" +matrix_dendrite_client_api_turn_username: "" +matrix_dendrite_client_api_turn_password: "" matrix_dendrite_client_api_turn_allow_guests: false matrix_dendrite_disable_tls_validation: false diff --git a/roles/custom/matrix-dendrite/templates/dendrite.yaml.j2 b/roles/custom/matrix-dendrite/templates/dendrite.yaml.j2 index 2ca9b06285b..02c08b9e75b 100644 --- a/roles/custom/matrix-dendrite/templates/dendrite.yaml.j2 +++ b/roles/custom/matrix-dendrite/templates/dendrite.yaml.j2 @@ -202,8 +202,8 @@ client_api: turn_user_lifetime: "" turn_uris: {{ matrix_dendrite_client_api_turn_uris | to_json }} turn_shared_secret: {{ matrix_dendrite_client_api_turn_shared_secret | to_json }} - turn_username: "" - turn_password: "" + turn_username: {{ matrix_dendrite_client_api_turn_username | to_json }} + turn_password: {{ matrix_dendrite_client_api_turn_password | to_json }} # Settings for rate-limited endpoints. Rate limiting will kick in after the # threshold number of "slots" have been taken by requests from a specific diff --git a/roles/custom/matrix-synapse/defaults/main.yml b/roles/custom/matrix-synapse/defaults/main.yml index 9bdafe20766..56d4162cfa3 100644 --- a/roles/custom/matrix-synapse/defaults/main.yml +++ b/roles/custom/matrix-synapse/defaults/main.yml @@ -1063,6 +1063,8 @@ matrix_synapse_database_database: "synapse" matrix_synapse_turn_uris: [] matrix_synapse_turn_shared_secret: "" +matrix_synapse_turn_username: "" +matrix_synapse_turn_password: "" matrix_synapse_turn_allow_guests: false matrix_synapse_email_enabled: false diff --git a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 index bf2a359f54f..b22178fcd9f 100644 --- a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 +++ b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 @@ -1263,13 +1263,13 @@ turn_uris: {{ matrix_synapse_turn_uris|to_json }} # The shared secret used to compute passwords for the TURN server # -turn_shared_secret: {{ matrix_synapse_turn_shared_secret | string|to_json }} +turn_shared_secret: {{ matrix_synapse_turn_shared_secret | string | to_json }} # The Username and password if the TURN server needs them and # does not use a token # -#turn_username: "TURNSERVER_USERNAME" -#turn_password: "TURNSERVER_PASSWORD" +turn_username: {{ matrix_synapse_turn_username | string | to_json }} +turn_password: {{ matrix_synapse_turn_password | string | to_json }} # How long generated TURN credentials last #