From ecc237bbad4b21edce37faba67864a36fde5a5cb Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 18 Dec 2021 10:50:44 +0200 Subject: [PATCH] Initial work on getting nginx reverse proxying working with Dendrite --- group_vars/matrix_servers | 30 +++++++-- roles/matrix-dendrite/defaults/main.yml | 14 +++- .../tasks/dendrite/setup_install.yml | 2 +- roles/matrix-dendrite/tasks/main.yml | 4 +- .../tasks/self_check_client_api.yml | 4 +- .../tasks/self_check_federation_api.yml | 7 +- .../templates/dendrite/dendrite.yaml.j2 | 2 +- .../systemd/matrix-dendrite.service.j2 | 3 +- roles/matrix-nginx-proxy/defaults/main.yml | 25 ++++--- .../tasks/setup_nginx_proxy.yml | 13 ++++ .../nginx/conf.d/matrix-dendrite.conf.j2 | 67 +++++++++++++++++++ 11 files changed, 143 insertions(+), 28 deletions(-) create mode 100644 roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index b40d62983..587ef2435 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -1365,7 +1365,13 @@ matrix_nginx_proxy_enabled: true matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "{{ 'matrix-corporal:41080' if matrix_corporal_enabled else 'matrix-nginx-proxy:12080' }}" matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "{{ '127.0.0.1:41080' if matrix_corporal_enabled else '127.0.0.1:12080' }}" -matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: "{{ matrix_synapse_max_upload_size_mb }}" +matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: |- + {{ + { + 'synapse': matrix_synapse_max_upload_size_mb, + 'dendrite': (matrix_dendrite_max_file_size_bytes / 1024 / 1024) | round, + }[matrix_homeserver_implementation]|int + }} matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: "{{ matrix_synapse_admin_enabled }}" @@ -1391,19 +1397,29 @@ matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container: "127.0.0.1:{{ # By default, we do TLS termination for the Matrix Federation API (port 8448) at matrix-nginx-proxy. # Unless this is handled there OR Synapse's federation listener port is disabled, we'll reverse-proxy. -matrix_nginx_proxy_proxy_matrix_federation_api_enabled: "{{ matrix_synapse_federation_port_enabled and not matrix_synapse_tls_federation_listener_enabled }}" +matrix_nginx_proxy_proxy_matrix_federation_api_enabled: |- + {{ + { + 'synapse': (matrix_synapse_federation_port_enabled and not matrix_synapse_tls_federation_listener_enabled), + 'dendrite': matrix_dendrite_federation_enabled, + }[matrix_homeserver_implementation]|bool + }} + matrix_nginx_proxy_proxy_matrix_federation_api_addr_with_container: "matrix-nginx-proxy:12088" matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container: "127.0.0.1:12088" -# Settings controlling matrix-synapse-proxy.conf matrix_nginx_proxy_proxy_synapse_enabled: "{{ matrix_synapse_enabled }}" - matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container: "matrix-synapse:{{ matrix_synapse_container_client_api_port }}" -matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container: "127.0.0.1:{{ matrix_synapse_container_client_api_port }}" - +matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container: "127.0.0.1:{{ matrix_dendrite_container_client_api_port }}" matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container: "matrix-synapse:{{matrix_synapse_container_federation_api_plain_port|string}}" matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container: "localhost:{{matrix_synapse_container_federation_api_plain_port|string}}" +matrix_nginx_proxy_proxy_dendrite_enabled: "{{ matrix_dendrite_enabled }}" +matrix_nginx_proxy_proxy_dendrite_client_api_addr_with_container: "matrix-dendrite:{{ matrix_dendrite_container_client_api_port }}" +matrix_nginx_proxy_proxy_dendrite_client_api_addr_sans_container: "127.0.0.1:{{ matrix_synapse_container_client_api_port }}" +matrix_nginx_proxy_proxy_dendrite_federation_api_addr_with_container: "matrix-dendrite:{{ matrix_dendrite_container_federation_api_plain_port|string }}" +matrix_nginx_proxy_proxy_dendrite_federation_api_addr_sans_container: "127.0.0.1:{{ matrix_dendrite_container_federation_api_plain_port|string }}" + # When matrix-nginx-proxy is disabled, the actual port number that the vhost uses may begin to matter. matrix_nginx_proxy_proxy_matrix_federation_port: "{{ matrix_federation_public_port }}" @@ -2221,6 +2237,8 @@ matrix_dendrite_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if matrix_dendrite_disable_tls_validation: "{{ true if matrix_ssl_retrieval_method == 'self-signed' else false }}" +matrix_dendrite_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + matrix_dendrite_systemd_required_services_list: | {{ (['docker.service']) diff --git a/roles/matrix-dendrite/defaults/main.yml b/roles/matrix-dendrite/defaults/main.yml index 1c1e7596c..11952ce75 100644 --- a/roles/matrix-dendrite/defaults/main.yml +++ b/roles/matrix-dendrite/defaults/main.yml @@ -14,6 +14,15 @@ matrix_dendrite_storage_path: "{{ matrix_dendrite_base_path }}/storage" matrix_dendrite_media_store_path: "{{ matrix_dendrite_storage_path }}/media-store" matrix_dendrite_ext_path: "{{ matrix_dendrite_base_path }}/ext" +matrix_dendrite_container_http_bind_port: 8008 + +# This is passed as a flag `-http-bind-address` flag to the Dendrite server in the container +matrix_dendrite_container_http_bind_address: ":{{ matrix_dendrite_container_http_bind_port }}" + +# Dendrite monolith exposes both the Client API and the Federation API on the same port +matrix_dendrite_container_client_api_port: "{{ matrix_dendrite_container_http_bind_port }}" +matrix_dendrite_container_federation_api_plain_port: "{{ matrix_dendrite_container_http_bind_port }}" + # Controls whether the matrix-dendrite container exposes the Client/Server API port (tcp/8008 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8008"), or empty string to not expose. @@ -116,7 +125,10 @@ matrix_dendrite_trusted_id_servers: # Controls whether Dendrite will federate at all. # Disable this to completely isolate your server from the rest of the Matrix network. -matrix_dendrite_disable_federation: false +matrix_dendrite_federation_enabled: true + +# Controls whether the self-check feature should validate SSL certificates. +matrix_dendrite_self_check_validate_certificates: true # Default Dendrite configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. diff --git a/roles/matrix-dendrite/tasks/dendrite/setup_install.yml b/roles/matrix-dendrite/tasks/dendrite/setup_install.yml index 2e319e170..3e3b21998 100644 --- a/roles/matrix-dendrite/tasks/dendrite/setup_install.yml +++ b/roles/matrix-dendrite/tasks/dendrite/setup_install.yml @@ -68,7 +68,7 @@ - name: Ensure systemd reloaded after matrix-dendrite.service installation service: daemon_reload: yes - when: "matrix_dendrite_systemd_service_result.changed" + when: "matrix_dendrite_systemd_service_result.changed|bool" - name: Ensure matrix-dendrite-create-account script created template: diff --git a/roles/matrix-dendrite/tasks/main.yml b/roles/matrix-dendrite/tasks/main.yml index 6c25f1906..e44134a5a 100644 --- a/roles/matrix-dendrite/tasks/main.yml +++ b/roles/matrix-dendrite/tasks/main.yml @@ -22,14 +22,14 @@ - import_tasks: "{{ role_path }}/tasks/self_check_client_api.yml" delegate_to: 127.0.0.1 become: false - when: run_self_check|bool + when: run_self_check|bool and matrix_dendrite_enabled|bool tags: - self-check - import_tasks: "{{ role_path }}/tasks/self_check_federation_api.yml" delegate_to: 127.0.0.1 become: false - when: run_self_check|bool + when: run_self_check|bool and matrix_dendrite_enabled|bool tags: - self-check diff --git a/roles/matrix-dendrite/tasks/self_check_client_api.yml b/roles/matrix-dendrite/tasks/self_check_client_api.yml index d3fb1f0de..7c2f6b5ec 100644 --- a/roles/matrix-dendrite/tasks/self_check_client_api.yml +++ b/roles/matrix-dendrite/tasks/self_check_client_api.yml @@ -7,14 +7,12 @@ register: result_matrix_dendrite_client_api ignore_errors: true check_mode: no - when: matrix_dendrite_enabled|bool - name: Fail if Matrix Client API not working fail: msg: "Failed checking Matrix Client API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_dendrite_client_api_url_endpoint_public }}`). Is Dendrite running? Is port 443 open in your firewall? Full error: {{ result_matrix_dendrite_client_api }}" - when: "matrix_dendrite_enabled|bool and (result_matrix_dendrite_client_api.failed or 'json' not in result_matrix_dendrite_client_api)" + when: "(result_matrix_dendrite_client_api.failed or 'json' not in result_matrix_dendrite_client_api)" - name: Report working Matrix Client API debug: msg: "The Matrix Client API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_dendrite_client_api_url_endpoint_public }}`) is working" - when: matrix_dendrite_enabled|bool diff --git a/roles/matrix-dendrite/tasks/self_check_federation_api.yml b/roles/matrix-dendrite/tasks/self_check_federation_api.yml index f11601d7f..a7c60a677 100644 --- a/roles/matrix-dendrite/tasks/self_check_federation_api.yml +++ b/roles/matrix-dendrite/tasks/self_check_federation_api.yml @@ -7,19 +7,18 @@ register: result_matrix_dendrite_federation_api ignore_errors: true check_mode: no - when: matrix_dendrite_enabled|bool - name: Fail if Matrix Federation API not working fail: msg: "Failed checking Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_dendrite_federation_api_url_endpoint_public }}`). Is Dendrite running? Is port {{ matrix_federation_public_port }} open in your firewall? Full error: {{ result_matrix_dendrite_federation_api }}" - when: "matrix_dendrite_enabled|bool and matrix_dendrite_federation_enabled|bool and (result_matrix_dendrite_federation_api.failed or 'json' not in result_matrix_dendrite_federation_api)" + when: "matrix_dendrite_federation_enabled|bool and (result_matrix_dendrite_federation_api.failed or 'json' not in result_matrix_dendrite_federation_api)" - name: Fail if Matrix Federation API unexpectedly enabled fail: msg: "Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_dendrite_federation_api_url_endpoint_public }}`) despite being disabled." - when: "matrix_dendrite_enabled|bool and not matrix_dendrite_federation_enabled|bool and not result_matrix_dendrite_federation_api.failed" + when: "not matrix_dendrite_federation_enabled|bool and not result_matrix_dendrite_federation_api.failed" - name: Report working Matrix Federation API debug: msg: "The Matrix Federation API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_dendrite_federation_api_url_endpoint_public }}`) is working" - when: "matrix_dendrite_enabled|bool and matrix_dendrite_federation_enabled|bool" + when: "matrix_dendrite_federation_enabled|bool" diff --git a/roles/matrix-dendrite/templates/dendrite/dendrite.yaml.j2 b/roles/matrix-dendrite/templates/dendrite/dendrite.yaml.j2 index 2559be15a..c512904eb 100644 --- a/roles/matrix-dendrite/templates/dendrite/dendrite.yaml.j2 +++ b/roles/matrix-dendrite/templates/dendrite/dendrite.yaml.j2 @@ -64,7 +64,7 @@ global: # Disables federation. Dendrite will not be able to make any outbound HTTP requests # to other servers and the federation API will not be exposed. - disable_federation: {{ matrix_dendrite_disable_federation|to_json }} + disable_federation: {{ (not matrix_dendrite_federation_enabled)|to_json }} # Configuration for Kafka/Naffka. kafka: diff --git a/roles/matrix-dendrite/templates/dendrite/systemd/matrix-dendrite.service.j2 b/roles/matrix-dendrite/templates/dendrite/systemd/matrix-dendrite.service.j2 index b41f6c2c5..48067c0e3 100644 --- a/roles/matrix-dendrite/templates/dendrite/systemd/matrix-dendrite.service.j2 +++ b/roles/matrix-dendrite/templates/dendrite/systemd/matrix-dendrite.service.j2 @@ -44,7 +44,8 @@ ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-dendrite \ {{ arg }} \ {% endfor %} {{ matrix_dendrite_docker_image }} \ - --config /data/dendrite.yaml + -config /data/dendrite.yaml \ + -http-bind-address {{ matrix_dendrite_container_http_bind_address }} ExecStop=-{{ matrix_host_command_docker }} kill matrix-dendrite ExecStop=-{{ matrix_host_command_docker }} rm matrix-dendrite diff --git a/roles/matrix-nginx-proxy/defaults/main.yml b/roles/matrix-nginx-proxy/defaults/main.yml index 74f53e674..749d9391d 100644 --- a/roles/matrix-nginx-proxy/defaults/main.yml +++ b/roles/matrix-nginx-proxy/defaults/main.yml @@ -111,14 +111,28 @@ matrix_nginx_proxy_access_log_enabled: true matrix_nginx_proxy_proxy_riot_compat_redirect_enabled: false matrix_nginx_proxy_proxy_riot_compat_redirect_hostname: "riot.{{ matrix_domain }}" -# Controls whether proxying the Synapse domain should be done. +# Controls whether proxying for Synapse should be done. matrix_nginx_proxy_proxy_synapse_enabled: false matrix_nginx_proxy_proxy_synapse_hostname: "matrix-nginx-proxy" matrix_nginx_proxy_proxy_synapse_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" - +# The addresses where the Matrix Client API is, when using Synapse. +matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container: "" +matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container: "" # The addresses where the Federation API is, when using Synapse. matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container: "" matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container: "" +# A list of strings containing additional configuration blocks to add to the Synapse's server configuration (matrix-synapse.conf). +matrix_nginx_proxy_proxy_synapse_additional_server_configuration_blocks: [] + +# Controls whether proxying for Dendrite should be done. +matrix_nginx_proxy_proxy_dendrite_enabled: false +matrix_nginx_proxy_proxy_dendrite_hostname: "matrix-nginx-proxy" +matrix_nginx_proxy_proxy_dendrite_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" +# The addresses where the Matrix Client API is, when using Dendrite. +matrix_nginx_proxy_proxy_dendrite_client_api_addr_with_container: "" +matrix_nginx_proxy_proxy_dendrite_client_api_addr_sans_container: "" +# A list of strings containing additional configuration blocks to add to the Dendrite's server configuration (matrix-dendrite.conf). +matrix_nginx_proxy_proxy_dendrite_additional_server_configuration_blocks: [] # Controls whether proxying the Element domain should be done. matrix_nginx_proxy_proxy_element_enabled: false @@ -200,10 +214,6 @@ matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_key: "" matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "matrix-nginx-proxy:12080" matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "127.0.0.1:12080" -# The addresses where the Matrix Client API is, when using Synapse. -matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container: "" -matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container: "" - # This needs to be equal or higher than the maximum upload size accepted by Synapse. matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: 50 @@ -268,9 +278,6 @@ matrix_nginx_proxy_proxy_http_additional_server_configuration_blocks: [] # A list of strings containing additional configuration blocks to add to the base matrix server configuration (matrix-domain.conf). matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: [] -# A list of strings containing additional configuration blocks to add to the synapse's server configuration (matrix-synapse.conf). -matrix_nginx_proxy_proxy_synapse_additional_server_configuration_blocks: [] - # A list of strings containing additional configuration blocks to add to Riot's server configuration (matrix-riot-web.conf). matrix_nginx_proxy_proxy_riot_additional_server_configuration_blocks: [] diff --git a/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml b/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml index 5ddbb19d0..e5021468a 100644 --- a/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml +++ b/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml @@ -67,6 +67,19 @@ state: absent when: "not matrix_nginx_proxy_proxy_synapse_enabled|bool" +- name: Ensure Matrix nginx-proxy configuration for matrix-dendrite exists + template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-dendrite.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-dendrite.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_dendrite_enabled|bool + +- name: Ensure Matrix nginx-proxy configuration for matrix-dendrite deleted + file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-dendrite.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_dendrite_enabled|bool" + - name: Ensure Matrix nginx-proxy configuration for Element domain exists template: src: "{{ role_path }}/templates/nginx/conf.d/matrix-client-element.conf.j2" diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 new file mode 100644 index 000000000..9776085e1 --- /dev/null +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 @@ -0,0 +1,67 @@ +#jinja2: lstrip_blocks: "True" + +server { + listen 12080; + server_name {{ matrix_nginx_proxy_proxy_dendrite_hostname }}; + + server_tokens off; + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% for configuration_block in matrix_nginx_proxy_proxy_dendrite_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + {# Everything else just goes to the API server ##} + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver 127.0.0.11 valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_dendrite_client_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_dendrite_client_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} + +{% if matrix_nginx_proxy_proxy_dendrite_federation_api_enabled %} +server { + listen 12088; + + server_name {{ matrix_nginx_proxy_proxy_dendrite_hostname }}; + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver 127.0.0.11 valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_dendrite_federation_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_dendrite_federation_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} +{% endif %}