From dc9ff4e01b4ef1293af6bd5fb4b10753033a2814 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Tue, 10 Oct 2023 11:10:21 +0300 Subject: [PATCH] Add support for external-IP-address-autodetection to Coturn --- docs/configuring-playbook-turn.md | 13 +++++++- examples/vars.yml | 16 ++++++++++ group_vars/matrix_servers | 3 ++ roles/custom/matrix-coturn/defaults/main.yml | 19 ++++++++++- .../matrix-coturn/tasks/setup_install.yml | 32 +++++++++++++++++++ .../templates/turnserver.conf.j2 | 2 +- 6 files changed, 82 insertions(+), 3 deletions(-) diff --git a/docs/configuring-playbook-turn.md b/docs/configuring-playbook-turn.md index 365fea4b..c7bf998f 100644 --- a/docs/configuring-playbook-turn.md +++ b/docs/configuring-playbook-turn.md @@ -16,13 +16,24 @@ matrix_coturn_enabled: false In that case, Synapse would not point to any Coturn servers and audio/video call functionality may fail. ## Manually defining your public IP + In the `hosts` file we explicitly ask for your server's external IP address when defining `ansible_host`, because the same value is used for configuring Coturn. + If you'd rather use a local IP for `ansible_host`, make sure to set up `matrix_coturn_turn_external_ip_address` replacing `YOUR_PUBLIC_IP` with the pubic IP used by the server. ```yaml matrix_coturn_turn_external_ip_address: "YOUR_PUBLIC_IP" ``` +If you'd like to rely on external IP address auto-detection (not recommended unless you need it), set `matrix_coturn_turn_external_ip_address` to an empty value. The playbook will automatically contact an [EchoIP](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable. + +If your server has multiple external IP addresses, the Coturn role offers a different variable for specifying them: + +```yaml +# Note: matrix_coturn_turn_external_ip_addresses is different than matrix_coturn_turn_external_ip_address +matrix_coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7'] +``` + ## 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: @@ -49,4 +60,4 @@ jitsi_web_stun_servers: You can put multiple host/port combinations if you like. ## Further variables and configuration options -To see all the available configuration options, check roles/custom/matrix-coturn/defaults/main.yml +To see all the available configuration options, check roles/custom/matrix-coturn/defaults/main.yml diff --git a/examples/vars.yml b/examples/vars.yml index 784bf061..dd9a97c4 100644 --- a/examples/vars.yml +++ b/examples/vars.yml @@ -41,3 +41,19 @@ devture_traefik_config_certificatesResolvers_acme_email: '' # The playbook creates additional Postgres users and databases (one for each enabled service) # using this superuser account. devture_postgres_connection_password: '' + +# By default, we configure Coturn's external IP address using the value specified for `ansible_host` in your `inventory/hosts` file. +# If this value is an external IP address, you can skip this section. +# +# If `ansible_host` is not the server's external IP address, you have 2 choices: +# 1. Uncomment the line below, to allow IP address auto-detection to happen (more on this below) +# 2. Uncomment and adjust the line below to specify an IP address manually +# +# By default, auto-detection will be attempted using the `https://ifconfig.co/json` API. +# Default values for this are specified in `matrix_coturn_turn_external_ip_address_auto_detection_*` variables in the Coturn role +# (see `roles/custom/matrix-coturn/defaults/main.yml`). +# +# If your server has multiple IP addresses, you may define them in another variable which allows a list of addresses. +# Example: `matrix_coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7']` +# +# matrix_coturn_turn_external_ip_address: '' diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index eaac3385..ad6433c4 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -2245,6 +2245,9 @@ matrix_coturn_enabled: true matrix_coturn_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" +# We make the assumption that `ansible_host` points to an external IP address, which may not always be the case. +# Users are free to set `matrix_coturn_turn_external_ip_address` to an empty string +# 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 }}" diff --git a/roles/custom/matrix-coturn/defaults/main.yml b/roles/custom/matrix-coturn/defaults/main.yml index 1e87d808..c090d038 100644 --- a/roles/custom/matrix-coturn/defaults/main.yml +++ b/roles/custom/matrix-coturn/defaults/main.yml @@ -73,8 +73,25 @@ matrix_coturn_turn_udp_max_port: 49172 matrix_coturn_turn_static_auth_secret: "" # 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` matrix_coturn_turn_external_ip_address: '' -matrix_coturn_turn_external_ip_addresses: ["{{ matrix_coturn_turn_external_ip_address }}"] +matrix_coturn_turn_external_ip_addresses: "{{ [matrix_coturn_turn_external_ip_address] if matrix_coturn_turn_external_ip_address != '' else [] }}" + +# Controls whether external IP address auto-detection should be attempted. +# We try to do this if there is no external IP address explicitly configured and if an EchoIP service URL is specified. +# See matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url +matrix_coturn_turn_external_ip_address_auto_detection_enabled: "{{ matrix_coturn_turn_external_ip_addresses | length == 0 and matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url != '' }}" + +# Specifies the address of the EchoIP service (https://github.com/mpolden/echoip) to use for detecting the external IP address. +# By default, we use the official public instance. +matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url: https://ifconfig.co/json + +# Controls whether SSL certificates will be validated when contacting the EchoIP service (matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url) +matrix_coturn_turn_external_ip_address_auto_detection_echoip_validate_certs: true + +matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_retries_count: "{{ devture_playbook_help_geturl_retries_count }}" +matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_retries_delay: "{{ devture_playbook_help_geturl_retries_delay }}" matrix_coturn_allowed_peer_ips: [] diff --git a/roles/custom/matrix-coturn/tasks/setup_install.yml b/roles/custom/matrix-coturn/tasks/setup_install.yml index 503ffae1..6064b360 100644 --- a/roles/custom/matrix-coturn/tasks/setup_install.yml +++ b/roles/custom/matrix-coturn/tasks/setup_install.yml @@ -1,5 +1,37 @@ --- +- when: matrix_coturn_turn_external_ip_address_auto_detection_enabled | bool + block: + - when: matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url == '' + name: Fail if enabled, but EchoIP service URL unset + ansible.builtin.fail: + msg: "To use the external IP address auto-detection feature, you need to set matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url" + + # NOTE: + # `ansible.builtin.uri` does not provide a way to configure whether IPv4 or IPv6 is used. + # Luckily, the default instance we use does not define AAAA records for now, so it's always IPv4. + - name: Fetch IP address information from EchoIP service + ansible.builtin.uri: + url: "{{ matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url }}" + headers: + Content-Type: application/json + follow_redirects: none + validate_certs: "{{ matrix_coturn_turn_external_ip_address_auto_detection_echoip_validate_certs }}" + register: result_matrix_coturn_turn_external_ip_address_auto_detection_echoip_response + ignore_errors: true + check_mode: false + retries: "{{ matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_retries_count }}" + delay: "{{ matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_retries_delay }}" + until: not result_matrix_coturn_turn_external_ip_address_auto_detection_echoip_response.failed + + - when: "(result_matrix_coturn_turn_external_ip_address_auto_detection_echoip_response.failed or 'json' not in result_matrix_coturn_turn_external_ip_address_auto_detection_echoip_response)" + name: Fail if EchoIP service failed + ansible.builtin.fail: + msg: "Failed contacting EchoIP service API at `{{ matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url }}` (controlled by `matrix_coturn_turn_external_ip_address_auto_detection_echoip_service_url`). Full error: {{ result_matrix_coturn_turn_external_ip_address_auto_detection_echoip_response }}" + + - ansible.builtin.set_fact: + matrix_coturn_turn_external_ip_address: "{{ result_matrix_coturn_turn_external_ip_address_auto_detection_echoip_response.json.ip }}" + - name: Ensure Matrix Coturn path exists ansible.builtin.file: path: "{{ item.path }}" diff --git a/roles/custom/matrix-coturn/templates/turnserver.conf.j2 b/roles/custom/matrix-coturn/templates/turnserver.conf.j2 index 3ed7b99f..b4688ff9 100644 --- a/roles/custom/matrix-coturn/templates/turnserver.conf.j2 +++ b/roles/custom/matrix-coturn/templates/turnserver.conf.j2 @@ -5,7 +5,7 @@ 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|select('ne', '') %} +{% for ip in matrix_coturn_turn_external_ip_addresses %} external-ip={{ ip }} {% endfor %}