From 585377975b81d490d581820cc04c774216f1381e Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Wed, 12 Mar 2025 16:51:10 +0200 Subject: [PATCH] Adjust LiveKit Server ports and exposure --- docs/configuring-playbook-element-call.md | 38 +++----- docs/configuring-playbook-livekit-server.md | 22 ++--- group_vars/matrix_servers | 10 +++ .../matrix-livekit-server/defaults/main.yml | 90 ++++++++++++++++--- .../tasks/validate_config.yml | 13 +++ .../templates/config.yaml.j2 | 29 ++++-- .../systemd/livekit-server.service.j2 | 17 +++- 7 files changed, 157 insertions(+), 62 deletions(-) diff --git a/docs/configuring-playbook-element-call.md b/docs/configuring-playbook-element-call.md index 4f32f79b9..694d9225b 100644 --- a/docs/configuring-playbook-element-call.md +++ b/docs/configuring-playbook-element-call.md @@ -18,11 +18,9 @@ See the project's [documentation](https://github.com/element-hq/element-call) to ## Decide on a domain and path -By default, Element Call is configured to be served on the `call.element.DOMAIN` domain, controlled by the `matrix_element_call_hostname` variable. +By default, Element Call is configured to be served on the `call.element.DOMAIN` domain. -This makes it easy to set it up, **without** having to adjust your DNS records manually. - -If you'd like to run Element Call on another hostname or path, use the `matrix_element_call_hostname` and `matrix_element_call_path_prefix` variables. +If you'd like to run Element Call on another hostname or path, use the `matrix_element_call_hostname` variable. A `matrix_element_call_path_prefix` variable is also available to set a path prefix for the Element Call service, but Element Call does not support running under a sub-path yet. ## Adjusting DNS records @@ -31,7 +29,12 @@ If you've changed the default hostname, **you may need to adjust your DNS** reco Ensure that the following DNS names have a public IP/FQDN: - `call.element.example.com` - `livekit.example.com` -- `sfu-jwt.example.com` + +## Adjusting firewall rules + +All services are exposed via HTTP/HTTPS as per usual, ports for which you've already opened as described in the [prerequisites](prerequisites.md) document. + +In addition to that, you'll also need to open ports required by LiveKit Server as described in its own [Adjusting firewall rules](configuring-playbook-livekit-server.md#adjusting-firewall-rules) section. ## Adjusting the playbook configuration @@ -49,29 +52,8 @@ matrix_element_call_enabled: true ## Installing -After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the [installation](installing.md) command: `just install-all` or `just setup-all` +After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records) and [adjusting firewall rules](#adjusting-firewall-rules), run the [installation](installing.md) command: `just install-all` or `just setup-all` ## Usage -Once installed, Element Call integrates seamlessly with Matrix clients like [Element Web](configuring-playbook-client-element-web.md). When the Element Call service is installed, the `/.well-known/matrix/client` file is also updated. A new `org.matrix.msc4143.rtc_foci` section is added to point to your LiveKit JWT service URL (e.g., `https://matrix.example.com/livekit-jwt-service`). - -Additionally, the `/.well-known/element/element.json` file is created to help Element clients discover the Element Call URL (e.g., `https://call.element.example.com`). - -## Required Firewall and Port Forwarding Rules - -To ensure the services function correctly, the following firewall rules and port forwarding settings are required: - -LiveKit: - -- Forward UDP ports 50100:50120 to the Docker instance running LiveKit. -- Forward TCP port 7881 to the Docker instance running LiveKit. - -Element Call: - -- Forward TCP port 443 to the server running Traefik (for Element Call). - -Ensure these ports are open and forwarded appropriately to allow traffic to flow correctly between the services. - -## Additional Information - -Refer to the Element Call documentation for more details on configuring and using Element Call. +Once installed, Element Call integrates seamlessly with Matrix clients like [Element Web](configuring-playbook-client-element-web.md). \ No newline at end of file diff --git a/docs/configuring-playbook-livekit-server.md b/docs/configuring-playbook-livekit-server.md index fc19ffa9d..8c1722507 100644 --- a/docs/configuring-playbook-livekit-server.md +++ b/docs/configuring-playbook-livekit-server.md @@ -39,24 +39,24 @@ livekit_server_enabled: true livekit_server_dev_key: 'your-secure-livekit-key' ``` +## Adjusting firewall rules + +To ensure the services function correctly, the following firewall rules and port forwarding settings are required: + +- `7881/tcp`: ICE/TCP (used by [LiveKit Server](./docs/configuring-playbook-livekit-server.md) for [Element Call](./docs/configuring-playbook-element-call.md)) + +- `7882/udp`: ICE/UDP Mux (used by [LiveKit Server](./docs/configuring-playbook-livekit-server.md) for [Element Call](./docs/configuring-playbook-element-call.md)) + +💡 The suggestions above are inspired by the upstream [Ports and Firewall](https://docs.livekit.io/home/self-hosting/ports-firewall/) documentation based on how LiveKit is configured in the playbook. If you've using custom configuration for the LiveKit Server role, you may need to adjust the firewall rules accordingly. + ## Installing After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the [installation](installing.md) command: `just install-all` or `just setup-all` ## Usage + Once installed, and in conjunction with Element Call and JWT Service, Livekit will become the WebRTC backend for all Element client calls. -## Required Firewall and Port Forwarding Rules - -To ensure the services function correctly, the following firewall rules and port forwarding settings are required: - -LiveKit: - -- Forward UDP ports 50100:50200 to the Docker instance running LiveKit. -- Forward TCP port 7881 to the Docker instance running LiveKit. - -Ensure these ports are open and forwarded appropriately to allow traffic to flow correctly between the services. - ## Additional Information Refer to the Livekit documentation for more details on configuring and using Livekit. diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index d6045a52c..564a4ef74 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -6320,6 +6320,16 @@ livekit_server_config_keys_auto: |- ) }} +# The playbook intentionally uses a non-standard port than the default used by the role (5349), +# because Coturn is already using that port. +# Note that TURN is not enabled by default, see `livekit_server_config_turn_enabled`. +livekit_server_config_turn_tls_port: 5350 + +# The playbook intentionally uses a non-standard port than the default used by the role (3478), +# because Coturn is already using that port. +# Note that TURN is not enabled by default, see `livekit_server_config_turn_enabled`. +livekit_server_config_turn_udp_port: 3479 + ######################################################################## # # # /livekit-server # diff --git a/roles/custom/matrix-livekit-server/defaults/main.yml b/roles/custom/matrix-livekit-server/defaults/main.yml index 6dfa1eb93..9132bf2ee 100644 --- a/roles/custom/matrix-livekit-server/defaults/main.yml +++ b/roles/custom/matrix-livekit-server/defaults/main.yml @@ -31,18 +31,17 @@ livekit_server_container_additional_networks: "{{ livekit_server_container_addit livekit_server_container_additional_networks_auto: [] livekit_server_container_additional_networks_custom: [] -# Controls whether the LiveKit Server container exposes its RCT TCP port (`livekit_server_config_rtc_tcp_port`) -# -# Takes an ":" or "" value (e.g. "127.0.0.1:5349"), or empty string to not expose. -livekit_server_container_rtc_tcp_host_bind_port: "{{ livekit_server_config_rtc_tcp_port if livekit_server_container_network != 'host' else '' }}" - -# Controls whether the LiveKit Server container exposes its RTC UDP port range and which interface to do it on. +# Controls whether the LiveKit Server container exposes its RTC ports and which interface to do it on. # # Takes an interface "" (e.g. "127.0.0.1"), or empty string to listen on all interfaces. # Takes a null/none value (`~`) or 'none' (as a string) to prevent listening. +livekit_server_container_rtc_listen_interface: "{{ '' if livekit_server_container_network != 'host' else 'none' }}" + +# Controls whether the LiveKit Server container exposes its TURN ports and which interface to do it on. # -# The UDP port-range itself is specified using `livekit_server_config_rtc_port_range_start` and `livekit_server_config_rtc_port_range_end`. -livekit_server_container_rtc_range_listen_interface: "{{ '' if livekit_server_container_network != 'host' else 'none' }}" +# Takes an interface "" (e.g. "127.0.0.1"), or empty string to listen on all interfaces. +# Takes a null/none value (`~`) or 'none' (as a string) to prevent listening. +livekit_server_container_turn_listen_interface: "{{ '' if livekit_server_container_network != 'host' else 'none' }}" livekit_server_container_image_self_build: false livekit_server_container_repo: "https://github.com/livekit/livekit.git" @@ -178,22 +177,89 @@ livekit_server_configuration_extension_yaml: | livekit_server_configuration_extension: "{{ livekit_server_configuration_extension_yaml | from_yaml if livekit_server_configuration_extension_yaml | from_yaml is mapping else {} }}" # Controls the `port` configuration property. +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ livekit_server_config_port: 7880 +######################################################################################## +# # +# RTC # +# # +######################################################################################## + # Controls the `rtc.tcp_port` configuration property +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ livekit_server_config_rtc_tcp_port: 7881 -# Controls the `rtc.port_range_start` configuration property -livekit_server_config_rtc_port_range_start: 50100 +# Controls the `rtc.port_range_start` configuration property. +# This must be defined together with `livekit_server_config_rtc_port_range_end`, +# or alternatively `livekit_server_config_rtc_udp_port` can be defined as a single port that handles all traffic. +# Example: 50100 +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ +livekit_server_config_rtc_port_range_start: '' -# Controls the `rtc.port_range_end` configuration property -livekit_server_config_rtc_port_range_end: 50120 +# Controls the `rtc.port_range_end` configuration property. +# This must be defined together with `livekit_server_config_rtc_port_range_start`, +# or alternatively `livekit_server_config_rtc_udp_port` can be defined as a single port that handles all traffic. +# Example: 50200 +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ +livekit_server_config_rtc_port_range_end: '' + +# Controls the `rtc.udp_port` configuration property. +# As an alternative to this, one may define both `livekit_server_config_rtc_port_range_start` and `livekit_server_config_rtc_port_range_end`. +# Example: 7882 +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ +livekit_server_config_rtc_udp_port: 7882 # Controls the `rtc.use_external_ip` configuration property. # When set to true, attempts to discover the host's public IP via STUN. # This is useful for cloud environments such as AWS & Google where hosts have an internal IP that maps to an external one. livekit_server_config_rtc_use_external_ip: true +######################################################################################## +# # +# /RTC # +# # +######################################################################################## + +######################################################################################## +# # +# TURN # +# # +######################################################################################## + +# Controls the `turn.enabled` configuration property. +# When set to true, enables TURN server. +livekit_server_config_turn_enabled: false + +# Controls the `turn.domain` configuration property. +# Example: livekit.example.com +livekit_server_config_turn_domain: "{{ livekit_server_hostname }}" + +# Controls the `turn.cert_file` configuration property. +# Path to the TLS certificate file. +livekit_server_config_turn_cert_file: '' + +# Controls the `turn.key_file` configuration property. +# Path to the TLS key file. +livekit_server_config_turn_key_file: '' + +# Controls the `turn.external_tls` configuration property. +livekit_server_config_turn_external_tls: false + +# Controls the `turn.tls_port` configuration property. +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ +livekit_server_config_turn_tls_port: 5349 + +# Controls the `turn.udp_port` configuration property. +# See: https://docs.livekit.io/home/self-hosting/ports-firewall/ +livekit_server_config_turn_udp_port: 3478 + +######################################################################################## +# # +# /TURN # +# # +######################################################################################## + # Controls the `keys` configuration property. livekit_server_config_keys: "{{ livekit_server_config_keys_auto | combine(livekit_server_config_keys_custom, recursive=True) }}" livekit_server_config_keys_auto: {} diff --git a/roles/custom/matrix-livekit-server/tasks/validate_config.yml b/roles/custom/matrix-livekit-server/tasks/validate_config.yml index cd0e3b074..912b9b5fb 100644 --- a/roles/custom/matrix-livekit-server/tasks/validate_config.yml +++ b/roles/custom/matrix-livekit-server/tasks/validate_config.yml @@ -16,3 +16,16 @@ - {'name': 'livekit_server_identifier', when: true} - {'name': 'livekit_server_uid', when: true} - {'name': 'livekit_server_gid', when: true} + - {'name': 'livekit_server_config_turn_domain', when: "{{ livekit_server_config_turn_enabled | bool }}"} + - {'name': 'livekit_server_config_turn_cert_file', when: "{{ livekit_server_config_turn_enabled | bool }}"} + - {'name': 'livekit_server_config_turn_key_file', when: "{{ livekit_server_config_turn_enabled | bool }}"} + +- name: Fail if LiveKit Server port range configuration is invalid + ansible.builtin.fail: + msg: > + You need to either define both port range settings (livekit_server_config_rtc_port_range_start and livekit_server_config_rtc_port_range_end) + or define a single UDP port (livekit_server_config_rtc_udp_port). + when: > + (livekit_server_config_rtc_port_range_start | string | length > 0 and livekit_server_config_rtc_port_range_end | string | length == 0) or + (livekit_server_config_rtc_port_range_start | string | length == 0 and livekit_server_config_rtc_port_range_end | string | length > 0) or + (livekit_server_config_rtc_port_range_start | string | length == 0 and livekit_server_config_rtc_port_range_end | string | length == 0 and livekit_server_config_rtc_udp_port | string | length == 0) diff --git a/roles/custom/matrix-livekit-server/templates/config.yaml.j2 b/roles/custom/matrix-livekit-server/templates/config.yaml.j2 index a9317735c..024d23562 100644 --- a/roles/custom/matrix-livekit-server/templates/config.yaml.j2 +++ b/roles/custom/matrix-livekit-server/templates/config.yaml.j2 @@ -1,3 +1,5 @@ +#jinja2: lstrip_blocks: "True" + port: {{ livekit_server_config_port | int | to_json }} bind_addresses: @@ -5,18 +7,31 @@ bind_addresses: rtc: tcp_port: {{ livekit_server_config_rtc_tcp_port | int | to_json }} + + {% if livekit_server_config_rtc_udp_port %} + udp_port: {{ livekit_server_config_rtc_udp_port | int | to_json }} + {% endif %} + + {% if livekit_server_config_rtc_port_range_start %} port_range_start: {{ livekit_server_config_rtc_port_range_start | int | to_json }} + {% endif %} + + {% if livekit_server_config_rtc_port_range_end %} port_range_end: {{ livekit_server_config_rtc_port_range_end | int | to_json }} + {% endif %} + use_external_ip: {{ livekit_server_config_rtc_use_external_ip | to_json }} turn: - enabled: false - domain: localhost - cert_file: "" - key_file: "" - tls_port: 5349 - udp_port: 443 - external_tls: true + enabled: {{ livekit_server_config_turn_enabled | to_json }} +{% if livekit_server_config_turn_enabled %} + domain: {{ livekit_server_config_turn_domain | to_json }} + cert_file: {{ livekit_server_config_turn_cert_file | to_json }} + key_file: {{ livekit_server_config_turn_key_file | to_json }} + tls_port: {{ livekit_server_config_turn_tls_port | int | to_json }} + udp_port: {{ livekit_server_config_turn_udp_port | int | to_json }} + external_tls: {{ livekit_server_config_turn_external_tls | to_json }} +{% endif %} keys: {{ livekit_server_config_keys | to_json }} diff --git a/roles/custom/matrix-livekit-server/templates/systemd/livekit-server.service.j2 b/roles/custom/matrix-livekit-server/templates/systemd/livekit-server.service.j2 index 6ff03d660..f68a6debb 100644 --- a/roles/custom/matrix-livekit-server/templates/systemd/livekit-server.service.j2 +++ b/roles/custom/matrix-livekit-server/templates/systemd/livekit-server.service.j2 @@ -19,11 +19,20 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --user={{ livekit_server_uid }}:{{ livekit_server_gid }} \ --cap-drop=ALL \ --network={{ livekit_server_container_network }} \ - {% if livekit_server_container_rtc_tcp_host_bind_port != '' %} - -p {{ livekit_server_container_rtc_tcp_host_bind_port }}:{{ livekit_server_config_rtc_tcp_port }} \ + {% if livekit_server_container_rtc_listen_interface is not in [none, 'none'] %} + -p {{ livekit_server_container_rtc_listen_interface }}{{ ':' if livekit_server_container_rtc_listen_interface else '' }}{{ livekit_server_config_rtc_tcp_port }}:{{ livekit_server_config_rtc_tcp_port }} \ {% endif %} - {% if livekit_server_container_rtc_range_listen_interface is not in [none, 'none'] %} - -p {{ livekit_server_container_rtc_range_listen_interface }}{{ ':' if livekit_server_container_rtc_range_listen_interface else '' }}{{ livekit_server_config_rtc_port_range_start }}-{{ livekit_server_config_rtc_port_range_end }}:{{ livekit_server_config_rtc_port_range_start }}-{{ livekit_server_config_rtc_port_range_end }}/udp \ + {% if livekit_server_container_rtc_listen_interface is not in [none, 'none'] and livekit_server_config_rtc_port_range_start and livekit_server_config_rtc_port_range_end %} + -p {{ livekit_server_container_rtc_listen_interface }}{{ ':' if livekit_server_container_rtc_listen_interface else '' }}{{ livekit_server_config_rtc_port_range_start }}-{{ livekit_server_config_rtc_port_range_end }}:{{ livekit_server_config_rtc_port_range_start }}-{{ livekit_server_config_rtc_port_range_end }}/udp \ + {% endif %} + {% if livekit_server_container_rtc_listen_interface is not in [none, 'none'] and livekit_server_config_rtc_udp_port %} + -p {{ livekit_server_container_rtc_listen_interface }}{{ ':' if livekit_server_container_rtc_listen_interface else '' }}{{ livekit_server_config_rtc_udp_port }}:{{ livekit_server_config_rtc_udp_port }}/udp \ + {% endif %} + {% if livekit_server_container_turn_listen_interface is not in [none, 'none'] and livekit_server_config_turn_enabled %} + -p {{ livekit_server_container_turn_listen_interface }}{{ ':' if livekit_server_container_turn_listen_interface else '' }}{{ livekit_server_config_turn_tls_port }}:{{ livekit_server_config_turn_tls_port }} \ + {% endif %} + {% if livekit_server_container_turn_listen_interface is not in [none, 'none'] and livekit_server_config_turn_enabled %} + -p {{ livekit_server_container_turn_listen_interface }}{{ ':' if livekit_server_container_turn_listen_interface else '' }}{{ livekit_server_config_turn_udp_port }}:{{ livekit_server_config_turn_udp_port }} \ {% endif %} --mount type=bind,src={{ livekit_server_config_path }}/config.yaml,dst=/livekit-config.yaml,ro \ --label-file={{ livekit_server_base_path }}/labels \